{
  "openapi": "3.0.0",
  "info": {
    "version": "3.0.0",
    "title": "Didit Verification API",
    "description": "신분증 인증 API입니다. x-api-key 헤더로 인증합니다."
  },
  "servers": [
    {
      "url": "https://verification.didit.me"
    }
  ],
  "tags": [],
  "paths": {
    "/system/healthcheck": {
      "get": {
        "summary": "서비스 상태 확인(공개, 인증 불필요)",
        "description": "공개 미인증 liveness 프로브입니다. 서비스, DB, 캐시, 브로커가 정상 상태일 때 `{status: \"ok\", timestamp}`와 함께 `HTTP 200`을 반환합니다.",
        "operationId": "get_system_healthcheck",
        "x-didit-sdk": {
          "resource": "system",
          "method": "healthcheck",
          "auth": "public",
          "server": false
        },
        "tags": [
          "System"
        ],
        "security": [
          {}
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "서비스가 정상 작동 중이며 요청을 수락하고 있습니다. 본문은 항상 `{\"status\": \"ok\", \"timestamp\": \"<iso8601>\"}`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status",
                    "timestamp"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ],
                      "description": "라이브니스 마커. 200 응답에서는 항상 리터럴 문자열 `\"ok\"`입니다.",
                      "example": "ok"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time",
                      "description": "상태 확인이 평가된 서버 시간으로, 밀리초 단위 정밀도와 `Z`(UTC) 접미사가 포함된 ISO 8601 형식입니다.",
                      "example": "2026-04-21T16:42:50.445Z"
                    }
                  }
                },
                "examples": {
                  "Healthy": {
                    "summary": "서비스가 정상 작동 중입니다",
                    "value": {
                      "status": "ok",
                      "timestamp": "2026-04-21T16:42:50.445Z"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "서비스가 비정상 상태입니다. 구성된 상태 확인 플러그인(데이터베이스, 캐시, 브로커) 중 하나에 오류가 발생했습니다. 응답 본문은 의도적으로 최소화되어 있으며, HTTP 상태 코드가 핵심 신호입니다. 지수 백오프를 적용하여 재시도하십시오."
          },
          "5XX": {
            "description": "인증 서비스의 성능이 저하되었거나 연결할 수 없습니다. 2xx 이외의 모든 응답을 \"비정상\"으로 처리하고 지수 백오프로 재시도하십시오."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -i https://verification.didit.me/system/healthcheck"
          },
          {
            "lang": "Python",
            "label": "Python (requests)",
            "source": "import requests\n\nresp = requests.get(\"https://verification.didit.me/system/healthcheck\", timeout=5)\nresp.raise_for_status()\nprint(resp.json())  # {'status': 'ok', 'timestamp': '2026-04-21T16:42:50.445Z'}"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (fetch)",
            "source": "const res = await fetch(\"https://verification.didit.me/system/healthcheck\");\nif (!res.ok) throw new Error(`Didit unhealthy: ${res.status}`);\nconst body = await res.json();\nconsole.log(body); // { status: 'ok', timestamp: '2026-04-21T16:42:50.445Z' }"
          }
        ]
      }
    },
    "/v3/email/risk/": {
      "post": {
        "summary": "이메일 주소 위험 점수 산정",
        "description": "OTP를 전송하지 않고 전송 가능 여부, 일회용 주소 여부, 유출 이력, 세션 간 일치 여부 및 정규화된 위험 인텔리전스 신호를 반환합니다. 이 endpoint는 API 세션을 생성하고 해당 ID를 `request_id`로 반환합니다.\n\n**결정.** 최상위 `status`는 `email.status`를 그대로 반영합니다. 일반적으로 `Approved`이며, 위험 평가에 따라 `In Review` 또는 `Declined`가 될 수 있습니다.\n\n**호환성 별칭.** 프로덕션 응답은 정규화된 인텔리전스 객체를 `email.email_intelligence`와 `email.enrichment` 둘 다로 제공합니다. 두 값은 동일합니다. 새로운 연동에서는 `email.enrichment`를 읽으시면 됩니다. 사용 가능한 인텔리전스 데이터가 반환되지 않은 경우 두 키 모두 생략됩니다.\n\n**결제.** 프로덕션 호출에는 Email Risk API 요금이 적용됩니다. 조회가 시작되면 최선 노력(best-effort) 방식으로 제공되는 일부 필드를 사용할 수 없더라도 요청에 대한 요금이 청구됩니다.\n\n**샌드박스.** 샌드박스 키는 이메일을 전송하거나 크레딧을 소비하거나 세션을 생성하거나 Networks에 기여하지 않고, 요청을 검증한 후 결정론적인 승인 데이터를 반환합니다.\n\n**인증.** 애플리케이션의 API 키를 `x-api-key`에 넣어 전송하십시오. 인증 정보가 누락되었거나 유효하지 않은 경우 `403`을 반환하며, 이 API는 `401`을 절대 반환하지 않습니다.\n\n**속도 제한.** POST/PATCH/DELETE endpoint 전반에 걸쳐 API 키당 분당 300개의 쓰기 요청 예산이 공유됩니다(거래 생성 및 이벤트 수집은 별도로 600개의 예산이 배정됨).\n\n**소셜 발자국.** `enable_social`을 `true`로 설정하면 `email_social` 블록이 추가됩니다. 여기에는 카테고리별 개수 및 확인 가능한 프로필 세부 정보와 함께 이 주소가 등록된 온라인 플랫폼 목록이 포함됩니다. `profiles_registered: 0`은 플랫폼들을 확인했으나 해당 주소가 어느 곳에서도 발견되지 않았음을 의미하며, 유효하고 청구 가능한 응답입니다. 부가 기능을 요청하지 않았거나 확인을 완료할 수 없는 경우 해당 블록은 생략되며, 이 경우 요금이 청구되지 않습니다. 결제 시 이 endpoint 자체의 가격에 더해 요청당 1건의 `email_social` 단위가 추가 청구됩니다.",
        "operationId": "post_v3email_risk",
        "x-didit-sdk": {
          "resource": "email",
          "method": "assess_risk",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/email/risk/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"email\": \"alice@example.com\",\n    \"country_code\": \"US\",\n    \"vendor_data\": \"lead-123\",\n    \"metadata\": {\"source\": \"signup_prescreen\"}\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.email.assess_risk(\n    email=\"alice@example.com\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.email.assessRisk({\n  email: \"alice@example.com\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Email.AssessRisk(ctx, didit.EmailRiskRequest{\n\tEmail: \"alice@example.com\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.EmailRiskRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.email().assessRisk(EmailRiskRequest.builder()\n        .email(\"alice@example.com\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->email->assessRisk([\n    'email' => 'alice@example.com',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.email.assess_risk(email: \"alice@example.com\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Email.AssessRiskAsync(new EmailRiskRequest\n{\n    Email = \"alice@example.com\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmailRiskRequest"
              },
              "examples": {
                "Minimal": {
                  "summary": "기본값으로 주소 점수 산정",
                  "value": {
                    "email": "alice@example.com"
                  }
                },
                "Full context": {
                  "summary": "신호, 국가 힌트 및 상관관계 ID를 포함한 점수 산정",
                  "value": {
                    "email": "alice@example.com",
                    "country_code": "US",
                    "signals": {
                      "ip": "192.0.2.1",
                      "device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2",
                      "device_platform": "web",
                      "os_version": "14.4",
                      "app_version": "1.2.34",
                      "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15"
                    },
                    "vendor_data": "lead-123",
                    "metadata": {
                      "source": "signup_prescreen"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "위험 평가가 완료되었습니다. 결정 사항은 `status`를 확인하십시오. 완료된 조회의 경우 HTTP는 항상 `200`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailRiskResponse"
                },
                "examples": {
                  "Clean address": {
                    "summary": "유출 위험이 없는 전송 가능한 주소",
                    "value": {
                      "request_id": "82397be9-5921-4970-a979-2d5b43e08b33",
                      "status": "Approved",
                      "email": {
                        "status": "Approved",
                        "email": "alice@example.com",
                        "is_breached": false,
                        "breaches": [],
                        "is_disposable": false,
                        "is_undeliverable": false,
                        "verification_attempts": 0,
                        "verified_at": null,
                        "warnings": [],
                        "lifecycle": [],
                        "matches": [],
                        "email_intelligence": {
                          "score": 4.0,
                          "deliverable": "high",
                          "breach_risk_level": "Low",
                          "breach_risk_index": 4,
                          "is_recent_breach": false,
                          "is_frequent_breached": false,
                          "is_disposable": false,
                          "is_free_domain": false,
                          "is_breached": false,
                          "no_of_breaches": 0,
                          "reason_codes": []
                        },
                        "enrichment": {
                          "score": 4.0,
                          "deliverable": "high",
                          "breach_risk_level": "Low",
                          "breach_risk_index": 4,
                          "is_recent_breach": false,
                          "is_frequent_breached": false,
                          "is_disposable": false,
                          "is_free_domain": false,
                          "is_breached": false,
                          "no_of_breaches": 0,
                          "reason_codes": []
                        }
                      },
                      "vendor_data": "lead-123",
                      "metadata": {
                        "source": "signup_prescreen"
                      },
                      "created_at": "2026-09-01T10:30:00.123456+00:00"
                    }
                  },
                  "Breached address": {
                    "summary": "알려진 데이터 유출 사건에서 발견된 주소",
                    "value": {
                      "request_id": "d1e5c2a8-6f30-4c1a-8b2d-3e4f5a6b7c8d",
                      "status": "In Review",
                      "email": {
                        "status": "In Review",
                        "email": "bob@example.org",
                        "is_breached": true,
                        "breaches": [
                          {
                            "name": "ExampleBreach2023",
                            "domain": "example.org",
                            "breach_date": "2023-06-01",
                            "breach_emails_count": 1200000,
                            "description": "A data breach affecting example.org accounts.",
                            "logo_path": "https://logos.example.org/example.png",
                            "data_classes": [
                              "email_addresses",
                              "passwords"
                            ],
                            "is_verified": true
                          }
                        ],
                        "is_disposable": false,
                        "is_undeliverable": false,
                        "verification_attempts": 0,
                        "verified_at": null,
                        "warnings": [],
                        "lifecycle": [],
                        "matches": [],
                        "email_intelligence": {
                          "score": 58.0,
                          "deliverable": "high",
                          "breach_risk_level": "High",
                          "breach_risk_index": 72,
                          "is_recent_breach": true,
                          "is_frequent_breached": true,
                          "is_disposable": false,
                          "is_free_domain": true,
                          "is_breached": true,
                          "no_of_breaches": 4,
                          "reason_codes": [
                            {
                              "code": "IR-F784B630",
                              "direction": "risk",
                              "message": "Email's digital footprint diversity is Very Low",
                              "impact_level": "low"
                            }
                          ]
                        },
                        "enrichment": {
                          "score": 58.0,
                          "deliverable": "high",
                          "breach_risk_level": "High",
                          "breach_risk_index": 72,
                          "is_recent_breach": true,
                          "is_frequent_breached": true,
                          "is_disposable": false,
                          "is_free_domain": true,
                          "is_breached": true,
                          "no_of_breaches": 4,
                          "reason_codes": [
                            {
                              "code": "IR-F784B630",
                              "direction": "risk",
                              "message": "Email's digital footprint diversity is Very Low",
                              "impact_level": "low"
                            }
                          ]
                        }
                      },
                      "vendor_data": "lead-125",
                      "metadata": null,
                      "created_at": "2026-09-01T10:30:00.123456+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/EmailRiskValidationError"
          },
          "403": {
            "$ref": "#/components/responses/RiskPermissionDenied"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/ip/risk/": {
      "post": {
        "summary": "IP 주소 위험 점수 산정",
        "description": "제공된 IP 주소에 대한 지리적 위치, 네트워크 소유권, VPN/Tor 및 데이터 센터 플래그, 위협 데이터, `country_mismatch`를 반환합니다. 이 endpoint는 API 세션을 생성하고 해당 ID를 `request_id`로 반환합니다.\n\n**결정.** 확인된 국가가 `claimed_country`와 충돌하거나, 해당 주소가 VPN, Tor 또는 데이터 센터 인프라와 연결되어 있는 경우 `status`는 `In Review`가 됩니다. 그렇지 않은 경우 `Approved`입니다.\n\n**최선의 노력.** IP 보강은 최선의 노력으로 제공됩니다. 사용할 수 있는 데이터를 반환하는 보강 소스가 없는 경우, endpoint는 `ip.ip_address: null`, `ip.country_mismatch: null` 및 빈 `ip.threat` 객체가 포함된 승인된 응답을 반환합니다.\n\n**결제.** 프로덕션 호출에는 IP Risk API 요금이 적용됩니다. 조회가 시작되면 요청에 대한 요금이 청구됩니다.\n\n**샌드박스.** 샌드박스 키는 크레딧을 소비하거나 세션을 생성하거나 Networks에 기여하지 않고, 요청을 검증한 후 결정론적인 승인 데이터를 반환합니다.\n\n**인증.** 애플리케이션의 API 키를 `x-api-key`에 넣어 전송하십시오. 인증 정보가 누락되었거나 유효하지 않은 경우 `403`을 반환하며, 이 API는 `401`을 절대 반환하지 않습니다.\n\n**속도 제한.** POST/PATCH/DELETE endpoint 전반에 걸쳐 API 키당 분당 300개의 쓰기 요청 예산이 공유됩니다(거래 생성 및 이벤트 수집은 별도로 600개의 예산이 배정됨).",
        "operationId": "post_v3ip_risk",
        "x-didit-sdk": {
          "resource": "ip",
          "method": "assess_risk",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/ip/risk/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"ip_address\": \"8.8.8.8\",\n    \"claimed_country\": \"ESP\",\n    \"user_agent\": \"Mozilla/5.0\",\n    \"vendor_data\": \"lead-123\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.ip.assess_risk(\n    ip_address=\"8.8.8.8\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.ip.assessRisk({\n  ip_address: \"8.8.8.8\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IP.AssessRisk(ctx, didit.IPRiskRequest{\n\tIPAddress: \"8.8.8.8\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.IPRiskRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.ip().assessRisk(IPRiskRequest.builder()\n        .ipAddress(\"8.8.8.8\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->ip->assessRisk([\n    'ip_address' => '8.8.8.8',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.ip.assess_risk(ip_address: \"8.8.8.8\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Ip.AssessRiskAsync(new IPRiskRequest\n{\n    IpAddress = \"8.8.8.8\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IPRiskRequest"
              },
              "examples": {
                "Minimal": {
                  "summary": "기본값으로 주소 점수 산정",
                  "value": {
                    "ip_address": "8.8.8.8"
                  }
                },
                "With claimed country": {
                  "summary": "불일치 감지를 위한 신고 국가를 포함한 점수 산정",
                  "value": {
                    "ip_address": "8.8.8.8",
                    "claimed_country": "ESP",
                    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15",
                    "vendor_data": "lead-123"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "위험 평가가 완료되었습니다. 결정 사항은 `status`를 확인하십시오. 완료된 조회의 경우 HTTP는 항상 `200`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IPRiskResponse"
                },
                "examples": {
                  "Clean residential IP": {
                    "summary": "거주지 주소, 명시된 국가가 일치함",
                    "value": {
                      "request_id": "9a96ed2a-721e-4b86-8cbf-d61eda529279",
                      "status": "Approved",
                      "ip": {
                        "status": "Approved",
                        "ip_address": "192.0.2.10",
                        "ip_country": "Spain",
                        "ip_country_code": "ES",
                        "ip_state": "Madrid",
                        "ip_city": "Madrid",
                        "latitude": 40.4168,
                        "longitude": -3.7038,
                        "isp": "Example Telecom",
                        "organization": "Example Telecom SA",
                        "is_vpn_or_tor": false,
                        "is_data_center": false,
                        "time_zone": "Europe/Madrid",
                        "time_zone_offset": "+0200",
                        "asn_number": 3352,
                        "asn_organization": "EXAMPLE-TELECOM",
                        "connection_type": "broadband",
                        "carrier": "Example Telecom",
                        "proxy_type": null,
                        "claimed_country": "ESP",
                        "country_mismatch": false,
                        "threat": {}
                      },
                      "vendor_data": "lead-123",
                      "metadata": null,
                      "created_at": "2026-09-01T10:30:00.123456+00:00"
                    }
                  },
                  "Datacenter mismatch": {
                    "summary": "신고된 국가와 충돌하는 데이터 센터 주소",
                    "value": {
                      "request_id": "5b1d4e9a-3c7b-4f8e-9a2d-1b0c9d8e7f6a",
                      "status": "In Review",
                      "ip": {
                        "status": "In Review",
                        "ip_address": "8.8.8.8",
                        "ip_country": "United States",
                        "ip_country_code": "US",
                        "ip_state": "California",
                        "ip_city": "Mountain View",
                        "latitude": 37.386,
                        "longitude": -122.0838,
                        "isp": "Google",
                        "organization": "Google LLC",
                        "is_vpn_or_tor": true,
                        "is_data_center": true,
                        "time_zone": "America/Los_Angeles",
                        "time_zone_offset": "-0700",
                        "asn_number": 15169,
                        "asn_organization": "GOOGLE, US",
                        "connection_type": "hosting",
                        "carrier": null,
                        "proxy_type": "VPN",
                        "claimed_country": "ESP",
                        "country_mismatch": true,
                        "threat": {
                          "is_proxy": true,
                          "is_data_center": true,
                          "is_tor": false
                        }
                      },
                      "vendor_data": "lead-126",
                      "metadata": null,
                      "created_at": "2026-09-01T10:30:00.123456+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/IPRiskValidationError"
          },
          "403": {
            "$ref": "#/components/responses/RiskPermissionDenied"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/phone/risk/": {
      "post": {
        "summary": "전화번호 위험 점수 산정",
        "description": "OTP를 전송하지 않고 전화번호를 조회하여 통신사, 회선 유형, 번호 이동, 일회용 번호, 세션 간 일치 및 정규화된 위험 인텔리전스 신호를 반환합니다. 이 endpoint는 API 세션을 생성하고 해당 id를 `request_id`로 반환합니다.\n\n**결정.** 최상위 `status`는 `phone.status`를 반영합니다. 일반적으로 `Approved`이며, 위험 평가에 따라 `In Review` 또는 `Declined`가 될 수 있습니다.\n\n**호환성 별칭.** 프로덕션 환경 응답은 정규화된 인텔리전스 객체를 `phone.phone_intelligence` 및 `phone.enrichment` 둘 다로 제공합니다. 두 값은 동일합니다. 새로운 연동에서는 `phone.enrichment`를 읽으면 됩니다. 사용 가능한 인텔리전스 데이터가 반환되지 않은 경우 두 키 모두 생략됩니다.\n\n**결제.** 프로덕션 환경 호출에는 Phone Risk API 요금이 적용됩니다. 조회가 시작되면 일부 최선형 필드를 사용할 수 없더라도 요청에 요금이 청구됩니다.\n\n**샌드박스.** 샌드박스 키는 요청을 검증하고 OTP 전송, 크레딧 소모, 세션 생성 또는 Networks 반영 없이 확정적인 승인 데이터를 반환합니다.\n\n**인증.** 애플리케이션의 API 키를 `x-api-key`에 담아 전송하십시오. 자격 증명이 누락되었거나 유효하지 않은 경우 `403`을 반환하며, 이 API는 `401`을 반환하지 않습니다.\n\n**속도 제한.** POST/PATCH/DELETE endpoint 전반에 걸쳐 API 키당 분당 300개의 요청 공유 쓰기 예산이 적용됩니다(거래 생성 및 이벤트 수집에는 별도로 600개의 예산이 배정됨).\n\n**소셜 발자국.** `enable_social`을 `true`로 설정하면 `phone_social` 블록이 추가됩니다. 여기에는 이 번호가 등록된 온라인 플랫폼, 카테고리별 개수 및 사용 가능한 프로필 세부 정보가 포함됩니다. `profiles_registered: 0`은 플랫폼을 확인했으나 해당 번호가 등록된 곳이 없음을 의미하며, 유효하고 청구 대상인 응답입니다. 추가 기능을 요청하지 않았거나 확인을 완료할 수 없는 경우에는 해당 블록이 생략되며, 이 경우 요금이 청구되지 않습니다. 결제 시 이 endpoint 자체 가격에 요청당 `phone_social` 1단위가 추가됩니다.",
        "operationId": "post_v3phone_risk",
        "x-didit-sdk": {
          "resource": "phone",
          "method": "assess_risk",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/phone/risk/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"phone_number\": \"+14155552671\",\n    \"country_code\": \"US\",\n    \"vendor_data\": \"lead-123\",\n    \"metadata\": {\"source\": \"signup_prescreen\"}\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.phone.assess_risk(\n    phone_number=\"+14155552671\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.phone.assessRisk({\n  phone_number: \"+14155552671\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Phone.AssessRisk(ctx, didit.PhoneRiskRequest{\n\tPhoneNumber: \"+14155552671\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.PhoneRiskRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.phone().assessRisk(PhoneRiskRequest.builder()\n        .phoneNumber(\"+14155552671\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->phone->assessRisk([\n    'phone_number' => '+14155552671',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.phone.assess_risk(phone_number: \"+14155552671\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Phone.AssessRiskAsync(new PhoneRiskRequest\n{\n    PhoneNumber = \"+14155552671\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PhoneRiskRequest"
              },
              "examples": {
                "Minimal": {
                  "summary": "기본값을 사용해 번호 점수 산정",
                  "value": {
                    "phone_number": "+14155552671"
                  }
                },
                "Full context": {
                  "summary": "신호, 국가 힌트 및 상관관계 ID를 포함한 점수 산정",
                  "value": {
                    "phone_number": "+14155552671",
                    "country_code": "US",
                    "signals": {
                      "ip": "192.0.2.1",
                      "device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2",
                      "device_platform": "ios",
                      "device_model": "iPhone17,2",
                      "os_version": "18.0.1",
                      "app_version": "1.2.34",
                      "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"
                    },
                    "vendor_data": "lead-123",
                    "metadata": {
                      "source": "signup_prescreen"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "위험 평가가 완료되었습니다. 결정 사항은 `status`를 확인하십시오. 완료된 조회의 경우 HTTP는 항상 `200`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneRiskResponse"
                },
                "examples": {
                  "Clean mobile number": {
                    "summary": "인텔리전스 커버리지가 포함된 유효한 휴대폰 번호",
                    "value": {
                      "request_id": "4fd09d2e-9bc9-4c4e-9c46-7f625ac0ab62",
                      "status": "Approved",
                      "phone": {
                        "status": "Approved",
                        "phone_number_prefix": "+1",
                        "phone_number": "4155552671",
                        "full_number": "+14155552671",
                        "country_code": "US",
                        "country_name": "United States",
                        "carrier": {
                          "name": "Example Mobile",
                          "type": "mobile"
                        },
                        "is_disposable": false,
                        "is_virtual": false,
                        "verification_method": null,
                        "verification_attempts": 0,
                        "verified_at": null,
                        "warnings": [],
                        "lifecycle": [],
                        "matches": [],
                        "phone_intelligence": {
                          "score": 3.0,
                          "phone_type_risk": "Low",
                          "phone_trust_index": 97,
                          "network_stability_index": 95,
                          "is_disposable": false,
                          "is_ported": false,
                          "is_recently_ported": false,
                          "carrier_type": "mobile",
                          "reason_codes": []
                        },
                        "enrichment": {
                          "score": 3.0,
                          "phone_type_risk": "Low",
                          "phone_trust_index": 97,
                          "network_stability_index": 95,
                          "is_disposable": false,
                          "is_ported": false,
                          "is_recently_ported": false,
                          "carrier_type": "mobile",
                          "reason_codes": []
                        }
                      },
                      "vendor_data": "lead-123",
                      "metadata": {
                        "source": "signup_prescreen"
                      },
                      "created_at": "2026-09-01T10:30:00.123456+00:00"
                    }
                  },
                  "Number in review": {
                    "summary": "검토 대상으로 플래그 지정된 일회용 또는 가상 번호",
                    "value": {
                      "request_id": "8c22e1f0-4b3d-4a3a-9d1e-2f6b7c8d9e0f",
                      "status": "In Review",
                      "phone": {
                        "status": "In Review",
                        "phone_number_prefix": "+44",
                        "phone_number": "7700900123",
                        "full_number": "+447700900123",
                        "country_code": "GB",
                        "country_name": "United Kingdom",
                        "carrier": {
                          "name": "Example VoIP",
                          "type": "voip"
                        },
                        "is_disposable": true,
                        "is_virtual": true,
                        "verification_method": null,
                        "verification_attempts": 0,
                        "verified_at": null,
                        "warnings": [],
                        "lifecycle": [],
                        "matches": [],
                        "phone_intelligence": {
                          "score": 72.0,
                          "phone_type_risk": "High",
                          "phone_trust_index": 28,
                          "network_stability_index": 40,
                          "is_disposable": true,
                          "is_ported": true,
                          "is_recently_ported": true,
                          "carrier_type": "voip",
                          "reason_codes": [
                            {
                              "code": "IR-5AC67A32",
                              "direction": "risk",
                              "message": "Phone type identified as non-mobile",
                              "impact_level": "medium"
                            }
                          ]
                        },
                        "enrichment": {
                          "score": 72.0,
                          "phone_type_risk": "High",
                          "phone_trust_index": 28,
                          "network_stability_index": 40,
                          "is_disposable": true,
                          "is_ported": true,
                          "is_recently_ported": true,
                          "carrier_type": "voip",
                          "reason_codes": [
                            {
                              "code": "IR-5AC67A32",
                              "direction": "risk",
                              "message": "Phone type identified as non-mobile",
                              "impact_level": "medium"
                            }
                          ]
                        }
                      },
                      "vendor_data": "lead-124",
                      "metadata": null,
                      "created_at": "2026-09-01T10:30:00.123456+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/PhoneRiskValidationError"
          },
          "403": {
            "$ref": "#/components/responses/RiskPermissionDenied"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/": {
      "post": {
        "summary": "인증 세션 생성",
        "description": "사용자 인증(KYC) 또는 기업 확인(KYB) 세션을 생성하고 최종 사용자에게 리디렉션하거나 임베드할 수 있는 호스팅 인증 `url` 및 `session_token`을 받습니다. `workflow_id`에 따라 실행할 인증 단계와 세션이 KYC인지 KYB인지가 결정됩니다.\n\n사용자나 기업의 인증이 필요할 때마다(회원가입 시, 민감한 작업 전 또는 재인증이 필요할 때) 백엔드에서 이 endpoint를 호출하세요(API 키는 비밀 정보이므로 브라우저에서는 절대 호출하지 마세요). 사전 요구 사항: 게시된 워크플로(콘솔 [Workflows](https://docs.didit.me/ko/console/workflows) 페이지에서 생성됨) 및 사용 가능한 크레딧이 있는 애플리케이션 API 키. 샌드박스 애플리케이션은 크레딧 확인을 건너뜁니다.\n\n**멱등성:** `vendor_data`가 제공되고 워크플로의 **현재 최신 게시 버전**에 동일한 `vendor_data`를 가진 완료되지 않은 세션(`Not Started`, `In Progress`, `Resubmitted` 또는 `Awaiting User`)이 이미 존재하며(해당 세션에 이미 호스팅 인증 URL이 있는 경우), 중복을 생성하는 대신 기존 세션이 반환(여전히 `201`)되며 `callback` 및 `metadata`가 새로 제공된 값으로 업데이트됩니다. 워크플로의 이전 버전(이후 다시 게시된 버전)에서 생성된 완료되지 않은 세션은 재사용되지 **않으며**, 최신 게시 버전에 고정된 새 세션이 대신 생성됩니다. `Approved`, `Declined`, `In Review`, `Expired`, `Abandoned` 또는 `Kyc Expired` 상태의 세션은 절대 재사용되지 않습니다.\n\n**부작용:** 호스팅 인증 URL이 생성되어 저장됩니다. `contact_details.send_notification_emails`가 `true`이고 이메일이 제공되면 인증 초대 이메일이 전송됩니다. 세션은 워크플로에 구성된 세션 만료 시간 후에 만료됩니다. KYB 워크플로의 경우 `contact_details.phone` 및 `expected_details`는 무시됩니다.",
        "operationId": "post_v3_session_create",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "responses": {
          "201": {
            "description": "세션이 생성되었습니다(또는 워크플로의 최신 게시 버전에 동일한 `vendor_data`를 가진 완료되지 않은 세션이 이미 존재하는 경우 해당 세션이 반환됨). 응답은 사용자를 리디렉션할 호스팅 인증 `url`을 포함하는 직렬화된 세션입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "session_id",
                    "session_number",
                    "session_token",
                    "url",
                    "vendor_data",
                    "metadata",
                    "status",
                    "workflow_id",
                    "workflow_version",
                    "callback"
                  ],
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "인증 세션의 고유 식별자입니다. `GET /v3/session/{sessionId}/decision/`을 호출할 때 이 id를 사용합니다.",
                      "example": "11111111-2222-3333-4444-555555555555"
                    },
                    "session_number": {
                      "type": "integer",
                      "description": "애플리케이션 내에서 세션에 할당된 사람이 읽기 쉬운 순차 번호입니다. 고객 지원 및 대시보드에 유용합니다.",
                      "example": 43762
                    },
                    "session_token": {
                      "type": "string",
                      "description": "최종 사용자가 `url`의 호스팅 인증 흐름에 접근할 수 있도록 권한을 부여하는 12자의 URL-safe token입니다. 세션이 만료될 때까지 유효합니다. 비밀 정보로 취급하십시오. 이 token을 보유한 사람은 누구나 해당 세션의 인증 흐름을 열 수 있습니다.",
                      "example": "3FaJ9wLqX2Mz"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri",
                      "description": "최종 사용자를 리디렉션할 호스팅 인증 URL입니다. URL에는 `session_token`이 포함되어 있으며, 구성된 경우 화이트 라벨 도메인을 사용합니다. 요청에 `language`가 포함되어 있으면 URL에 언어 경로 세그먼트(`https://verify.didit.me/{language}/session/{session_token}`, 예: `/es/session/...`)가 포함되고, `language`가 없으면 해당 세그먼트가 생략됩니다.",
                      "example": "https://verify.didit.me/session/3FaJ9wLqX2Mz"
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "자체 시스템의 사용자 또는 기업과 세션을 연결하기 위해 요청에 전달한 식별자입니다. 입력한 그대로 반환됩니다. 제공되지 않은 경우 null입니다.",
                      "example": "user-123"
                    },
                    "metadata": {
                      "description": "세션 생성 시 함께 저장한 임의의 JSON payload입니다. 보낸 JSON 값(객체, 문자열, 숫자, 배열)이 그대로 반환되지만, JSON 객체를 사용하는 것이 좋습니다. 최종 사용자에게는 표시되지 않습니다. 응답에 항상 포함되며, 생성 시 제공되지 않은 경우 `null`입니다.",
                      "example": {
                        "user_type": "premium",
                        "account_id": "ABC123"
                      }
                    },
                    "tags": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "세션의 태그를 이름으로 표시합니다.",
                      "example": [
                        "VIP",
                        "ONBOARDING Q4"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "Not Started",
                        "In Progress",
                        "Approved",
                        "Declined",
                        "In Review",
                        "Expired",
                        "Abandoned",
                        "Kyc Expired",
                        "Resubmitted",
                        "Awaiting User"
                      ],
                      "description": "세션의 현재 상태입니다. 새로 생성된 세션은 `Not Started`를 반환합니다. 워크플로의 최신 게시 버전에 동일한 `vendor_data`를 가진 완료되지 않은 세션이 이미 존재하는 경우, 반환되는 상태에는 해당 기존 세션의 상태가 반영됩니다.",
                      "example": "Not Started"
                    },
                    "callback": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "사용자가 플로우를 완료한 후 이동하게 되는 최종 리디렉션 URL입니다. Didit은 이 URL에 `?verificationSessionId={session_id}&status={status}`를 추가합니다. 요청에서 제공되지 않은 경우 워크플로에 구성된 콜백 URL로 대체되며, 둘 다 설정되지 않은 경우 `null`입니다. 애플리케이션에 허용된 도메인이 설정되어 있고 이 URL이 해당 도메인 외의 웹 URL인 경우(예: 목록이 변경되기 전에 설정된 워크플로 기본값), 호스팅 플로우는 사용자를 해당 URL로 리디렉션하지 않습니다.",
                      "example": "https://example.com/verification/callback"
                    },
                    "workflow_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "이 세션이 실행되는 워크플로의 안정적인 식별자입니다. 항상 워크플로의 안정적인 그룹 식별자이며, 요청에서 특정 워크플로 버전 UUID를 참조했더라도(하위 호환성 조회) 응답에는 안정적인 `workflow_id`가 반환됩니다. 콘솔에서 구성한 워크플로와 세션을 연결하는 데 사용하세요.",
                      "example": "11111111-2222-3333-4444-555555555555"
                    },
                    "workflow_version": {
                      "type": "integer",
                      "description": "세션 생성 시 고정된 게시된 워크플로 버전의 버전 번호입니다. Didit은 세션이 생성될 때 `workflow_id`를 워크플로의 최신 게시 버전에 매핑하며, 이후 워크플로가 다시 게시되더라도 세션은 해당 버전을 계속 실행합니다.",
                      "example": 3
                    }
                  }
                },
                "examples": {
                  "KYC session": {
                    "summary": "KYC 세션이 생성됨",
                    "value": {
                      "session_id": "11111111-2222-3333-4444-555555555555",
                      "session_number": 43762,
                      "session_token": "3FaJ9wLqX2Mz",
                      "url": "https://verify.didit.me/en/session/3FaJ9wLqX2Mz",
                      "vendor_data": "user-123",
                      "metadata": {
                        "user_type": "premium",
                        "account_id": "ABC123"
                      },
                      "status": "Not Started",
                      "workflow_id": "11111111-2222-3333-4444-555555555555",
                      "workflow_version": 3,
                      "callback": "https://example.com/verification/callback"
                    }
                  },
                  "KYB session": {
                    "summary": "KYB 세션이 생성됨",
                    "value": {
                      "session_id": "22222222-3333-4444-5555-666666666666",
                      "session_number": 43763,
                      "session_token": "Yk7pQ2vN8aBc",
                      "url": "https://verify.didit.me/en/session/Yk7pQ2vN8aBc",
                      "vendor_data": "company-acme-001",
                      "metadata": {
                        "tier": "enterprise"
                      },
                      "status": "Not Started",
                      "workflow_id": "33333333-4444-5555-6666-777777777777",
                      "workflow_version": 1,
                      "callback": "https://example.com/kyb/callback"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "잘못된 요청 — payload 유효성 검사에 실패했거나(`workflow_id` 누락 또는 알 수 없음, 잘못된 `language`, 차단 목록에 포함된 `vendor_data`, 잘못된 형식의 `portrait_image`, `country`/`poa_country`가 없는 `address`, 잘못된 `sandbox_scenario`, `signature_document_not_supported`, `signature_document_conversion_failed`, `field_anchor_not_found`, `field_value_missing` 등 워크플로의 전자 서명 단계에서 거부하는 `sign` 문서, 필드 또는 값) 조직에 세션을 시작하기 위한 크레딧이 부족합니다.\n\n본문은 문제가 발생한 필드 이름을 키로 갖는 객체입니다(필드 외 오류의 경우 `detail`). 값은 입력 유효성 검사 실패(예: 필수 필드 누락, 잘못된 언어, 허용 크기를 초과한 인물 사진 이미지)의 경우 **문자열 배열**이며, 세션 생성 중 감지된 실패(알 수 없는 `workflow_id`, 차단 목록에 포함된 `vendor_data`, 얼굴 대조 워크플로에 사용 가능한 기준 얼굴 없음)의 경우 **일반 문자열**입니다. 두 형태를 모두 처리하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "필드 오류가 아닌 경우(예: 크레딧 부족)의 사람이 읽기 쉬운 오류 메시지입니다. 필드 수준의 오류는 대신 필드 이름을 키로 사용하며, 문자열 또는 문자열 배열 값을 가집니다.",
                      "example": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                },
                "examples": {
                  "Missing workflow_id": {
                    "summary": "필수 필드가 누락됨(문자열 배열 형식)",
                    "value": {
                      "workflow_id": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid workflow_id": {
                    "summary": "알 수 없는 workflow_id(일반 문자열 형식)",
                    "value": {
                      "workflow_id": "Invalid workflow_id."
                    }
                  },
                  "Insufficient credits": {
                    "summary": "조직의 크레딧이 부족합니다",
                    "value": {
                      "detail": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  },
                  "Blocklisted vendor_data": {
                    "summary": "vendor_data가 차단 목록에 있습니다",
                    "value": {
                      "vendor_data": "This user or business has been blocked and cannot create new verification sessions."
                    }
                  },
                  "Portrait image too large": {
                    "summary": "portrait_image 크기 유효성 검사 실패",
                    "value": {
                      "portrait_image": [
                        "Image size exceeds 2MB."
                      ]
                    }
                  },
                  "No stored face for vendor_data": {
                    "summary": "portrait_image가 없고 vendor_data 사용자에 대해 저장된 얼굴이 없는 얼굴 대조 워크플로",
                    "value": {
                      "portrait_image": "No stored face image was found for this user. Send a portrait_image, or complete an approved verification with face liveness or an ID document for this vendor_data first."
                    }
                  },
                  "Portrait image required without vendor_data": {
                    "summary": "portrait_image 및 vendor_data가 없는 얼굴 대조 워크플로",
                    "value": {
                      "portrait_image": "A portrait image is required to perform face match for this workflow. Send a portrait_image, or provide the vendor_data of a user with a previously stored face image to reuse it."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `x-api-key` 헤더가 없거나, API 키가 유효하지만 클라이언트에 이 애플리케이션에서 세션을 생성할 수 있는 권한이 없는 경우(예: API 키가 다른 조직에 속한 경우) endpoint는 `403`을 반환합니다. 이러한 실패는 `{\"detail\": \"You do not have permission to perform this action.\"}` 본문을 공유합니다. `x-api-key` 헤더가 존재하며 의도한 애플리케이션에 속하는지 확인하고, 필요한 경우 [Auth API](/ko/auth-api/get-credentials)를 통해 애플리케이션 API 키를 다시 가져와 재시도하십시오.\n\n**삭제된 애플리케이션:** 애플리케이션이 삭제된 후 몇 분 동안 해당 API 키 중 하나로 전송된 요청에 대해 `{\"detail\": \"This application was deleted.\", \"code\": \"application_deleted\"}` 응답이 반환될 수 있습니다. 재시도하지 마십시오. 해당 애플리케이션과 API 키는 더 이상 존재하지 않습니다. 이 몇 분이 지나면 키는 다른 유효하지 않은 키와 마찬가지로 거부됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "You do not have permission to perform this action."
                    },
                    "code": {
                      "type": "string",
                      "description": "기계 판독 가능한 사유로, 일부 실패 시에만 제공됩니다. `application_deleted`: API 키가 삭제된 애플리케이션에 속해 있습니다.",
                      "example": "application_deleted"
                    }
                  },
                  "required": [
                    "detail"
                  ]
                },
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나 잘못된 API 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "No permission": {
                    "summary": "클라이언트가 세션을 생성할 수 없음",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Application deleted": {
                    "summary": "삭제된 애플리케이션의 API 키",
                    "value": {
                      "detail": "This application was deleted.",
                      "code": "application_deleted"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. 동일한 API 키 또는 IP에서 60초 동안 600회를 초과하는 세션 생성 요청이 발생했습니다. `Retry-After`를 확인하고 백오프 후 재시도하세요.\n\n**참고:** 소스 코드에는 `PAID_SESSION_RATE_LIMIT=600`과 함께 분당 10회 호출의 `FREE_SESSION_RATE_LIMIT`도 정의되어 있지만(`sessions/serializers/session.py`), 해당 무료 요금제 상한은 **이 V3 endpoint에는 적용되지 않습니다**. 속도 제한 미들웨어는 요금제와 관계없이 분당 600회의 `SESSION_CREATE_RATE_LIMIT`을 적용합니다. 여기서 적용되는 유일한 한도는 분당 600회입니다.",
            "headers": {
              "Retry-After": {
                "description": "호출자가 요청을 재시도하기 전에 대기해야 하는 시간(초).",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 42
                }
              },
              "X-RateLimit-Limit": {
                "description": "초과된 제한에 대해 현재 60초 윈도우에서 허용되는 최대 요청 수(세션 생성의 경우 600)입니다. 샌드박스 할당량 변형에는 없습니다.",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "위반된 제한에 대해 현재 윈도우에서 여전히 허용되는 요청 수입니다. 샌드박스 쿼터 변형에는 표시되지 않습니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "현재 속도 제한 윈도우가 초기화되는 UTC 에포크 초입니다. 샌드박스 할당량 변형에서는 제공되지 않습니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "example": 1747497600
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "속도 제한 초과에 대한 사람이 읽기 쉬운 설명입니다. 이 메시지를 사용하여 세 가지 제한 중 어느 제한에 도달했는지 구분하십시오.",
                      "example": "Session creation rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                },
                "examples": {
                  "Session-create limit": {
                    "summary": "분당 600건을 초과하는 세션 생성 요청 발생",
                    "value": {
                      "detail": "Session creation rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  },
                  "Sandbox session quota": {
                    "summary": "샌드박스 애플리케이션이 24시간 내에 500개 세션을 초과했습니다",
                    "value": {
                      "detail": "Sandbox session quota exceeded (500 sessions per 24h). Wait for the window to reset. Expected available in 3600 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/session/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"workflow_id\": \"11111111-2222-3333-4444-555555555555\",\n    \"vendor_data\": \"user-123\",\n    \"callback\": \"https://example.com/verification/callback\",\n    \"callback_method\": \"both\",\n    \"metadata\": {\"user_type\": \"premium\", \"account_id\": \"ABC123\"},\n    \"language\": \"en\",\n    \"contact_details\": {\n      \"email\": \"john.doe@example.com\",\n      \"send_notification_emails\": true,\n      \"email_lang\": \"en\",\n      \"phone\": \"+14155552671\"\n    },\n    \"expected_details\": {\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"date_of_birth\": \"1990-05-15\",\n      \"id_country\": \"USA\",\n      \"expected_document_types\": [\"P\", \"ID\"]\n    }\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.create(\n    workflow_id=\"11111111-2222-3333-4444-555555555555\",\n    vendor_data=\"user-123\",\n    callback=\"https://example.com/verification/callback\",\n    callback_method=\"both\",\n    metadata={\"user_type\": \"premium\", \"account_id\": \"ABC123\"},\n    language=\"en\",\n    contact_details={\n        \"email\": \"john.doe@example.com\",\n        \"send_notification_emails\": True,\n        \"email_lang\": \"en\",\n        \"phone\": \"+14155552671\",\n    },\n    expected_details={\n        \"first_name\": \"John\",\n        \"last_name\": \"Doe\",\n        \"date_of_birth\": \"1990-05-15\",\n        \"nationality\": \"USA\",\n        \"id_country\": \"USA\",\n        \"expected_document_types\": [\"P\", \"ID\"],\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.create({\n  workflow_id: \"11111111-2222-3333-4444-555555555555\",\n  vendor_data: \"user-123\",\n  callback: \"https://example.com/verification/callback\",\n  callback_method: \"both\",\n  metadata: { user_type: \"premium\", account_id: \"ABC123\" },\n  language: \"en\",\n  contact_details: {\n    email: \"john.doe@example.com\",\n    send_notification_emails: true,\n    email_lang: \"en\",\n    phone: \"+14155552671\",\n  },\n  expected_details: {\n    first_name: \"John\",\n    last_name: \"Doe\",\n    date_of_birth: \"1990-05-15\",\n    nationality: \"USA\",\n    id_country: \"USA\",\n    expected_document_types: [\"P\", \"ID\"],\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Create(ctx, didit.SessionsCreateParams{\n\tWorkflowID:     \"11111111-2222-3333-4444-555555555555\",\n\tVendorData:     didit.String(\"user-123\"),\n\tCallback:       didit.String(\"https://example.com/verification/callback\"),\n\tCallbackMethod: didit.Some(didit.SessionsCreateParamsCallbackMethod(\"both\")),\n\tMetadata:       didit.Some[any](map[string]any{\"user_type\": \"premium\", \"account_id\": \"ABC123\"}),\n\tLanguage:       didit.Some(didit.SessionsCreateParamsLanguage(\"en\")),\n\tContactDetails: didit.Some(didit.SessionsCreateParamsContactDetails{\n\t\tEmail:                  didit.String(\"john.doe@example.com\"),\n\t\tSendNotificationEmails: didit.Bool(true),\n\t\tEmailLang:              didit.Some(didit.SessionsCreateParamsContactDetailsEmailLang(\"en\")),\n\t\tPhone:                  didit.String(\"+14155552671\"),\n\t}),\n\tExpectedDetails: didit.Some(didit.SessionsCreateParamsExpectedDetails{\n\t\tFirstName:             didit.String(\"John\"),\n\t\tLastName:              didit.String(\"Doe\"),\n\t\tDateOfBirth:           didit.String(\"1990-05-15\"),\n\t\tNationality:           didit.String(\"USA\"),\n\t\tIDCountry:             didit.String(\"USA\"),\n\t\tExpectedDocumentTypes: didit.Some([]didit.SessionsCreateParamsExpectedDetailsExpectedDocumentTypes{\"P\", \"ID\"}),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().create(SessionsCreateParams.builder()\n        .workflowId(\"11111111-2222-3333-4444-555555555555\")\n        .vendorData(\"user-123\")\n        .callback(\"https://example.com/verification/callback\")\n        .callbackMethod(SessionsCreateParams.CallbackMethod.of(\"both\"))\n        .metadata(Map.of(\"user_type\", \"premium\", \"account_id\", \"ABC123\"))\n        .language(SessionsCreateParams.Language.of(\"en\"))\n        .contactDetails(SessionsCreateParams.ContactDetails.builder()\n                .email(\"john.doe@example.com\")\n                .sendNotificationEmails(true)\n                .emailLang(SessionsCreateParams.ContactDetails.EmailLang.of(\"en\"))\n                .phone(\"+14155552671\")\n                .build())\n        .expectedDetails(SessionsCreateParams.ExpectedDetails.builder()\n                .firstName(\"John\")\n                .lastName(\"Doe\")\n                .dateOfBirth(LocalDate.parse(\"1990-05-15\"))\n                .nationality(\"USA\")\n                .idCountry(\"USA\")\n                .expectedDocumentTypes(List.of(SessionsCreateParams.ExpectedDetails.ExpectedDocumentTypes.of(\"P\"), SessionsCreateParams.ExpectedDetails.ExpectedDocumentTypes.of(\"ID\")))\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->create([\n    'workflow_id' => '11111111-2222-3333-4444-555555555555',\n    'vendor_data' => 'user-123',\n    'callback' => 'https://example.com/verification/callback',\n    'callback_method' => 'both',\n    'metadata' => ['user_type' => 'premium', 'account_id' => 'ABC123'],\n    'language' => 'en',\n    'contact_details' => [\n        'email' => 'john.doe@example.com',\n        'send_notification_emails' => true,\n        'email_lang' => 'en',\n        'phone' => '+14155552671',\n    ],\n    'expected_details' => [\n        'first_name' => 'John',\n        'last_name' => 'Doe',\n        'date_of_birth' => '1990-05-15',\n        'nationality' => 'USA',\n        'id_country' => 'USA',\n        'expected_document_types' => ['P', 'ID'],\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.create(\n  workflow_id: \"11111111-2222-3333-4444-555555555555\",\n  vendor_data: \"user-123\",\n  callback: \"https://example.com/verification/callback\",\n  callback_method: \"both\",\n  metadata: { user_type: \"premium\", account_id: \"ABC123\" },\n  language: \"en\",\n  contact_details: {\n    email: \"john.doe@example.com\",\n    send_notification_emails: true,\n    email_lang: \"en\",\n    phone: \"+14155552671\",\n  },\n  expected_details: {\n    first_name: \"John\",\n    last_name: \"Doe\",\n    date_of_birth: \"1990-05-15\",\n    nationality: \"USA\",\n    id_country: \"USA\",\n    expected_document_types: [\"P\", \"ID\"],\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.CreateAsync(new SessionsCreateParams\n{\n    WorkflowId = \"11111111-2222-3333-4444-555555555555\",\n    VendorData = \"user-123\",\n    Callback = \"https://example.com/verification/callback\",\n    CallbackMethod = new SessionsCreateParamsCallbackMethod(\"both\"),\n    Metadata = new Dictionary<string, object> { [\"user_type\"] = \"premium\", [\"account_id\"] = \"ABC123\" },\n    Language = new SessionsCreateParamsLanguage(\"en\"),\n    ContactDetails = new SessionsCreateParamsContactDetails\n    {\n        Email = \"john.doe@example.com\",\n        SendNotificationEmails = true,\n        EmailLang = new SessionsCreateParamsContactDetailsEmailLang(\"en\"),\n        Phone = \"+14155552671\",\n    },\n    ExpectedDetails = new SessionsCreateParamsExpectedDetails\n    {\n        FirstName = \"John\",\n        LastName = \"Doe\",\n        DateOfBirth = \"1990-05-15\",\n        Nationality = \"USA\",\n        IdCountry = \"USA\",\n        ExpectedDocumentTypes = new SessionsCreateParamsExpectedDetailsExpectedDocumentTypes[] { \"P\", \"ID\" },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "workflow_id"
                ],
                "properties": {
                  "workflow_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "세션에서 실행할 인증 단계를 정의하는 워크플로의 안정적인 식별자입니다. 워크플로는 콘솔의 [워크플로](/ko/console/workflows) 페이지에서 생성 및 관리됩니다. `workflow_id`는 세션이 KYC인지 KYB인지도 암시적으로 선택합니다.",
                    "example": "11111111-2222-3333-4444-555555555555",
                    "x-readme-id": "0.0"
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "인증 대상 사용자의 고유 식별자(UUID, 이메일, 내부 사용자 ID 등)입니다. 이 필드는 다음 용도로 사용됩니다. (1) **사용자 그룹화** — 동일한 vendor_data를 가진 세션은 Users 탭에서 동일한 사용자 프로필로 연결됩니다. (2) **세션 간 중복 감지** — 중복된 얼굴, 문서, 전화번호, 이메일, IP 주소 또는 기기 지문을 확인할 때 동일한 vendor_data를 가진 세션은 동일한 사용자로 처리되어 일치 항목에서 제외됩니다. vendor_data가 없으면 모든 세션이 고유한 사용자로 처리되어 모든 잠재적 중복 항목이 표시됩니다. 중복 감지의 노이즈를 줄이기 위해 항상 vendor_data를 제공하는 것을 강력히 권장합니다.",
                    "example": "user-123",
                    "x-readme-id": "0.1"
                  },
                  "multi_account_segment": {
                    "type": "string",
                    "maxLength": 64,
                    "description": "조직 내의 선택적 중복 감지 영역입니다. 중복 얼굴 확인은 이 세션을 동일한 세그먼트를 가진 다른 세션들과만 비교하므로, 별도의 계정 기반(개인 및 기업 계정 또는 B2B 하위 고객사별 계정)이 있는 경우 양쪽에 정당하게 계정을 보유한 인물을 오탐 플래그로 지정하지 않습니다. 생략하면 현재 모든 세션이 사용하는 단일 기본 영역을 사용합니다. 차단 목록 및 허용 목록 매칭 시에는 이 필드가 무시됩니다.",
                    "example": "business-accounts"
                  },
                  "callback": {
                    "type": "string",
                    "description": "인증 완료 후 사용자를 리디렉션할 URL입니다. Didit은 `verificationSessionId` 및 `status`(Approved, Declined, In Review)를 쿼리 파라미터로 자동 추가합니다. 모바일 콜백을 위한 커스텀 URL 스킴(예: `myapp://`)이 지원됩니다. 생략하면 워크플로의 기본 `callback_url`이 사용됩니다. 애플리케이션에 허용된 도메인이 설정된 경우(`PATCH /v3/webhook/`의 `allowed_domains`), `http` 또는 `https` 콜백은 해당 오리진 중 하나에 있어야 하며(동일한 스킴, 호스트 및 포트), 그렇지 않으면 `callback`에서 400 오류와 함께 요청이 실패합니다: `callback must be on one of the application's allowed domains: https://app.example.com`. 커스텀 URL 스킴은 항상 허용됩니다.",
                    "example": "https://example.com/verification/callback",
                    "x-readme-id": "0.2"
                  },
                  "callback_method": {
                    "type": "string",
                    "description": "제공된 콜백 URL로의 리디렉션을 처리할 기기를 결정합니다. 흐름을 시작한 기기만 리디렉션하려면 `initiator`, 흐름을 완료하는 기기는 `completer`, 두 기기 중 어느 쪽이든 콜백을 트리거할 수 있도록 허용하려면 `both`를 사용하십시오. 콜백이 안정적으로 트리거되지 않는 문제가 발생할 경우 이 값을 `both`로 설정하는 것을 권장합니다.",
                    "enum": [
                      "initiator",
                      "completer",
                      "both"
                    ],
                    "default": "initiator",
                    "example": "both",
                    "x-readme-id": "0.3"
                  },
                  "metadata": {
                    "description": "세션과 함께 저장되며 응답 및 webhook에 그대로 반환되는 임의의 JSON입니다. 모든 JSON 값(객체, 문자열, 숫자, 배열)이 허용되지만, 키/값 쌍의 JSON 객체를 사용하는 것이 좋습니다. 최종 사용자에게는 표시되지 않습니다. 자체 상관 관계 ID, A/B 변형 또는 비즈니스 컨텍스트를 전달하는 데 사용하십시오.",
                    "example": {
                      "user_type": "premium",
                      "account_id": "ABC123"
                    },
                    "x-readme-id": "0.4"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 50
                    },
                    "maxItems": 10,
                    "description": "세션이 생성될 때 이름별로 추가된 태그입니다. 최대 10개, 각각 최대 50자입니다. 이름은 대소문자를 구분하지 않으며 대문자로 저장됩니다. 애플리케이션에 아직 존재하지 않는 이름은 새 태그로 생성됩니다. 태그는 콘솔의 세션에 표시되며, 이를 기준으로 필터링할 수 있습니다.",
                    "example": [
                      "VIP",
                      "ONBOARDING Q4"
                    ]
                  },
                  "language": {
                    "type": "string",
                    "description": "인증 프로세스 인터페이스의 언어 코드(ISO 639-1)입니다. 인증 중에 최종 사용자에게 표시되는 언어를 제어합니다. 제공되지 않으면 브라우저 언어가 자동으로 감지되어 사용됩니다. 지원되는 모든 언어는 [여기](/ko/integration/supported-languages)에서 확인하세요.",
                    "enum": [
                      "en",
                      "ar",
                      "bg",
                      "bn",
                      "bs",
                      "ca",
                      "cnr",
                      "cs",
                      "da",
                      "de",
                      "el",
                      "es",
                      "et",
                      "fa",
                      "fi",
                      "fr",
                      "he",
                      "hi",
                      "hr",
                      "hu",
                      "hy",
                      "id",
                      "it",
                      "ja",
                      "ka",
                      "kk",
                      "ko",
                      "ky",
                      "lt",
                      "lv",
                      "mk",
                      "mn",
                      "ms",
                      "nl",
                      "no",
                      "pl",
                      "pt-BR",
                      "pt",
                      "ro",
                      "ru",
                      "sk",
                      "sl",
                      "so",
                      "sq",
                      "sr",
                      "sv",
                      "th",
                      "tr",
                      "uk",
                      "uz",
                      "vi",
                      "zh-CN",
                      "zh-TW",
                      "zh"
                    ],
                    "example": "en",
                    "x-readme-id": "0.5"
                  },
                  "contact_details": {
                    "type": "object",
                    "description": "알림, 인증 양식 자동 완성 및 전화번호 인증에 사용할 수 있는 사용자 연락처 정보입니다. 이메일 주소, 통신에 사용할 선호 언어 및 전화번호가 포함됩니다.",
                    "example": {
                      "email": "john.doe@example.com",
                      "send_notification_emails": true,
                      "email_lang": "en",
                      "phone": "+14155552671"
                    },
                    "properties": {
                      "email": {
                        "type": "string",
                        "format": "email",
                        "description": "[이메일 인증](/ko/core-technology/email-verification/overview) 단계에서 사용될 사용자의 이메일 주소(예: \"john.doe@example.com\")입니다. 제공되지 않으면 사용자가 인증 플로우 중에 직접 입력해야 합니다.",
                        "example": "john.doe@example.com",
                        "x-readme-id": "1.0"
                      },
                      "send_notification_emails": {
                        "type": "boolean",
                        "default": false,
                        "description": "true이고 이메일이 제공된 경우, Didit은 사용자 인증(KYC) 또는 기업 확인(KYB) 세션이 생성될 때 최초의 \"신원을 인증하세요\" 이메일을 비동기식으로 전송합니다. 또한 Didit은 수동 검토가 필요한 세션에 대해 인증 상태 알림을 제공된 이메일 주소로 전송합니다(예: 'In Review'에서 'Approved' 또는 'Declined'로 변경). 이를 통해 사용자가 인증 완료 후 애플리케이션으로 다시 돌아올 수 있도록 돕습니다. 세션에 화이트 라벨이 활성화되어 있는 경우 전송되는 이메일에 화이트 라벨이 적용됩니다.",
                        "example": true,
                        "x-readme-id": "1.1"
                      },
                      "email_lang": {
                        "type": "string",
                        "description": "이메일 알림 언어 코드(ISO 639-1)입니다. 모든 이메일 커뮤니케이션의 언어를 제어합니다(예: \"en\", \"es\", \"fr\"). 저장된 기본값은 없습니다. 생략 시 발송 시점에 인증 초대 이메일이 영어(`en`)로 자동 대체됩니다. 아래 enum은 스냅샷이며, 허용되는 값의 실시간 기준은 [지원 언어](/ko/integration/supported-languages) 문서이므로 특정 코드를 사용하기 전에 항상 확인하세요.",
                        "enum": [
                          "en",
                          "ar",
                          "bg",
                          "bn",
                          "bs",
                          "ca",
                          "cnr",
                          "cs",
                          "da",
                          "de",
                          "el",
                          "es",
                          "et",
                          "fa",
                          "fi",
                          "fr",
                          "he",
                          "hi",
                          "hr",
                          "hu",
                          "hy",
                          "id",
                          "it",
                          "ja",
                          "ka",
                          "kk",
                          "ko",
                          "ky",
                          "lt",
                          "lv",
                          "mk",
                          "mn",
                          "ms",
                          "nl",
                          "no",
                          "pl",
                          "pt-BR",
                          "pt",
                          "ro",
                          "ru",
                          "sk",
                          "sl",
                          "so",
                          "sq",
                          "sr",
                          "sv",
                          "th",
                          "tr",
                          "uk",
                          "uz",
                          "vi",
                          "zh-CN",
                          "zh-TW",
                          "zh"
                        ],
                        "example": "en",
                        "x-readme-id": "1.2"
                      },
                      "phone": {
                        "type": "string",
                        "description": "[전화번호 인증](/ko/core-technology/phone-verification/overview) 단계에서 사용될 E.164 형식의 전화번호(예: \"+14155552671\")입니다. 제공되지 않으면 사용자가 인증 플로우 중에 직접 제공해야 합니다. 기업 확인(KYB) 워크플로에서는 무시됩니다. **중요:** 이 전화번호는 유효한 E.164 형식 전화번호인 경우에만 적용됩니다. 제공된 번호가 유효하지 않거나 파싱할 수 없는 경우 무시되며 사용자는 전화번호 인증 단계에서 유효한 전화번호를 자유롭게 입력할 수 있습니다.",
                        "example": "+14155552671",
                        "x-readme-id": "1.3"
                      }
                    },
                    "x-readme-id": "0.4"
                  },
                  "expected_details": {
                    "type": "object",
                    "description": "사용자의 신분증 문서, 주소 증명 및 기타 인증 단계에서 추출된 데이터와 교차 검증하는 데 사용되는 예상 사용자 세부정보입니다. 불일치 항목은 결정 시 경고로 표시되며, 일부 필드(예: `id_country`, `expected_document_types`)는 사용자 대상 플로우를 변경하기도 합니다. 기업 확인(KYB) 워크플로의 경우 기업 필드(`company_name`, `registry_country`, `registration_number`)만 사용되어 사용자를 위한 법인 등기부 검색을 미리 채우며, 모든 개인 단위 필드는 무시됩니다.",
                    "example": {
                      "first_name": "John",
                      "last_name": "Doe",
                      "date_of_birth": "1990-05-15",
                      "nationality": "USA",
                      "id_country": "USA",
                      "expected_document_types": [
                        "P",
                        "ID"
                      ]
                    },
                    "properties": {
                      "first_name": {
                        "type": "string",
                        "description": "사용자의 이름입니다. 예: `John`. 일치 여부는 퍼지 비교를 사용하며, 콘솔에서 신분증 및 주소 증명 워크플로 모두에 대해 이름 일치 점수 임계값을 설정하여 엄격도를 조정할 수 있습니다.",
                        "example": "John",
                        "x-readme-id": "1.0"
                      },
                      "last_name": {
                        "type": "string",
                        "description": "사용자의 성입니다. 예: `Doe`. 일치 여부는 퍼지 비교를 사용하며, 콘솔에서 신분증 및 주소 증명 워크플로 모두에 대해 이름 일치 점수 임계값을 설정하여 엄격도를 조정할 수 있습니다.",
                        "example": "Doe",
                        "x-readme-id": "1.1"
                      },
                      "date_of_birth": {
                        "type": "string",
                        "format": "date",
                        "description": "사용자의 생년월일 형식: YYYY-MM-DD. 예: `1990-05-15`.",
                        "example": "1990-05-15",
                        "x-readme-id": "1.2"
                      },
                      "gender": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                          "M",
                          "F"
                        ],
                        "default": null,
                        "description": "사용자의 성별입니다. 'M', 'F' 또는 null이어야 합니다.",
                        "example": "M",
                        "x-readme-id": "1.3"
                      },
                      "nationality": {
                        "type": "string",
                        "description": "신청자의 출신 국가를 나타내는 ISO 3166-1 alpha-3 국가 코드입니다. 예: `USA`. [지원되는 국가 코드 전체 목록](https://docs.didit.me/ko/core-technology/id-verification/supported-documents-id-verification#국가별-지원-문서)을 참조하십시오.",
                        "example": "USA",
                        "x-readme-id": "1.4"
                      },
                      "country": {
                        "type": "string",
                        "description": "신분증 인증 및 주소 증명 국가 불일치 확인 모두에 대체 값으로 사용되는 ISO 3166-1 alpha-3 국가 코드입니다. `address`가 제공되고 `id_country`와 `poa_country`가 모두 설정되지 않은 경우 필수입니다.",
                        "example": "USA",
                        "x-readme-id": "1.4.1"
                      },
                      "id_country": {
                        "type": "string",
                        "description": "신청자의 신분증 문서의 예상 국가를 나타내는 ISO 3166-1 alpha-3 국가 코드이며, 국적과 다를 수 있습니다. 예: `GBR`. 신분증 인증 국가 불일치 확인 시 `country`보다 우선 적용됩니다. [지원되는 국가 코드 전체 목록](https://docs.didit.me/ko/core-technology/id-verification/supported-documents-id-verification#국가별-지원-문서)을 참조하십시오.",
                        "example": "GBR",
                        "x-readme-id": "1.5"
                      },
                      "poa_country": {
                        "type": "string",
                        "description": "주소 증명 문서의 예상 국가를 나타내는 ISO 3166-1 alpha-3 국가 코드입니다. 예: `USA`. POA 국가 불일치 확인 시 `country`보다 우선 적용됩니다. [지원되는 국가 코드 전체 목록](https://docs.didit.me/ko/core-technology/id-verification/supported-documents-id-verification#국가별-지원-문서)을 참조하십시오.",
                        "example": "USA",
                        "x-readme-id": "1.5.1"
                      },
                      "address": {
                        "type": "string",
                        "description": "가능한 한 많은 정보를 포함한 사람이 읽을 수 있는 형식의 주소입니다. 예를 들어 `123 Main St, San Francisco, CA 94105, USA`입니다. 제공할 경우 `country` 또는 `poa_country`도 함께 전달해야 하며, 그렇지 않으면 요청이 `400`으로 실패합니다.",
                        "example": "123 Main St, San Francisco, CA 94105, USA",
                        "x-readme-id": "1.6"
                      },
                      "identification_number": {
                        "type": "string",
                        "description": "사용자의 문서 번호, 개인 식별 번호 또는 납세자 번호입니다. 예를 들어 `123456789`입니다.",
                        "example": "123456789",
                        "x-readme-id": "1.7"
                      },
                      "ip_address": {
                        "type": "string",
                        "description": "IPv4 또는 IPv6 형식의 세션 예상 IP 주소입니다. 실제 IP 주소가 이 값과 다르면 경고가 기록됩니다. 예: `192.168.1.100` 또는 `2001:db8::1`.",
                        "example": "192.168.1.100",
                        "x-readme-id": "1.8"
                      },
                      "expected_document_types": {
                        "type": "array",
                        "description": "신분증 인증(OCR) 단계에서 사용자가 제시할 수 있는 문서 유형을 제한합니다. 설정하면 문서 선택 화면에 요청된 유형만 표시되고 반환되는 `documents_allowed`도 이에 따라 필터링됩니다. 값은 대소문자를 구분하지 않으며 중복이 제거됩니다. 알 수 없는 값은 `400`으로 거부됩니다. 허용되는 코드: `P`(여권), `ID`(국가 신분증), `DL`(운전면허증), `RP`(거주 허가증), `HIC`(건강보험증), `TC`(세금 카드), `SSC`(사회보장 카드).",
                        "items": {
                          "type": "string",
                          "enum": [
                            "P",
                            "ID",
                            "DL",
                            "RP",
                            "HIC",
                            "TC",
                            "SSC"
                          ]
                        },
                        "example": [
                          "P",
                          "ID"
                        ],
                        "x-readme-id": "1.9"
                      },
                      "company_name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "인증 대상 기업의 예상 법적 명칭입니다. 예를 들어 `Tesco PLC`입니다. 기업 확인(KYB) 워크플로의 등기부 검색에서 회사명 필드를 미리 채웁니다. `registration_number`도 함께 제공되면 등기부 조회 시 두 식별자를 결합합니다. KYC 워크플로에서는 무시됩니다.",
                        "example": "Tesco PLC",
                        "x-readme-id": "1.10"
                      },
                      "registry_country": {
                        "type": "string",
                        "maxLength": 10,
                        "description": "기업이 등록된 법인 등기부의 국가에 해당하는 ISO 3166-1 alpha-2 코드입니다. 예를 들어 `GB`입니다. 법인 등기부가 주 또는 도 단위로 운영되는 경우 `XX-YY` 형식으로 ISO 3166-2 행정 구역 코드를 추가합니다. `US-CA`는 캘리포니아 등기부를 대상으로 합니다. [KYB Registry Search API](https://docs.didit.me/ko/standalone-apis/kyb-registry-search)의 `country_code`와 동일한 형식입니다. 기업 확인(KYB) 워크플로에서 등기부 국가를 미리 선택하며, KYC 워크플로에서는 무시됩니다.",
                        "example": "US-CA",
                        "x-readme-id": "1.11"
                      },
                      "registration_number": {
                        "type": "string",
                        "maxLength": 100,
                        "description": "법인 등기부상 기업의 예상 등록번호입니다. 예를 들어 `00445790`입니다. 기업 확인(KYB) 워크플로의 등기부 검색에서 등록번호 필드를 미리 채웁니다. `company_name`도 함께 제공되면 등기부 조회 시 두 식별자를 결합합니다. KYC 워크플로에서는 무시됩니다.",
                        "example": "00445790",
                        "x-readme-id": "1.12"
                      }
                    },
                    "x-readme-id": "0.5"
                  },
                  "portrait_image": {
                    "type": "string",
                    "format": "byte",
                    "description": "최종 사용자의 얼굴을 촬영한 Base64 인코딩된 인물 사진 이미지입니다(최대 2MB, JPEG, PNG, WebP 또는 TIFF). 워크플로가 얼굴 대조가 활성화된 `Biometric Authentication` 워크플로이거나, 얼굴 대조가 신분증 인증(OCR)보다 먼저 실행되는 그래프 워크플로인 경우 라이브니스 캡처와 대조할 기준 이미지로 사용됩니다. `vendor_data` 사용자에게 이미 저장된 얼굴 이미지가 있는 경우 선택 사항입니다. Didit은 승인된 라이브니스 얼굴, 전자여권(ePassport) 칩 사진, 신분증 인물 사진, 직접 등록한 프로필 얼굴 순으로 우선순위를 확인하여 자동으로 재사용합니다(승인된 세션의 얼굴 또는 직접 등록한 얼굴만 재사용됨). `portrait_image`가 제공되면 저장된 얼굴보다 항상 우선 적용됩니다. 생략되었고 저장된 얼굴도 없는 경우(또는 `vendor_data`가 전송되지 않은 경우) 세션 생성은 `400` 오류로 실패합니다. 다른 워크플로 유형에서는 무시됩니다.",
                    "example": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=",
                    "x-readme-id": "0.6"
                  },
                  "sandbox_scenario": {
                    "type": "string",
                    "description": "샌드박스 전용 시나리오 slug입니다. API 키가 샌드박스 모드 애플리케이션에 속한 경우에만 허용되며, 프로덕션 애플리케이션에서는 거부됩니다. 설정 시 생성 흐름에서 시나리오에 번들된 매직 값을 세션의 입력 필드(contact_details, expected_details)로 확장하여 모의 제공업체가 실제 워크플로 파이프라인을 통해 시나리오 결과를 재현하도록 합니다. GET /v1/sandbox/scenarios/ 또는 [Sandbox & Test Data](/ko/integration/sandbox-testing)에서 시나리오 카탈로그를 확인하세요. 또한 세션이 아직 `Not Started` 상태인 경우 POST /v3/session/{sessionId}/sandbox/arm/을 통해 생성 후 시나리오를 준비(또는 재준비)할 수도 있습니다. 비문서 조회의 경우 `lookup_partial_match`, `lookup_no_match` 또는 `lookup_provider_error`를 사용하여 구성된 시도 예산 및 폴백을 테스트하세요. 신원 지갑의 경우 `wallet_cancelled`, `wallet_timeout` 또는 `wallet_provider_error`를 사용하세요. `approve`는 검증된 지갑을 시뮬레이션합니다. 프로덕션 애플리케이션에서 사용할 수 없는 방식을 포함하여 카탈로그의 모든 지갑을 샌드박스에서 테스트할 수 있습니다. 시뮬레이션된 시도에는 요금이 청구되지 않습니다.",
                    "example": "decline_document_expired"
                  },
                  "sign": {
                    "type": "object",
                    "description": "이 세션에 대한 전자 서명 입력값입니다. `documents`는 서명할 문서이며, 전자 서명 단계가 세션에서 문서를 가져오는 워크플로(`signature_documents_source`가 `session` 또는 `both`)의 경우 최대 20개 문서 및 총 50MB까지 가능합니다. `field_values`는 워크플로 및 세션 문서 모두에서 `prefill`이 `api.<key>`인 필드를 채웁니다. 동일한 `workflow_id` 및 `vendor_data`로 세션을 다시 생성하면 대기 중인 세션이 반환됩니다. 해당 호출이 `sign`을 전송하는 경우 해당 문서, 필드 및 값은 첫 번째 호출과 동일해야 하며, 다를 경우 `{\"sign\": \"signature_document_changed\"}`와 함께 `400`이 반환됩니다. [전자 서명 문서](/ko/sessions-api/create-session#전자-서명-문서)를 참조하세요.",
                    "properties": {
                      "documents": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 20,
                        "items": {
                          "$ref": "#/components/schemas/SessionSignDocument"
                        }
                      },
                      "field_values": {
                        "type": "object",
                        "description": "각 `api.<key>` 사전 채우기 소스의 `<key>`를 키로 하는 값: `text` 및 `data` 필드의 경우 1~500자의 문자열, `checkbox`의 경우 불리언입니다. 어떤 필드에서도 사용하지 않는 키의 경우 `field_value_unknown`, 값이 없는 필수 필드의 경우 `field_value_missing`, 필드 검증에 실패한 값의 경우 `field_value_invalid`와 함께 `400`이 반환됩니다.",
                        "additionalProperties": {
                          "oneOf": [
                            {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            {
                              "type": "boolean"
                            }
                          ]
                        },
                        "example": {
                          "credit_limit": "3,000 EUR"
                        }
                      }
                    }
                  },
                  "user_state": {
                    "type": "string",
                    "maxLength": 16,
                    "description": "알려진 경우 해당 개인이 거주하는 위치: ISO 3166-2 세부 구역 코드(`US-IL`, `ES-M`) 또는 미국 주 코드나 이름(`IL`, `Illinois`). 법적으로 명시적인 생체 인증 동의를 요구하는 주(일리노이, 텍사스, 콜로라도)의 경우 인증 흐름에서 얼굴을 캡처하기 전에 `declared_state` 트리거와 함께 동의를 요청합니다. 인식할 수 없는 값은 `400`을 반환합니다. [생체 인증 동의](/ko/getting-started/biometric-consent)를 참고하십시오.",
                    "example": "US-IL"
                  },
                  "biometric_consent": {
                    "type": "object",
                    "description": "해당 인물로부터 이미 수집한 명시적 생체 인식 동의입니다. 요구사항을 충족하므로 인증 플로우에서 다시 묻지 않으며, 결정에는 트리거 `customer_collected`와 함께 `status: \"given\"`으로 기록됩니다. 사용자가 플로우에서 이미 제출한 답변은 대체되지 않습니다. [생체 인식 동의](/ko/getting-started/biometric-consent)를 참고하십시오.",
                    "required": [
                      "given_at",
                      "text_version"
                    ],
                    "properties": {
                      "given_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "사용자가 명시적인 생체 인식 동의를 제공한 시점(ISO 8601)입니다. 미래 시점일 수 없습니다."
                      },
                      "text_version": {
                        "type": "string",
                        "maxLength": 64,
                        "description": "자체 기록 내 사용자가 수락한 동의 텍스트의 버전 ID입니다."
                      }
                    }
                  }
                },
                "example": {
                  "workflow_id": "11111111-2222-3333-4444-555555555555",
                  "vendor_data": "user-123",
                  "callback": "https://example.com/verification/callback",
                  "callback_method": "both",
                  "metadata": {
                    "user_type": "premium",
                    "account_id": "ABC123"
                  },
                  "language": "en",
                  "contact_details": {
                    "email": "john.doe@example.com",
                    "send_notification_emails": true,
                    "email_lang": "en",
                    "phone": "+14155552671"
                  },
                  "expected_details": {
                    "first_name": "John",
                    "last_name": "Doe",
                    "date_of_birth": "1990-05-15",
                    "id_country": "USA",
                    "expected_document_types": [
                      "P",
                      "ID"
                    ]
                  }
                }
              },
              "examples": {
                "Create KYC session": {
                  "summary": "사용자 인증(KYC) 세션에 대한 전체 정상 경로(happy-path) payload",
                  "description": "자주 설정되는 모든 필드를 사용하는 실용적인 생성 호출 예시입니다: 워크플로 선택, 벤더 연동, 콜백 라우팅, 메타데이터, 로캘, 연락처 사전 입력, 예상 사용자 세부 정보. 위의 cURL 샘플에 그대로 복사하여 붙여넣으세요.",
                  "value": {
                    "workflow_id": "11111111-2222-3333-4444-555555555555",
                    "vendor_data": "user-123",
                    "callback": "https://example.com/verification/callback",
                    "callback_method": "both",
                    "metadata": {
                      "user_type": "premium",
                      "account_id": "ABC123"
                    },
                    "language": "en",
                    "contact_details": {
                      "email": "john.doe@example.com",
                      "send_notification_emails": true,
                      "email_lang": "en",
                      "phone": "+14155552671"
                    },
                    "expected_details": {
                      "first_name": "John",
                      "last_name": "Doe",
                      "date_of_birth": "1990-05-15",
                      "nationality": "USA",
                      "id_country": "USA",
                      "expected_document_types": [
                        "P",
                        "ID"
                      ]
                    }
                  }
                },
                "Create KYB session": {
                  "summary": "기업 확인(KYB) 세션에 대한 정상 경로 payload",
                  "description": "KYC 호출과 동일한 형태입니다. 세션을 KYB로 만드는 것은 `workflow_id`입니다. `vendor_data`는 일반적으로 귀하의 시스템에서 회사를 참조하며, `contact_details.email`은 절차를 완료할 법정 대리인을 대상으로 합니다. `expected_details`는 법인 등기부 검색을 미리 채우는 기업 필드(`company_name`, `registry_country`, `registration_number`)를 허용합니다. 개인 수준 필드 및 `contact_details.phone`은 KYB 워크플로에서 무시됩니다.",
                  "value": {
                    "workflow_id": "33333333-4444-5555-6666-777777777777",
                    "vendor_data": "company-acme-001",
                    "callback": "https://example.com/kyb/callback",
                    "callback_method": "both",
                    "metadata": {
                      "tier": "enterprise",
                      "company_id": "ACME-001"
                    },
                    "expected_details": {
                      "company_name": "Tesco PLC",
                      "registry_country": "GB",
                      "registration_number": "00445790"
                    },
                    "language": "en",
                    "contact_details": {
                      "email": "legal-rep@acme.example.com",
                      "send_notification_emails": true,
                      "email_lang": "en"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/session/imports/": {
      "post": {
        "summary": "인증 가져오기 작업 생성",
        "description": "과거 사용자 인증 세션, 기업 확인(KYB) 세션, 거래 모니터링 기록 또는 워크플로 커스텀 상태 규칙에 대한 비동기 가져오기 작업을 생성합니다. 다른 제공업체에서 이전하려면 `source=provider`로 설정하세요. Didit은 읽기 전용 키를 사용하여 Sumsub, Onfido, Persona 및 ComplyCube를 읽고, `file`에 업로드한 ID를 통해 Veriff, iDenfy 및 MetaMap 기록을 읽으며, 그 외 제공업체에 대해서는 Didit 형식의 내보내기 파일을 가져옵니다. 기록 ID에는 제공업체별 네임스페이스(`sumsub:<id>`)가 지정되므로 재실행 시 Didit에 이미 존재하는 모든 항목을 건너뛰며, 제공업체의 순수 ID가 포함된 파일을 통해 가져온 기록도 양방향으로 인식되므로 파일 가져오기와 제공업체 마이그레이션 간을 전환해도 기록이 중복으로 가져와지지 않습니다. 애플리케이션은 한 번에 최대 4개의 가져오기 작업을 실행할 수 있으며, 배포나 워커 재시작으로 인해 중단된 작업은 마지막으로 가져온 행부터 자동으로 계속 진행됩니다. 가져오기는 기본적으로 비활성화되어 있으며 Didit에서 조직별로 활성화해야 합니다.",
        "operationId": "post_v3_session_imports_create",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "import_type": {
                    "type": "string",
                    "enum": [
                      "user_verification",
                      "business_verification",
                      "status_rules",
                      "transactions"
                    ],
                    "default": "user_verification",
                    "description": "가져올 항목: 이전 사용자 인증 세션, 이전 기업 확인 세션, 워크플로 커스텀 상태 규칙, 또는 이전 거래 모니터링 기록."
                  },
                  "workflow_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "가져온 세션이나 상태 규칙을 연결할 워크플로 UUID입니다. user_verification, business_verification, status_rules의 경우 필수입니다. 거래(transactions)의 경우 생략합니다."
                  },
                  "source_format": {
                    "type": "string",
                    "enum": [
                      "csv",
                      "ndjson"
                    ],
                    "description": "선택 사항입니다. 생략 시 업로드된 파일 확장자에서 유추됩니다."
                  },
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "표준 CSV 또는 NDJSON 파일입니다. 대용량 가져오기에는 NDJSON을 사용하십시오. 최대 업로드 크기는 25MB입니다(더 큰 파일에는 `source_file_url` 사용). `source_file_url`과 상호 배타적입니다."
                  },
                  "source_file_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "파일 업로드의 대안입니다. 공인 주소로 확인되는 HTTPS URL이어야 합니다(사설/루프백 네트워크는 거부됨). `file`과 상호 배타적입니다."
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "file",
                      "provider"
                    ],
                    "description": "`provider`는 다른 신분증 인증 공급자로부터의 마이그레이션을 의미합니다. 파일 가져오기의 경우 생략하십시오."
                  },
                  "provider": {
                    "type": "string",
                    "enum": [
                      "sumsub",
                      "jumio",
                      "veriff",
                      "onfido",
                      "persona",
                      "metamap",
                      "socure",
                      "idnow",
                      "shufti",
                      "idenfy",
                      "ondato",
                      "trulioo",
                      "au10tix",
                      "complycube",
                      "other"
                    ],
                    "description": "`GET /v3/session/imports/providers/`에서 가져온 마이그레이션 소스입니다. `source`가 `provider`인 경우 필수입니다."
                  },
                  "credentials": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "`credential_fields`에 나열된 필드 이름을 포함하는 공급자의 읽기 전용 키입니다. 저장 시 암호화되고, 반환되지 않으며, 가져오기가 끝나면 삭제됩니다. multipart에서 JSON 문자열로 전송하십시오."
                  },
                  "options": {
                    "type": "object",
                    "properties": {
                      "region": {
                        "type": "string",
                        "description": "해당 `regions` 중 하나인 공급자 리전입니다(Onfido: `eu`, `us`, `ca`)."
                      }
                    }
                  },
                  "status_mapping": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string",
                      "enum": [
                        "Approved",
                        "Declined",
                        "In Review",
                        "Expired",
                        "Not Finished",
                        "Abandoned"
                      ]
                    },
                    "description": "제공업체의 기본 상태 매핑(소스 상태에서 Didit 상태로)을 수정합니다. `Not Finished` 및 `Abandoned`는 건너뛰고 카운트되며 가져오지 않습니다."
                  },
                  "dry_run": {
                    "type": "boolean",
                    "default": false,
                    "description": "마이그레이션 시 가져올 대상을 계산하고(상태별, 이미 Didit에 존재함, 동일인, 완료되지 않음) 아무것도 기록하지 않습니다. 작업은 `READY` 상태로 종료되며, `POST /v3/session/imports/{importId}/start/`로 시작합니다."
                  },
                  "face_templates": {
                    "type": "boolean",
                    "default": false,
                    "description": "가져온 셀피로 얼굴 템플릿을 생성하고 애플리케이션의 얼굴 및 차단 목록과 대조하여 검색합니다. 일치 항목은 검토용으로만 플래그가 지정됩니다. `lawful_basis_confirmed`가 필요합니다."
                  },
                  "lawful_basis_confirmed": {
                    "type": "boolean",
                    "default": false,
                    "description": "처리자로서 Didit과 해당 셀피를 공유할 수 있는 적법한 근거가 있음을 확인합니다."
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "source_file_url"
                ],
                "properties": {
                  "import_type": {
                    "type": "string",
                    "enum": [
                      "user_verification",
                      "business_verification",
                      "status_rules",
                      "transactions"
                    ],
                    "default": "user_verification",
                    "description": "가져올 항목: 이전 사용자 인증 세션, 이전 기업 확인 세션, 워크플로 커스텀 상태 규칙, 또는 이전 거래 모니터링 기록."
                  },
                  "workflow_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "가져온 세션이나 상태 규칙을 연결할 워크플로 UUID입니다. user_verification, business_verification, status_rules의 경우 필수입니다. 거래(transactions)의 경우 생략합니다."
                  },
                  "source_format": {
                    "type": "string",
                    "enum": [
                      "csv",
                      "ndjson"
                    ],
                    "description": "선택 사항입니다. 생략 시 URL의 파일 확장자에서 유추됩니다."
                  },
                  "source_file_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "파일 업로드의 대안입니다. 공인 주소로 확인되는 HTTPS URL이어야 합니다(사설/루프백 네트워크는 거부됨). `file`과 상호 배타적입니다."
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "file",
                      "provider"
                    ],
                    "description": "`provider`는 다른 신분증 인증 공급자로부터의 마이그레이션을 의미합니다. 파일 가져오기의 경우 생략하십시오."
                  },
                  "provider": {
                    "type": "string",
                    "enum": [
                      "sumsub",
                      "jumio",
                      "veriff",
                      "onfido",
                      "persona",
                      "metamap",
                      "socure",
                      "idnow",
                      "shufti",
                      "idenfy",
                      "ondato",
                      "trulioo",
                      "au10tix",
                      "complycube",
                      "other"
                    ],
                    "description": "`GET /v3/session/imports/providers/`에서 가져온 마이그레이션 소스입니다. `source`가 `provider`인 경우 필수입니다."
                  },
                  "credentials": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "`credential_fields`에 나열된 필드 이름을 포함하는 공급자의 읽기 전용 키입니다. 저장 시 암호화되고, 반환되지 않으며, 가져오기가 끝나면 삭제됩니다. multipart에서 JSON 문자열로 전송하십시오."
                  },
                  "options": {
                    "type": "object",
                    "properties": {
                      "region": {
                        "type": "string",
                        "description": "해당 `regions` 중 하나인 공급자 리전입니다(Onfido: `eu`, `us`, `ca`)."
                      }
                    }
                  },
                  "status_mapping": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string",
                      "enum": [
                        "Approved",
                        "Declined",
                        "In Review",
                        "Expired",
                        "Not Finished",
                        "Abandoned"
                      ]
                    },
                    "description": "제공업체의 기본 상태 매핑(소스 상태에서 Didit 상태로)을 수정합니다. `Not Finished` 및 `Abandoned`는 건너뛰고 카운트되며 가져오지 않습니다."
                  },
                  "dry_run": {
                    "type": "boolean",
                    "default": false,
                    "description": "마이그레이션 시 가져올 대상을 계산하고(상태별, 이미 Didit에 존재함, 동일인, 완료되지 않음) 아무것도 기록하지 않습니다. 작업은 `READY` 상태로 종료되며, `POST /v3/session/imports/{importId}/start/`로 시작합니다."
                  },
                  "face_templates": {
                    "type": "boolean",
                    "default": false,
                    "description": "가져온 셀피로 얼굴 템플릿을 생성하고 애플리케이션의 얼굴 및 차단 목록과 대조하여 검색합니다. 일치 항목은 검토용으로만 플래그가 지정됩니다. `lawful_basis_confirmed`가 필요합니다."
                  },
                  "lawful_basis_confirmed": {
                    "type": "boolean",
                    "default": false,
                    "description": "처리자로서 Didit과 해당 셀피를 공유할 수 있는 적법한 근거가 있음을 확인합니다."
                  }
                }
              },
              "examples": {
                "URL-based import": {
                  "value": {
                    "import_type": "user_verification",
                    "workflow_id": "9f9b1234-aaaa-bbbb-cccc-1234567890ab",
                    "source_file_url": "https://files.example.com/exports/sessions.ndjson"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "가져오기 작업이 접수되었습니다. `status`가 `COMPLETED` 또는 `FAILED`가 될 때까지 반환된 `uuid`를 폴링하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                },
                "examples": {
                  "Job accepted": {
                    "value": {
                      "uuid": "3f9c1a2b-4d5e-4f60-8a7b-9c0d1e2f3a4b",
                      "status": "PENDING",
                      "import_type": "user_verification",
                      "source_format": "ndjson",
                      "source_filename": "sessions.ndjson",
                      "total_rows": 0,
                      "processed_rows": 0,
                      "checkpoint_row": 0,
                      "created_count": 0,
                      "updated_count": 0,
                      "skipped_count": 0,
                      "failed_count": 0,
                      "total_media_bytes": 0,
                      "last_error": null,
                      "created_at": "2026-05-17T08:42:11Z",
                      "updated_at": "2026-05-17T08:42:11Z",
                      "started_at": null,
                      "completed_at": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 워크플로, 파일 형식, 파일 크기, 소스 URL 또는 선택기 조합입니다. 제공업체가 키를 거부한 마이그레이션은 `code`(`invalid_credentials`, `missing_permission`, `wrong_region`, `provider_unavailable`, `rate_limited`, `ids_required`, `record_not_found`), `missing_permissions`, `suggested_region`으로 응답합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid workflow": {
                    "value": {
                      "workflow_id": [
                        "Invalid workflow_id."
                      ]
                    }
                  },
                  "Workflow required": {
                    "value": {
                      "workflow_id": [
                        "This field is required for this import type."
                      ]
                    }
                  },
                  "Wrong file type": {
                    "value": {
                      "file": [
                        "Only CSV and NDJSON files are supported."
                      ]
                    }
                  },
                  "File too large": {
                    "value": {
                      "file": [
                        "Import file exceeds the maximum allowed size."
                      ]
                    }
                  },
                  "No source": {
                    "value": {
                      "file": [
                        "Upload a file or provide source_file_url."
                      ]
                    }
                  },
                  "Both sources": {
                    "value": {
                      "file": [
                        "Use either file or source_file_url, not both."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "가져오기가 활성화되지 않았거나, 샌드박스 애플리케이션이거나, API 키가 누락되었습니다(잘못되었거나 취소되었거나 만료된 키는 `401` 반환). 인증 가져오기는 기본적으로 비활성화되어 있으며 Didit에서 조직별로 활성화해야 합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Imports not enabled": {
                    "value": {
                      "detail": "Verification imports are not enabled for this organization."
                    }
                  },
                  "Sandbox": {
                    "value": {
                      "detail": "Verification imports are not enabled for sandbox applications."
                    }
                  },
                  "Bad API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "애플리케이션에 이미 4개의 활성 가져오기 작업(PENDING/PROCESSING/PAUSED)이 있으며, 이는 동시에 실행할 수 있는 최대 개수입니다. 다른 작업을 시작하기 전에 기존 작업 중 하나가 완료될 때까지 기다리십시오.",
            "content": {
              "application/json": {
                "examples": {
                  "Active job": {
                    "value": {
                      "detail": "This application already has 4 active import jobs, the most it can run at once. Wait for one to finish before starting another."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.create(\n    import_type=\"user_verification\",\n    workflow_id=\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n    source_file_url=\"https://files.example.com/exports/sessions.ndjson\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.create({\n  import_type: \"user_verification\",\n  workflow_id: \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n  source_file_url: \"https://files.example.com/exports/sessions.ndjson\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Create(ctx, didit.SessionsImportsCreateParams{\n\tImportType:    didit.Some(didit.SessionsImportsCreateParamsImportType(\"user_verification\")),\n\tWorkflowID:    didit.String(\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\"),\n\tSourceFileURL: didit.String(\"https://files.example.com/exports/sessions.ndjson\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsImportsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().create(SessionsImportsCreateParams.builder()\n        .importType(SessionsImportsCreateParams.ImportType.of(\"user_verification\"))\n        .workflowId(\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\")\n        .sourceFileUrl(\"https://files.example.com/exports/sessions.ndjson\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->create([\n    'import_type' => 'user_verification',\n    'workflow_id' => '9f9b1234-aaaa-bbbb-cccc-1234567890ab',\n    'source_file_url' => 'https://files.example.com/exports/sessions.ndjson',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.create(\n  import_type: \"user_verification\",\n  workflow_id: \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n  source_file_url: \"https://files.example.com/exports/sessions.ndjson\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.CreateAsync(new SessionsImportsCreateParams\n{\n    ImportType = new SessionsImportsCreateParamsImportType(\"user_verification\"),\n    WorkflowId = \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n    SourceFileUrl = \"https://files.example.com/exports/sessions.ndjson\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/template/": {
      "get": {
        "summary": "인증 가져오기 템플릿 다운로드",
        "description": "인증 가져오기를 위한 표준 CSV 헤더를 다운로드합니다. 열 집합은 `import_type`에 따라 결정됩니다. 세션 템플릿의 첫 번째 열은 멱등성 키인 `external_id`입니다.",
        "operationId": "get_v3_session_imports_template",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "retrieve_template",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "import_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "user_verification",
                "business_verification",
                "status_rules",
                "transactions"
              ],
              "default": "user_verification"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "CSV 템플릿 파일입니다.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 폐기되었거나, 해당 키에 가져오기 템플릿을 다운로드할 수 있는 권한이 없습니다. 누락된 키는 `403`을 반환하며, 잘못되었거나 폐기되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "summary": "누락되었거나 유효하지 않거나 취소된 API 키",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.imports.retrieve_template()\nwith open(\"download.csv\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.imports.retrieveTemplate();\nawait writeFile(\"download.csv\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.Imports.RetrieveTemplate(ctx, didit.SessionsImportsRetrieveTemplateParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.csv\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().imports().retrieveTemplate()\n        .writeTo(Path.of(\"download.csv\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->sessions->imports->retrieveTemplate();\n$content->saveTo('download.csv');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.imports.retrieve_template\nFile.binwrite(\"download.csv\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.Imports.RetrieveTemplateAsync();\nawait content.SaveToAsync(\"download.csv\");"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/": {
      "get": {
        "summary": "인증 가져오기 작업 조회",
        "description": "단일 작업에 대한 가져오기 진행률 카운터 및 최종 상태를 조회합니다. `status`가 `COMPLETED` 또는 `FAILED`가 될 때까지 폴링하십시오. `failed_count` > 0은 일부 행이 거부되었음을 의미하며, 오류 endpoint를 통해 해당 목록을 확인할 수 있습니다.",
        "operationId": "get_v3_session_imports_retrieve",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "가져오기 작업 상태입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에 대한 가져오기 작업을 찾을 수 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 폐기되었거나, 해당 키에 이 애플리케이션의 가져오기 작업을 읽을 수 있는 권한이 없습니다. 누락된 키는 `403`을 반환하며, 잘못되었거나 폐기되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "summary": "누락되었거나 유효하지 않거나 취소된 API 키",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/errors/": {
      "get": {
        "summary": "인증 가져오기 행 오류 목록 조회",
        "description": "인증 가져오기 작업의 행 수준 오류를 `row_number` 순으로 나열합니다. 실패한 행만 포함된 수정된 재시도 파일을 생성하려면 이 endpoint를 사용하십시오.",
        "operationId": "get_v3_session_imports_errors",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "list_errors",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "페이지 크기입니다. 생략 시 기본값은 50입니다."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "반환할 첫 번째 레코드의 0부터 시작하는 오프셋입니다."
          }
        ],
        "responses": {
          "200": {
            "description": "페이지네이션된 행 오류 목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "오류 행 수입니다. 최대 100개까지 정확하며, 그 이상은 100개로 제한됩니다. 마지막 페이지를 감지하려면 `next`가 `null`인지 확인하십시오."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "다음 페이지의 절대 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "이전 페이지의 절대 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SessionImportError"
                      }
                    }
                  }
                },
                "examples": {
                  "Row errors": {
                    "value": {
                      "count": 1,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d",
                          "row_number": 17,
                          "external_id": "ext-000017",
                          "error": "status: invalid value 'unknown_status'",
                          "raw_row": {
                            "external_id": "ext-000017",
                            "status": "unknown_status",
                            "first_name": "Jane"
                          },
                          "created_at": "2026-05-17T08:44:02Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에 대한 가져오기 작업을 찾을 수 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 폐기되었거나, 해당 키에 이 애플리케이션의 가져오기 작업을 읽을 수 있는 권한이 없습니다. 누락된 키는 `403`을 반환하며, 잘못되었거나 폐기되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "summary": "누락되었거나 유효하지 않거나 취소된 API 키",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.imports.list_errors(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.imports.listErrors(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.Imports.ListErrorsAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsImportsListErrorsParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().imports().listErrors(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->sessions->imports->listErrors('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.imports.list_errors(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.Imports.ListErrorsAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/decision/": {
      "get": {
        "summary": "인증 세션의 전체 결정 조회",
        "description": "인증 세션의 전체 결정 보고서(취합된 세션 `status` 및 워크플로가 실행한 인증 기능별 보고서 각 1개)를 조회합니다. 이 endpoint는 사용자 인증(KYC) 및 기업 확인(KYB) 세션 모두를 위한 표준 읽기 endpoint입니다. 동일한 경로가 둘 다 처리하며, 최상위 `session_kind` 구분자를 통해 수신된 형태(`\"user\"` 또는 `\"business\"`)를 확인할 수 있습니다.\n\n**모든 기능 보고서는 복수형 배열입니다.** V3 워크플로는 동일한 기능을 여러 번 실행할 수 있는 그래프이므로, 각 블록(`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `document_ai_documents`, `phone_verifications`, `email_verifications`, `aml_screenings`, `ip_analyses`, `database_validations`, `questionnaire_responses`)은 이를 생성한 워크플로 그래프 노드를 식별하는 `node_id`를 각 항목에 포함하는 JSON 배열입니다. NFC는 단수형 `nfc` 필드가 아닌 `response.nfc_verifications[0]`과 같이 읽어야 합니다. 워크플로가 해당 기능을 최소 한 번 실행할 때까지 블록은 `null`이며, 워크플로에 포함되지 않은 기능에는 데이터가 표시되지 않습니다. 전자 서명 결과는 워크플로에 전자 서명 단계가 있는 경우에만 표시되는 `signatures`에 포함됩니다.\n\n**호출 시점.** 권장되는 패턴은 이벤트 기반 방식입니다. 세션이 결정(`Approved`, `Declined`, `In Review`)에 도달할 때 발생하는 `status.updated` webhook을 기다린 후, 이 endpoint를 한 번 호출하여 전체 보고서를 가져옵니다. 폴링 방식도 가능합니다. 이 endpoint는 세션 수명 주기의 어느 시점에서든 호출할 수 있으며 현재까지 생성된 데이터를 반환하지만, webhook 수신 후 조회하는 방식이 비용이 적게 들고 더 빠릅니다. 응답의 미디어 URL(문서 이미지, 비디오, PDF)은 유효 기간이 짧은 사전 서명된 링크입니다. 즉시 가져오거나 결정을 다시 요청하여 새로운 링크를 받아야 하며, 장기 보관용 참조로 저장해서는 안 됩니다.\n\n**상태 값.** 최상위 `status`는 세션 수명 주기 상태(`Not Started`, `In Progress`, `Awaiting User`, `In Review`, `Approved`, `Declined`, `Resubmitted`, `Expired`, `Kyc Expired`, `Abandoned`)입니다. 또한 각 기능 항목은 자체 기능 수준 `status`(`Not Finished`, `Approved`, `Declined`, `In Review`, ...)를 전달합니다. 워크플로의 결정 규칙에 따라 개별 기능이 `In Review`인 상태에서도 세션 전체가 `Approved`될 수 있습니다.\n\n**인증 및 가시성.** `x-api-key` 헤더의 애플리케이션 API 키로 인증합니다(`read:sessions` 권한이 있는 콘솔 사용자 Bearer token도 작동함). 인증된 애플리케이션이 소유한 세션만 볼 수 있습니다. 워크플로에서 응답 속성을 제한하는 경우, 기능 항목 내부의 허용되지 않은 필드는 `null`로 반환되지만 `status`, `warnings`, `node_id`는 항상 유지됩니다.\n\n**속도 제한.** GET 요청은 API 키당 분당 600개로 제한됩니다. 한도를 초과하면 `Retry-After` 및 `X-RateLimit-*` 헤더와 함께 `429`가 반환됩니다.",
        "operationId": "get_v3_session_decision",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "retrieve_decision",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "responses": {
          "200": {
            "description": "전체 결정 보고서입니다. `session_kind`는 두 가지 형태를 구분합니다. `user` 세션은 아래에 표시된 KYC 기능 배열을 포함하고, `business` 세션은 공유 배열과 함께 `registry_checks`, `document_verifications`, `key_people_checks`를 대신 포함합니다. 기능 배열은 워크플로에서 해당 기능을 실행할 때까지 `null`이며, 미디어 URL은 유효 기간이 짧은 presigned 링크입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Example": {
                    "summary": "전체 예시",
                    "value": {
                      "session_id": "11111111-2222-3333-4444-555555555555",
                      "session_kind": "user",
                      "session_number": 43762,
                      "session_url": "https://verify.didit.me/session/11111111-2222-3333-4444-555555555555",
                      "status": "In Review",
                      "environment": "live",
                      "workflow_id": "11111111-2222-3333-4444-555555555555",
                      "features": [
                        "ID_VERIFICATION",
                        "NFC",
                        "LIVENESS",
                        "FACE_MATCH",
                        "POA",
                        "PHONE",
                        "DATABASE_VALIDATION",
                        "AML",
                        "IP_ANALYSIS"
                      ],
                      "vendor_data": "11111111-1111-1111-1111-111111111111",
                      "metadata": {
                        "user_type": "premium",
                        "account_id": "ABC123"
                      },
                      "expected_details": {
                        "first_name": "Carmen",
                        "last_name": "Española Española"
                      },
                      "contact_details": {
                        "email": "carmen@example.com",
                        "email_lang": "es",
                        "send_notification_emails": false,
                        "phone": null
                      },
                      "callback": "https://verify.didit.me/",
                      "id_verifications": [
                        {
                          "node_id": "feature_ocr_1",
                          "status": "Approved",
                          "document_type": "Identity Card",
                          "document_subtype": "ID_CARD_GENERIC",
                          "document_number": "CAA000000",
                          "personal_number": "99999999R",
                          "portrait_image": "https://<media-host>/portrait.jpg",
                          "front_image": "https://<media-host>/front.jpg",
                          "front_video": "https://<media-host>/front.mp4",
                          "back_image": "https://<media-host>/back.jpg",
                          "back_video": "https://<media-host>/back.mp4",
                          "full_front_image": "https://<media-host>/full_front.jpg",
                          "full_back_image": "https://<media-host>/full_back.jpg",
                          "front_image_camera_front": "https://<media-host>/front_camera_front.jpg",
                          "back_image_camera_front": "https://<media-host>/back_camera_front.jpg",
                          "date_of_birth": "1980-01-01",
                          "age": 45,
                          "expiration_date": "2031-06-02",
                          "date_of_issue": "2021-06-02",
                          "issuing_state": "ESP",
                          "issuing_state_name": "Spain",
                          "first_name": "Carmen",
                          "last_name": "Española Española",
                          "full_name": "Carmen Española Española",
                          "gender": "F",
                          "address": "Avda de Madrid 34, Madrid, Madrid",
                          "formatted_address": "Avda de Madrid 34, Madrid, Madrid 28822, Spain",
                          "place_of_birth": "Madrid",
                          "marital_status": "Single",
                          "nationality": "ESP",
                          "extra_fields": {
                            "dl_categories": [],
                            "blood_group": null
                          },
                          "mrz": {
                            "surname": "ESPANOLA ESPANOLA",
                            "name": "CARMEN",
                            "country": "ESP",
                            "nationality": "ESP",
                            "birth_date": "800101",
                            "expiry_date": "310602",
                            "sex": "F",
                            "document_type": "ID",
                            "document_number": "CAA000000",
                            "optional_data": "99999999R",
                            "optional_data_2": "",
                            "birth_date_hash": "4",
                            "expiry_date_hash": "8",
                            "document_number_hash": "4",
                            "final_hash": "1",
                            "personal_number": "99999999R",
                            "warnings": [],
                            "errors": [],
                            "mrz_type": "TD1",
                            "mrz_string": "IDESPCAA000000499999999R<<<<<<\n8001014F3106028ESP<<<<<<<<<<<1\nESPANOLA<ESPANOLA<<CARMEN<<<<<",
                            "mrz_key": "CAA000000480010143106028"
                          },
                          "parsed_address": {
                            "city": "Madrid",
                            "label": "Spain ID Card Address",
                            "region": "Madrid",
                            "country": "ES",
                            "category": "Residential",
                            "street_1": "Avda de Madrid 34",
                            "street_2": null,
                            "is_verified": true,
                            "postal_code": "28822",
                            "raw_results": {
                              "types": [
                                "street_address"
                              ],
                              "geometry": {
                                "location": {
                                  "lat": 37.4222804,
                                  "lng": -122.0843428
                                },
                                "viewport": {
                                  "northeast": {
                                    "lat": 37.4237349802915,
                                    "lng": -122.083183169709
                                  },
                                  "southwest": {
                                    "lat": 37.4210370197085,
                                    "lng": -122.085881130292
                                  }
                                },
                                "location_type": "ROOFTOP"
                              },
                              "place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4",
                              "formatted_address": "Avda de Madrid 34, 28822 Madrid, Spain",
                              "navigation_points": [
                                {
                                  "location": {
                                    "latitude": 37.4222804,
                                    "longitude": -122.0843428
                                  }
                                }
                              ],
                              "address_components": [
                                {
                                  "types": [
                                    "street_number"
                                  ],
                                  "long_name": "34",
                                  "short_name": "34"
                                },
                                {
                                  "types": [
                                    "route"
                                  ],
                                  "long_name": "Avda de Madrid",
                                  "short_name": "Avda de Madrid"
                                },
                                {
                                  "types": [
                                    "locality",
                                    "political"
                                  ],
                                  "long_name": "Madrid",
                                  "short_name": "Madrid"
                                },
                                {
                                  "types": [
                                    "country",
                                    "political"
                                  ],
                                  "long_name": "Spain",
                                  "short_name": "ES"
                                },
                                {
                                  "types": [
                                    "postal_code"
                                  ],
                                  "long_name": "28822",
                                  "short_name": "28822"
                                }
                              ]
                            },
                            "address_type": "Avda",
                            "document_location": {
                              "latitude": 37.4222804,
                              "longitude": -122.0843428
                            },
                            "formatted_address": "Avda de Madrid 34, 28822 Madrid, Spain"
                          },
                          "front_image_camera_front_face_match_score": 95.5,
                          "back_image_camera_front_face_match_score": 93.2,
                          "document_selfie_face_matches": [
                            {
                              "session_id": "3f0c9a52-7b1e-4d68-a2c4-5e9d8b7f1a20",
                              "session_number": 1180,
                              "similarity_percentage": 97.4,
                              "vendor_data": "user_ref_001",
                              "vendor_user_id": null,
                              "biometric_template_id": null,
                              "verification_date": "2026-09-02T09:15:00Z",
                              "user_details": {
                                "full_name": "Jane Doe"
                              },
                              "match_image_url": "https://<media-host>/match_face.jpg",
                              "status": "Approved",
                              "is_blocklisted": false,
                              "is_allowlisted": false,
                              "api_service": null,
                              "source": "session"
                            }
                          ],
                          "front_image_quality_score": {
                            "focus_score": 85.3,
                            "brightness_score": 92.1,
                            "brightness_issue": "ok",
                            "is_document_fully_visible": true,
                            "resolution_score": 72.4,
                            "overall_score": 88.7
                          },
                          "back_image_quality_score": {
                            "focus_score": 79.1,
                            "brightness_score": 90.5,
                            "brightness_issue": "ok",
                            "is_document_fully_visible": true,
                            "resolution_score": 72.4,
                            "overall_score": 85.2
                          },
                          "extra_files": [
                            "https://<media-host>/extra_id_verification.jpg"
                          ],
                          "matches": [
                            {
                              "session_id": "7d4f1f60-9c2e-4b8a-8f3d-2a1b5c6d7e8f",
                              "session_number": 1234,
                              "vendor_data": "user_ref_001",
                              "verification_date": "2024-06-15T10:30:00Z",
                              "user_details": {
                                "name": "John Smith",
                                "document_type": "ID",
                                "document_number": "CLM148418"
                              },
                              "status": "Approved",
                              "is_blocklisted": false,
                              "api_service": null,
                              "front_image_url": "https://<media-host>/document_front.jpg"
                            },
                            {
                              "session_id": "b2c8e4d1-6a3f-4e7b-95c0-1d8f2a6b4c9e",
                              "session_number": 1235,
                              "vendor_data": null,
                              "verification_date": "2024-05-20T14:45:00Z",
                              "user_details": {
                                "name": "John Smith",
                                "document_type": "ID",
                                "document_number": "CLM148418"
                              },
                              "status": "Declined",
                              "is_blocklisted": true,
                              "api_service": "ID_VERIFICATION",
                              "front_image_url": "https://<media-host>/document_front_2.jpg"
                            }
                          ],
                          "warnings": [
                            {
                              "feature": "ID_VERIFICATION",
                              "risk": "QR_NOT_DETECTED",
                              "additional_data": null,
                              "log_type": "information",
                              "short_description": "QR not detected",
                              "long_description": "The system couldn't find or read the QR code on the document, which is necessary for document verification. This could be due to poor image quality or an unsupported document type.",
                              "node_id": "feature_ocr_1"
                            }
                          ],
                          "verification_method": "document",
                          "assurance": "documentary",
                          "wallet_provider": null,
                          "fallback_from": null,
                          "id_lookup": null,
                          "wallet_verification": null,
                          "document_liveness": {
                            "portrait_replace": {
                              "score": 96.46,
                              "front": 96.46,
                              "back": 98.2,
                              "decline_threshold": 35,
                              "review_threshold": 70,
                              "bucket": "approve"
                            },
                            "printed_copy": {
                              "score": 91.2,
                              "front": 91.2,
                              "back": 93.7,
                              "decline_threshold": 35,
                              "review_threshold": 77,
                              "bucket": "approve"
                            },
                            "screen_replay": {
                              "score": 99.9,
                              "front": 99.9,
                              "back": 99.5,
                              "decline_threshold": 30,
                              "review_threshold": 70,
                              "bucket": "approve"
                            }
                          }
                        },
                        {
                          "node_id": "feature_ocr_2",
                          "status": "Approved",
                          "issuing_state": "ZAF",
                          "issuing_state_name": "South Africa",
                          "first_name": "Thabo",
                          "last_name": "Mokoena",
                          "full_name": "Thabo Mokoena",
                          "date_of_birth": "1991-06-15",
                          "personal_number": "9106155043088",
                          "verification_method": "id_lookup",
                          "assurance": "data_match",
                          "wallet_provider": null,
                          "fallback_from": null,
                          "id_lookup": {
                            "source": "Department of Home Affairs",
                            "checked_at": "2026-09-04T09:12:44Z",
                            "attempts": 1,
                            "max_attempts": 2,
                            "outcome": "match",
                            "comparison": [
                              {
                                "field": "identification_number",
                                "label": "ID number",
                                "provided": "9106155043088",
                                "record": "9106155043088",
                                "result": "match"
                              },
                              {
                                "field": "full_name",
                                "label": "Full name",
                                "provided": "Thabo Mokoena",
                                "record": "Thabo Mokoena",
                                "result": "match"
                              },
                              {
                                "field": "date_of_birth",
                                "label": "Date of birth",
                                "provided": "1991-06-15",
                                "record": "1991-06-15",
                                "result": "match"
                              }
                            ],
                            "registry_portrait": "https://<media-host>/registry_portrait.jpg",
                            "face_match_score": 96.4,
                            "source_errors": []
                          },
                          "wallet_verification": null,
                          "warnings": []
                        },
                        {
                          "node_id": "feature_ocr_3",
                          "status": "Approved",
                          "issuing_state": "DNK",
                          "issuing_state_name": "Denmark",
                          "first_name": "Freja",
                          "last_name": "Nielsen",
                          "full_name": "Freja Nielsen",
                          "date_of_birth": "1988-03-02",
                          "verification_method": "wallet",
                          "assurance": "cryptographic",
                          "wallet_provider": "mitid",
                          "fallback_from": null,
                          "id_lookup": null,
                          "wallet_verification": {
                            "provider": "mitid",
                            "provider_name": "MitID",
                            "issuing_authority": "Danish Agency for Digital Government",
                            "issuing_country": "DNK",
                            "credential_type": "person_identification",
                            "level_of_assurance": "substantial",
                            "verified_at": "2026-09-04T09:12:44Z",
                            "signature_valid": true,
                            "attributes": {
                              "full_name": "Freja Nielsen",
                              "date_of_birth": "1988-03-02",
                              "cpr_alias": "b0f1c2d3-e4f5-4678-9abc-def012345678"
                            },
                            "portrait": null,
                            "face_match_score": null
                          },
                          "warnings": []
                        }
                      ],
                      "nfc_verifications": [
                        {
                          "node_id": "feature_nfc_1",
                          "status": "In Review",
                          "is_nfc_skipped": false,
                          "skip_reason": null,
                          "chip_protocol": "icao",
                          "jpki": null,
                          "portrait_image": "https://<media-host>/portrait.jpg",
                          "signature_image": "https://<media-host>/signature.jpg",
                          "chip_data": {
                            "document_type": "ID",
                            "issuing_country": "ESP",
                            "document_number": "123456789",
                            "expiration_date": "2030-01-01",
                            "first_name": "John",
                            "last_name": "Smith",
                            "birth_date": "1990-05-15",
                            "gender": "M",
                            "nationality": "ESP",
                            "address": "CALLE MAYOR 123 4B, MADRID, MADRID",
                            "place_of_birth": "MADRID, MADRID"
                          },
                          "authenticity": {
                            "sod_integrity": true,
                            "dg_integrity": true
                          },
                          "certificate_summary": {
                            "issuer": "Common Name: CSCA SPAIN, Serial Number: 3, Organization: DIRECCION GENERAL DE LA POLICIA, Country: ES",
                            "subject": "Common Name: DS n-eID SPAIN 2, Organizational Unit: PASSPORT, Organization: DIRECCION GENERAL DE LA POLICIA, Country: ES",
                            "serial_number": "118120836164494130086420187336801405660",
                            "not_valid_after": "2031-02-18 10:21:11",
                            "not_valid_before": "2020-11-18 10:21:11"
                          },
                          "warnings": [
                            {
                              "feature": "NFC",
                              "risk": "DATA_INCONSISTENT",
                              "additional_data": null,
                              "log_type": "warning",
                              "short_description": "OCR and NFC mrz code extracted are not the same",
                              "long_description": "The Optical Character Recognition (OCR) data and the NFC chip data don't match, indicating potential document tampering or data inconsistency.",
                              "node_id": "feature_nfc_1"
                            }
                          ]
                        }
                      ],
                      "liveness_checks": [
                        {
                          "node_id": "feature_liveness_1",
                          "status": "Approved",
                          "method": "ACTIVE_3D",
                          "score": 89.92,
                          "reference_image": "https://<media-host>/reference.jpg",
                          "video_url": "https://<media-host>/video.mp4",
                          "age_estimation": 24.3,
                          "matches": [
                            {
                              "session_id": "7d4f1f60-9c2e-4b8a-8f3d-2a1b5c6d7e8f",
                              "session_number": 1234,
                              "vendor_data": "user_ref_001",
                              "verification_date": "2024-06-15T10:30:00Z",
                              "user_details": {
                                "full_name": "John Smith",
                                "document_type": "ID",
                                "document_number": "CLM148418"
                              },
                              "status": "Approved",
                              "is_blocklisted": false,
                              "is_allowlisted": false,
                              "api_service": null,
                              "source": "session",
                              "match_image_url": "https://<media-host>/face_match.jpg",
                              "similarity_percentage": 98.5
                            },
                            {
                              "session_id": "3e9a7c21-5b48-4f0e-9c6a-8d2f4b1e0a35",
                              "session_number": 1100,
                              "vendor_data": "customer_xyz",
                              "verification_date": "2024-04-10T09:15:00Z",
                              "user_details": {
                                "full_name": "John Smith",
                                "document_type": "P",
                                "document_number": "DZ8375806"
                              },
                              "status": "Approved",
                              "is_blocklisted": false,
                              "is_allowlisted": false,
                              "api_service": "PASSIVE_LIVENESS",
                              "source": "session",
                              "match_image_url": "https://<media-host>/face_match_2.jpg",
                              "similarity_percentage": 95.2
                            }
                          ],
                          "warnings": [
                            {
                              "feature": "LIVENESS",
                              "risk": "LOW_LIVENESS_SCORE",
                              "additional_data": null,
                              "log_type": "information",
                              "short_description": "Low liveness score",
                              "long_description": "The liveness check resulted in a low score, indicating potential use of non-live facial representations or poor-quality biometric data.",
                              "node_id": "feature_liveness_1"
                            }
                          ],
                          "face_quality": null,
                          "face_luminance": null
                        }
                      ],
                      "face_matches": [
                        {
                          "node_id": "feature_face_match_1",
                          "status": "In Review",
                          "score": 65.43,
                          "source_image_session_id": null,
                          "source_image": "https://<media-host>/source-image.jpg",
                          "target_image": "https://<media-host>/target-image.jpg",
                          "warnings": [
                            {
                              "feature": "FACEMATCH",
                              "risk": "LOW_FACE_MATCH_SIMILARITY",
                              "additional_data": null,
                              "log_type": "warning",
                              "short_description": "Low face match similarity",
                              "long_description": "The facial features of the provided image don't closely match the reference image, suggesting a potential identity mismatch.",
                              "node_id": "feature_face_match_1"
                            }
                          ]
                        }
                      ],
                      "phone_verifications": [
                        {
                          "node_id": "feature_phone_1",
                          "status": "Approved",
                          "phone_number_prefix": "+34",
                          "phone_number": "600600600",
                          "full_number": "+34600600600",
                          "country_code": "ES",
                          "country_name": "Spain",
                          "carrier": {
                            "name": "Orange",
                            "type": "mobile"
                          },
                          "is_disposable": false,
                          "is_virtual": false,
                          "verification_method": "sms",
                          "verification_attempts": 1,
                          "verified_at": "2024-07-28T06:47:35.654321Z",
                          "lifecycle": [
                            {
                              "type": "PHONE_VERIFICATION_MESSAGE_SENT",
                              "timestamp": "2025-08-24T09:12:39.580554+00:00",
                              "details": {
                                "status": "Success",
                                "reason": null,
                                "channel": "sms",
                                "actual_channel": "sms"
                              },
                              "fee": 0.1
                            },
                            {
                              "type": "VALID_CODE_ENTERED",
                              "timestamp": "2025-08-24T09:12:39.662157+00:00",
                              "details": {
                                "code_tried": "123456",
                                "status": "Approved"
                              },
                              "fee": 0
                            },
                            {
                              "type": "PHONE_VERIFICATION_APPROVED",
                              "timestamp": "2025-08-24T09:12:39.684292+00:00",
                              "details": null,
                              "fee": 0
                            }
                          ],
                          "warnings": [],
                          "matches": [
                            {
                              "session_id": null,
                              "session_number": null,
                              "vendor_data": null,
                              "verification_date": null,
                              "phone_number": "+34600000000",
                              "status": null,
                              "is_blocklisted": true,
                              "api_service": null,
                              "source": "list_entry"
                            }
                          ]
                        }
                      ],
                      "email_verifications": [
                        {
                          "node_id": "feature_email_1",
                          "status": "Approved",
                          "email": "test@example.com",
                          "is_breached": true,
                          "breaches": [
                            {
                              "name": "TAPAirPortugal",
                              "domain": "flytap.com",
                              "logo_path": "https://logos.example.com/TAPAirPortugal.png",
                              "breach_date": "2022-08-25",
                              "description": "In August 2022, the Portuguese airline <a href=\"https://www.bleepingcomputer.com/news/security/ragnar-locker-ransomware-claims-attack-on-portugals-flag-airline/\" target=\"_blank\" rel=\"noopener\">TAP Air Portugal was the target of a ransomware attack perpetrated by the Ragnar Locker gang</a> who later leaked the compromised data via a public dark web site. Over 5M unique email addresses were exposed alongside other personal data including names, genders, DoBs, phone numbers and physical addresses.",
                              "is_verified": true,
                              "data_classes": [
                                "dates_of_birth",
                                "email_addresses",
                                "genders",
                                "names",
                                "nationalities",
                                "phone_numbers",
                                "physical_addresses",
                                "salutations",
                                "spoken_languages"
                              ],
                              "breach_emails_count": 6083479
                            }
                          ],
                          "is_disposable": false,
                          "is_undeliverable": false,
                          "verification_attempts": 1,
                          "verified_at": "2025-09-15T17:36:19.963451Z",
                          "warnings": [
                            {
                              "feature": "EMAIL",
                              "risk": "BREACHED_EMAIL_DETECTED",
                              "additional_data": null,
                              "log_type": "information",
                              "short_description": "Breached email detected",
                              "long_description": "This email address was found in one or more known data breaches.",
                              "node_id": "feature_email_1"
                            }
                          ],
                          "lifecycle": [
                            {
                              "type": "EMAIL_VERIFICATION_MESSAGE_SENT",
                              "timestamp": "2025-09-15T17:36:19.792684+00:00",
                              "details": {
                                "status": "Success",
                                "reason": null
                              },
                              "fee": 0.02
                            },
                            {
                              "type": "VALID_CODE_ENTERED",
                              "timestamp": "2025-09-15T17:36:19.963427+00:00",
                              "details": {
                                "code_tried": "123456",
                                "status": "Approved"
                              },
                              "fee": 0
                            },
                            {
                              "type": "EMAIL_VERIFICATION_DECLINED",
                              "timestamp": "2025-09-15T17:36:20.081471+00:00",
                              "details": {
                                "reason": "BREACHED_EMAIL_DETECTED"
                              },
                              "fee": 0
                            }
                          ],
                          "matches": [
                            {
                              "session_id": null,
                              "session_number": null,
                              "vendor_data": null,
                              "verification_date": null,
                              "email": "test@example.com",
                              "status": null,
                              "is_blocklisted": true,
                              "api_service": null,
                              "source": "list_entry"
                            }
                          ]
                        }
                      ],
                      "poa_verifications": [
                        {
                          "node_id": "feature_poa_1",
                          "status": "Declined",
                          "document_file": "https://<media-host>/poa_document.pdf",
                          "issuing_state": "AR",
                          "document_type": "UTILITY_BILL",
                          "document_subtype": null,
                          "document_language": "es",
                          "document_metadata": {
                            "file_size": 1000,
                            "content_type": "application/pdf",
                            "creation_date": "2021-01-01",
                            "modified_date": "2021-01-01",
                            "overlay_manipulation": null,
                            "creator": null,
                            "producer": "PDF Generator",
                            "software": null,
                            "encryption": null,
                            "is_signed": false,
                            "is_tampered": false,
                            "signature_info": null,
                            "exif_original_date": null,
                            "exif_digitized_date": null,
                            "processed_by_known_editor": false,
                            "has_different_creation_mod_date": true
                          },
                          "issuer": "Aguas del Norte",
                          "issue_date": "2021-02-01",
                          "expiration_date": null,
                          "poa_address": "AVDA. MONSEÑOR TAVELLA N° 3396, SALTA",
                          "poa_formatted_address": "Av. Monseñor Tavella 3396, A4400 Salta, Argentina",
                          "poa_parsed_address": {
                            "address_type": "Avenida",
                            "street_1": "Avenida Monseñor Tavella 3396",
                            "street_2": null,
                            "city": "Salta",
                            "region": "Salta",
                            "country": "AR",
                            "postal_code": "A4400",
                            "document_location": {
                              "latitude": -24.8208664,
                              "longitude": -65.4131
                            }
                          },
                          "name_on_document": "Fernando De Lima",
                          "name_match_score_expected_details": null,
                          "name_match_score_id_verification": 38.5,
                          "expected_details_address": null,
                          "expected_details_formatted_address": null,
                          "expected_details_parsed_address": {},
                          "extra_fields": {
                            "bank_account_number": "1234567890",
                            "bank_iban": null,
                            "bank_sort_code": null,
                            "bank_routing_number": null,
                            "bank_swift_bic": null,
                            "bank_branch_name": null,
                            "bank_branch_address": null,
                            "document_phone_number": "+5491112345678",
                            "additional_names": []
                          },
                          "extra_files": [
                            "https://<media-host>/extra_poa.pdf"
                          ],
                          "detected_codes": [
                            {
                              "type": "QR_CODE",
                              "page_number": 1,
                              "position": [
                                [
                                  820,
                                  1120
                                ],
                                [
                                  1002,
                                  1120
                                ],
                                [
                                  1002,
                                  1302
                                ],
                                [
                                  820,
                                  1302
                                ]
                              ],
                              "x": 820,
                              "y": 1120,
                              "width": 182,
                              "height": 182,
                              "page_width": 1190,
                              "page_height": 1684,
                              "raw_payload": "aHR0cHM6Ly9hZ3Vhc2RlbG5vcnRlLmNvbS9mYWN0dXJhLzk5ODgxMQ==",
                              "parsed_payload": "https://aguasdelnorte.com/factura/998811"
                            },
                            {
                              "type": "CODE_128",
                              "page_number": 1,
                              "position": [
                                [
                                  112,
                                  1480
                                ],
                                [
                                  560,
                                  1480
                                ],
                                [
                                  560,
                                  1540
                                ],
                                [
                                  112,
                                  1540
                                ]
                              ],
                              "x": 112,
                              "y": 1480,
                              "width": 448,
                              "height": 60,
                              "page_width": 1190,
                              "page_height": 1684,
                              "raw_payload": "MDA5OTg4MTEwMDA0Mg==",
                              "parsed_payload": "0099881100042"
                            }
                          ],
                          "warnings": []
                        }
                      ],
                      "document_ai_documents": [
                        {
                          "status": "Approved",
                          "node_id": "feature_document_ai_1",
                          "items": [
                            {
                              "uuid": "c1a2b3c4-d5e6-7f80-9a1b-2c3d4e5f6071",
                              "node_id": "feature_document_ai_1",
                              "document_key": "proof_of_funds",
                              "original_filename": "bank_statement.pdf",
                              "file_size": 184320,
                              "file_url": "https://<media-host>/document_ai/proof_of_funds.pdf",
                              "status": "Approved",
                              "extracted_data": {
                                "account_holder": "John Doe",
                                "balance": 15230.55,
                                "currency": "EUR",
                                "statement_date": "2026-05-31"
                              },
                              "detected_codes": [
                                {
                                  "type": "QR_CODE",
                                  "page_number": 2,
                                  "position": [
                                    [
                                      124,
                                      86
                                    ],
                                    [
                                      306,
                                      86
                                    ],
                                    [
                                      306,
                                      268
                                    ],
                                    [
                                      124,
                                      268
                                    ]
                                  ],
                                  "x": 124,
                                  "y": 86,
                                  "width": 182,
                                  "height": 182,
                                  "page_width": 1190,
                                  "page_height": 1684,
                                  "raw_payload": "SU5WLTIwMjYtMDA0Mg==",
                                  "parsed_payload": "INV-2026-0042"
                                }
                              ],
                              "fields": [
                                {
                                  "key": "account_holder",
                                  "name": "Account holder",
                                  "instruction": "Extract the full name of the account holder.",
                                  "type": "text",
                                  "required": true
                                },
                                {
                                  "key": "balance",
                                  "name": "Closing balance",
                                  "instruction": "Extract the closing balance amount.",
                                  "type": "number",
                                  "required": true
                                }
                              ],
                              "document_metadata": {
                                "is_tampered": false
                              },
                              "cross_check_result": null,
                              "created_at": "2026-06-01T12:34:56Z"
                            }
                          ],
                          "warnings": []
                        }
                      ],
                      "questionnaire_responses": [
                        {
                          "node_id": "feature_questionnaire_1",
                          "questionnaire_id": "9f7485e0-b00b-4d56-9d3e-7859b68d1213",
                          "title": "Source of Funds",
                          "description": "Reply to this questionnaire to help us understand the source of funds.",
                          "languages": [
                            "en"
                          ],
                          "default_language": "en",
                          "is_active": true,
                          "is_simple_questionnaire": true,
                          "questionnaire_group_id": "2b6a9d40-13a8-4b1e-9a6c-3f1d2e4b5a60",
                          "version": 1,
                          "published_at": "2025-11-02T09:14:55.000000Z",
                          "sections": [
                            {
                              "title": null,
                              "description": null,
                              "items": [
                                {
                                  "uuid": "618636d9-7d5c-41ce-b8d0-1ab2a4be20db",
                                  "value": "question_1",
                                  "element_type": "DROPDOWN",
                                  "is_required": true,
                                  "title": "What is your primary source of funds?",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": [
                                    {
                                      "label": "Salary",
                                      "value": "salary"
                                    },
                                    {
                                      "label": "Business Income",
                                      "value": "business_income"
                                    },
                                    {
                                      "label": "Savings",
                                      "value": "savings"
                                    },
                                    {
                                      "label": "Investments",
                                      "value": "investments"
                                    },
                                    {
                                      "label": "Sale of Asset",
                                      "value": "sale_of_asset"
                                    },
                                    {
                                      "label": "Inheritance/Gift",
                                      "value": "inheritance_gift"
                                    },
                                    {
                                      "label": "Pension",
                                      "value": "pension"
                                    },
                                    {
                                      "label": "Crypto Proceeds",
                                      "value": "crypto_proceeds"
                                    },
                                    {
                                      "label": "Other",
                                      "value": "other",
                                      "requires_text_input": true
                                    }
                                  ],
                                  "max_files": 1,
                                  "answer": {
                                    "value": "salary"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "2d16b527-72be-42e0-8e96-b164b818386c",
                                  "value": "question_2",
                                  "element_type": "LONG_TEXT",
                                  "is_required": true,
                                  "title": "Provide details of the primary source.",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": null,
                                  "max_files": 1,
                                  "answer": {
                                    "value": "Test answer"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "a9239b7c-fbfb-4ea7-b7e4-c835cd4016e0",
                                  "value": "question_3",
                                  "element_type": "DROPDOWN",
                                  "is_required": true,
                                  "title": "What is your annual income range (pre-tax)?",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": [
                                    {
                                      "label": "Less than $25,000",
                                      "value": "<25k"
                                    },
                                    {
                                      "label": "$25,000 - $50,000",
                                      "value": "25k-50k"
                                    },
                                    {
                                      "label": "$50,001 - $100,000",
                                      "value": "50k-100k"
                                    },
                                    {
                                      "label": "$100,001 - $250,000",
                                      "value": "100k-250k"
                                    },
                                    {
                                      "label": "More than $250,000",
                                      "value": ">250k"
                                    }
                                  ],
                                  "max_files": 1,
                                  "answer": {
                                    "value": "<25k"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "93dede62-6d0c-4a7f-934d-42175eb94011",
                                  "value": "question_4",
                                  "element_type": "DROPDOWN",
                                  "is_required": true,
                                  "title": "What is your approximate net worth (range)?",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": [
                                    {
                                      "label": "Less than $50,000",
                                      "value": "<50k"
                                    },
                                    {
                                      "label": "$50,000 - $250,000",
                                      "value": "50k-250k"
                                    },
                                    {
                                      "label": "$250,001 - $1,000,000",
                                      "value": "250k-1m"
                                    },
                                    {
                                      "label": "$1,000,001 - $5,000,000",
                                      "value": "1m-5m"
                                    },
                                    {
                                      "label": "More than $5,000,000",
                                      "value": ">5m"
                                    }
                                  ],
                                  "max_files": 1,
                                  "answer": {
                                    "value": "<50k"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "2af60d6f-6961-4692-9ee7-24b3033610a6",
                                  "value": "question_5",
                                  "element_type": "LONG_TEXT",
                                  "is_required": true,
                                  "title": "For your initial deposit/funding, indicate the exact source and amount.",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": null,
                                  "max_files": 1,
                                  "answer": {
                                    "value": "Test answer"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "0ad9d1aa-736f-46cf-947b-9e1241b53e40",
                                  "value": "question_6",
                                  "element_type": "LONG_TEXT",
                                  "is_required": true,
                                  "title": "Breakdown of sources by percentage.",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": null,
                                  "max_files": 1,
                                  "answer": {
                                    "value": "Test answer"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "1bf8a2a3-14ee-48a8-bb3d-175481aae4aa",
                                  "value": "question_7",
                                  "element_type": "SINGLE_CHOICE",
                                  "is_required": true,
                                  "title": "Will any funds originate from third parties? If yes, please provide details.",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": [
                                    {
                                      "label": "Yes",
                                      "value": "yes",
                                      "requires_text_input": true
                                    },
                                    {
                                      "label": "No",
                                      "value": "no"
                                    }
                                  ],
                                  "max_files": 1,
                                  "answer": {
                                    "text": "Additional details",
                                    "value": "yes"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "e18d4dd3-b7bf-4883-ba18-d6046adbe313",
                                  "value": "question_8",
                                  "element_type": "SINGLE_CHOICE",
                                  "is_required": true,
                                  "title": "Do you hold or plan to use virtual assets (e.g., crypto) to fund this account? If yes, please provide details.",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": [
                                    {
                                      "label": "Yes",
                                      "value": "yes",
                                      "requires_text_input": true
                                    },
                                    {
                                      "label": "No",
                                      "value": "no"
                                    }
                                  ],
                                  "max_files": 1,
                                  "answer": {
                                    "text": "Additional details",
                                    "value": "yes"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "a90a073d-e098-404c-bbce-5130d8b12a13",
                                  "value": "question_9",
                                  "element_type": "FILE_UPLOAD",
                                  "is_required": true,
                                  "title": "Upload a proof of funds document",
                                  "description": "You can upload your three (3) most recent bank statements, three (3) most recent payslips, your most recent tax return, proof of company ownership, trading exchange statement, sale of property, or proof of inheritance.",
                                  "placeholder": null,
                                  "choices": null,
                                  "max_files": 3,
                                  "answer": {
                                    "files": [
                                      "/media/ocr/",
                                      "/media/ocr/"
                                    ]
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "9503b486-7cb8-4c3b-a97d-4b64926a5a47",
                                  "value": "question_10",
                                  "element_type": "LONG_TEXT",
                                  "is_required": false,
                                  "title": "Would you like to add any details to help us expedite our review of the documents you submitted?",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": null,
                                  "max_files": 1,
                                  "answer": {
                                    "value": "Test answer"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                }
                              ]
                            }
                          ],
                          "status": "Approved"
                        }
                      ],
                      "aml_screenings": [
                        {
                          "node_id": "feature_aml_1",
                          "status": "In Review",
                          "total_hits": 1,
                          "entity_type": "person",
                          "hits": [
                            {
                              "id": "hit_7c1e9a40b2d35f86e0a4c912",
                              "url": "https://news.example.org/articles/sample",
                              "match": false,
                              "score": 0.73,
                              "target": null,
                              "caption": "Javier Ejemplo Modelo",
                              "datasets": [
                                "PEP"
                              ],
                              "features": null,
                              "rca_name": "",
                              "last_seen": "2025-06-13T00:00:00",
                              "risk_view": {
                                "crimes": {
                                  "score": 0,
                                  "weightage": 20,
                                  "risk_level": "Low",
                                  "risk_scores": {}
                                },
                                "countries": {
                                  "score": 0,
                                  "weightage": 30,
                                  "risk_level": "Low",
                                  "risk_scores": {}
                                },
                                "categories": {
                                  "score": 100,
                                  "weightage": 50,
                                  "risk_level": "High",
                                  "risk_scores": {
                                    "PEP": 100
                                  }
                                },
                                "custom_list": {}
                              },
                              "first_seen": "2025-01-18T00:00:00",
                              "properties": {
                                "name": [
                                  "Javier Ejemplo Modelo"
                                ],
                                "alias": [
                                  "Javier Ejemplo Modelo",
                                  "David Azagra"
                                ],
                                "notes": [
                                  "Spanish orchestra conductor"
                                ],
                                "title": null,
                                "gender": [
                                  "male"
                                ],
                                "height": null,
                                "topics": null,
                                "weight": null,
                                "address": null,
                                "country": null,
                                "website": null,
                                "eyeColor": null,
                                "keywords": null,
                                "lastName": [
                                  "Ejemplo",
                                  "Modelo"
                                ],
                                "position": null,
                                "religion": null,
                                "birthDate": [
                                  "1974"
                                ],
                                "education": [
                                  "Tokyo Arts and Space (2012-2012)",
                                  "Saint Petersburg Conservatory (-2010)",
                                  "Comillas Pontifical University"
                                ],
                                "ethnicity": null,
                                "firstName": [
                                  "David"
                                ],
                                "hairColor": null,
                                "weakAlias": null,
                                "birthPlace": [
                                  "Madrid"
                                ],
                                "modifiedAt": null,
                                "wikidataId": null,
                                "citizenship": null,
                                "nationality": null
                              },
                              "match_score": 98,
                              "risk_score": 73,
                              "review_status": "Unreviewed",
                              "score_breakdown": {
                                "name_score": 95,
                                "name_weight": 60,
                                "name_weight_normalized": 70.59,
                                "name_contribution": 67.06,
                                "dob_score": 100,
                                "dob_weight": 25,
                                "dob_weight_normalized": 29.41,
                                "dob_contribution": 29.41,
                                "country_score": 0,
                                "country_weight": 15,
                                "country_weight_normalized": 0,
                                "country_contribution": 0,
                                "document_number_match_type": "NEUTRAL",
                                "document_number_effect": "No document number provided for screening",
                                "total_score": 98
                              },
                              "pep_matches": [
                                {
                                  "aliases": [
                                    "Javier Ejemplo Modelo",
                                    "David Azagra"
                                  ],
                                  "education": [
                                    "Tokyo Arts and Space (2012-2012)",
                                    "Saint Petersburg Conservatory (-2010)",
                                    "Comillas Pontifical University"
                                  ],
                                  "list_name": "Wikidata",
                                  "publisher": "Wikidata",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "description": "Wikidata is the structured data project of the Wikipedia community, providing fact-based information edited by humans and machines",
                                  "matched_name": "Javier Ejemplo Modelo",
                                  "pep_position": "",
                                  "date_of_birth": "1974",
                                  "other_sources": [],
                                  "place_of_birth": "Madrid"
                                }
                              ],
                              "linked_entities": [
                                {
                                  "name": [
                                    "Antonio Ejemplo"
                                  ],
                                  "active": [],
                                  "status": [],
                                  "details": [],
                                  "relation": []
                                }
                              ],
                              "warning_matches": [],
                              "sanction_matches": [],
                              "adverse_media_details": {
                                "sentiment": "Moderately Negative",
                                "entity_type": "person",
                                "sentiment_score": -2,
                                "adverse_keywords": {
                                  "fraud": 3,
                                  "juicio": 1,
                                  "delitos": 2,
                                  "imputado": 1,
                                  "impunidad": 1,
                                  "corruption": 2,
                                  "favoritism": 2,
                                  "privilegio": 1,
                                  "corrupción": 1,
                                  "persecution": 2,
                                  "desconfianza": 1,
                                  "desprestigio": 1,
                                  "fraude de ley": 2,
                                  "manipulación": 1,
                                  "investigación": 3,
                                  "prevaricación": 8,
                                  "trato de favor": 1,
                                  "irregularidades": 2,
                                  "crisis de confianza": 1,
                                  "tráfico de influencias": 8
                                }
                              },
                              "adverse_media_matches": [
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo is implicated in legal violations related to favoritism and influence trafficking, leading to a negative portrayal in the article.",
                                  "headline": "La Diputación de Villaejemplo consolida la plaza a medida para el ex asesor de Moncloa amigo del \"hermanito\" de Ejemplo",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "fraud",
                                    "prevaricación",
                                    "tráfico de influencias",
                                    "irregularidades",
                                    "imputado"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-10T20:46:38"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo is implicated in legal issues regarding favoritism and corruption, leading to a negative portrayal in the article.",
                                  "headline": "La Diputación de Villaejemplo consolida la plaza a medida para el ex asesor de Moncloa amigo del \"hermanito\" de Ejemplo",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "fraud",
                                    "prevaricación",
                                    "tráfico de influencias",
                                    "irregularidades",
                                    "trato de favor"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-10T20:46:38"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo Modelo is mentioned in connection with Carlos Ficticio's corruption case, indicating his involvement in alleged influence peddling.",
                                  "headline": "España, paraíso del aforado",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "prevaricación",
                                    "tráfico de influencias",
                                    "corrupción",
                                    "impunidad",
                                    "privilegio",
                                    "desconfianza",
                                    "manipulación",
                                    "fraude de ley"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-10T05:05:34"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo Modelo is implicated in the same investigation as Ficticio, which raises questions about his conduct and political ethics.",
                                  "headline": "Aforamientos: esa figura incómoda",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "prevaricación",
                                    "tráfico de influencias",
                                    "investigación",
                                    "juicio",
                                    "fraude de ley",
                                    "desprestigio",
                                    "crisis de confianza",
                                    "delitos"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-08T06:01:00"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo is implicated in a legal investigation regarding irregularities in his hiring, which raises serious concerns about his conduct.",
                                  "headline": "La jueza del 'caso Javier Ejemplo' denuncia un «fraude de ley» en el aforamiento de Ficticio (Partido Ejemplo)",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "fraud",
                                    "irregularities",
                                    "prevaricación",
                                    "tráfico de influencias"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-09T10:19:10"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo Modelo is mentioned in connection with legal allegations of corruption, contributing to a negative perception.",
                                  "headline": "'Caso aforamiento': la letrada mayor de la Asamblea certifica a la juez que Ficticio es diputado desde antes de prometer su cargo en el Pleno",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "prevaricación",
                                    "tráfico de influencias"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-09T08:08:30"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo Modelo is implicated in the same investigation as Ficticio, raising concerns about political corruption and influence.",
                                  "headline": "Aforamientos: esa figura incómoda",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "prevaricación",
                                    "tráfico de influencias",
                                    "investigación"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-08T06:01:00"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo Modelo is implicated in the same investigation as Ficticio, which raises concerns about political misconduct.",
                                  "headline": "Aforamientos: esa figura incómoda",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "prevaricación",
                                    "tráfico de influencias",
                                    "investigación",
                                    "delitos"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-08T06:00:59"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo is implicated in a case of favoritism and corruption, which casts a negative light on his character and actions.",
                                  "headline": "'Caso Javier Ejemplo': las asociaciones judiciales salen en defensa de la juez Luisa Inventada ante las \"presiones externas\" que sufre",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "favoritism",
                                    "corruption",
                                    "persecution"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-06T10:08:15"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo is implicated in a case of alleged favoritism and corruption, which casts a negative light on his character and actions.",
                                  "headline": "'Caso Javier Ejemplo': las asociaciones judiciales salen en defensa de la juez Luisa Inventada ante las \"presiones externas\" que sufre",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "favoritism",
                                    "corruption",
                                    "persecution"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-06T08:08:15"
                                }
                              ],
                              "additional_information": {}
                            }
                          ],
                          "score": 80,
                          "screened_data": {
                            "full_name": "Javier Ejemplo Modelo",
                            "nationality": "ES",
                            "date_of_birth": "1974-01-01",
                            "document_number": null
                          },
                          "is_ongoing_monitoring_enabled": true,
                          "next_ongoing_monitoring_bill_date": "2026-07-24",
                          "last_ongoing_screening_at": "2026-09-12T04:03:11Z",
                          "last_ongoing_screening_datasets_updated_at": "2026-09-11T06:00:00Z",
                          "warnings": [
                            {
                              "feature": "AML",
                              "risk": "POSSIBLE_MATCH_FOUND",
                              "additional_data": null,
                              "log_type": "warning",
                              "short_description": "Possible match found in AML screening",
                              "long_description": "The Anti-Money Laundering (AML) screening process identified potential matches with watchlists or high-risk databases, requiring further review.",
                              "node_id": "feature_aml_1"
                            }
                          ]
                        }
                      ],
                      "ip_analyses": [
                        {
                          "node_id": "feature_ip_1",
                          "status": "Approved",
                          "device_brand": "Apple",
                          "device_model": "iPhone",
                          "browser_family": "Mobile Safari",
                          "os_family": "iOS",
                          "platform": "mobile",
                          "device_fingerprint": "didit-fp-a1b2c3d4e5f6g7h8",
                          "ip_country": "Spain",
                          "ip_country_code": "ES",
                          "ip_state": "Barcelona",
                          "ip_city": "Barcelona",
                          "latitude": 41.4022,
                          "longitude": 2.1407,
                          "ip_address": "83.50.226.71",
                          "isp": null,
                          "organization": null,
                          "is_vpn_or_tor": false,
                          "is_data_center": false,
                          "time_zone": "Europe/Madrid",
                          "time_zone_offset": "+0100",
                          "ip": {
                            "location": {
                              "latitude": 40.2206327,
                              "longitude": 1.5770097
                            },
                            "distance_from_id_document": 23.4,
                            "distance_from_poa_document": 12.3
                          },
                          "id_document": {
                            "location": {
                              "latitude": 41.2706327,
                              "longitude": 1.9770097
                            },
                            "distance_from_ip": 23.4,
                            "distance_from_poa_document": 18.7
                          },
                          "poa_document": {
                            "location": {
                              "latitude": 41.2706327,
                              "longitude": 1.9770097
                            },
                            "distance_from_ip": 12.3,
                            "distance_from_id_document": 18.7
                          },
                          "warnings": [],
                          "matches": [
                            {
                              "session_id": "99999999-8888-7777-6666-555555555555",
                              "session_number": 41205,
                              "vendor_data": "22222222-2222-2222-2222-222222222222",
                              "verification_date": "2024-07-20T10:15:30Z",
                              "match_type": "ip_address",
                              "match_source": "ip_address",
                              "matched_value": "83.50.226.71",
                              "status": "Approved",
                              "is_blocklisted": false,
                              "api_service": null,
                              "source": "session",
                              "device_info": {
                                "device_brand": "Apple",
                                "device_model": "iPhone",
                                "browser_family": "Mobile Safari",
                                "os_family": "iOS",
                                "platform": "mobile",
                                "device_fingerprint": "didit-fp-f9e8d7c6b5a40312"
                              },
                              "location_info": {
                                "ip_address": "83.50.226.71",
                                "ip_country": "Spain",
                                "ip_country_code": "ES",
                                "ip_state": "Barcelona",
                                "ip_city": "Barcelona",
                                "is_vpn_or_tor": false,
                                "is_data_center": false
                              },
                              "confidence": 0.0,
                              "match_mode": "co_occurrence"
                            },
                            {
                              "session_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                              "session_number": 42830,
                              "vendor_data": "33333333-3333-3333-3333-333333333333",
                              "verification_date": "2024-06-30T18:22:05Z",
                              "match_type": "device_fingerprint",
                              "match_source": "recovered_high",
                              "matched_value": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
                              "status": "Declined",
                              "is_blocklisted": false,
                              "api_service": null,
                              "source": "session",
                              "device_info": {
                                "device_brand": "Samsung",
                                "device_model": "SM-G991B",
                                "browser_family": "Chrome Mobile",
                                "os_family": "Android",
                                "platform": "mobile",
                                "device_fingerprint": null
                              },
                              "location_info": {
                                "ip_address": "83.50.231.18",
                                "ip_country": "Spain",
                                "ip_country_code": "ES",
                                "ip_state": "Madrid",
                                "ip_city": "Madrid",
                                "is_vpn_or_tor": false,
                                "is_data_center": false
                              },
                              "confidence": 1.0,
                              "match_mode": "deterministic",
                              "recovery_similarity": 0.9874,
                              "tls_ja4_corroborated": true,
                              "recovery_gate_reason": "hardware_root_match"
                            }
                          ]
                        }
                      ],
                      "database_validations": [
                        {
                          "node_id": "feature_db_validation_1",
                          "issuing_state": "BRA",
                          "validation_type": "one_by_one",
                          "screened_data": {
                            "last_name": "De Lima",
                            "first_name": "Fernando",
                            "tax_number": "01234567890",
                            "date_of_birth": "1980-01-01",
                            "document_type": "ID",
                            "expiration_date": "2030-01-01"
                          },
                          "validations": [
                            {
                              "service_id": "bra_cpf",
                              "service_name": "Brazil - CPF status check",
                              "outcome_code": "MATCH",
                              "validation": {
                                "full_name": "full_match",
                                "date_of_birth": "full_match",
                                "identification_number": "full_match"
                              },
                              "source_data": {
                                "identification_number": "01234567890",
                                "first_name": "FERNANDO",
                                "last_name": "DE LIMA",
                                "date_of_birth": "1980-01-01",
                                "gender": "M",
                                "nationality": "BRA"
                              }
                            }
                          ],
                          "match_type": "full_match",
                          "status": "Approved",
                          "warnings": []
                        }
                      ],
                      "reviews": [
                        {
                          "user": "compliance@example.com",
                          "new_status": "Declined",
                          "comment": "Possible match found in AML screening",
                          "created_at": "2024-07-18T13:29:00.366811Z"
                        }
                      ],
                      "created_at": "2024-07-24T08:54:25.443172Z",
                      "expires_at": "2025-07-24T08:54:25.443172Z",
                      "biometric_consent": {
                        "required": false,
                        "trigger": null,
                        "status": "not_required",
                        "given_at": null,
                        "declined_at": null,
                        "text_version": null,
                        "text_hash": null,
                        "locale": null,
                        "policy_url": null,
                        "step": null,
                        "node_id": null,
                        "ip_address": null,
                        "ip_country_code": null,
                        "ip_state": null,
                        "ip_city": null,
                        "user_agent": null,
                        "detected_ip_address": "83.50.226.71",
                        "detected_country_code": "ES",
                        "detected_state": "ES-B",
                        "detected_city": "Barcelona",
                        "declared_state": null,
                        "document_state": null,
                        "jurisdictions": [],
                        "retention_months": null,
                        "reason": null,
                        "decline_reason": null,
                        "face_data_deleted_at": null
                      }
                    }
                  },
                  "BusinessExample": {
                    "summary": "기업 확인(KYB) 세션 예시",
                    "description": "`session_kind = \"business\"` 결정: KYB 세션은 KYC 기능 배열을 `registry_checks`, `document_verifications`, `key_people_checks`로 대체하는 동시에 `aml_screenings`, `phone_verifications`, `email_verifications`, `questionnaire_responses`, `ip_analyses`, `reviews` 및 세션 엔벨로프를 공유합니다.",
                    "value": {
                      "session_id": "66666666-7777-8888-9999-000000000000",
                      "session_kind": "business",
                      "session_number": 31415,
                      "session_url": "https://verify.didit.me/session/business123",
                      "status": "In Review",
                      "environment": "live",
                      "workflow_id": "abababab-cdcd-efef-0101-232323232323",
                      "features": [
                        "KYB_REGISTRY",
                        "KYB_DOCUMENTS",
                        "KYB_KEY_PEOPLE"
                      ],
                      "vendor_data": "merchant-001234",
                      "metadata": null,
                      "callback": "https://example.com/verification/callback",
                      "registry_checks": [
                        {
                          "status": "Approved",
                          "node_id": "feature_kyb_registry_1",
                          "data_resolved": true,
                          "company": {
                            "uuid": "dddd4444-eeee-5555-ffff-666677778888",
                            "node_id": "feature_kyb_registry_1",
                            "status": "Approved",
                            "registry_status": "active",
                            "data_resolved": true,
                            "company_name": "ACME HOLDINGS LTD",
                            "registration_number": "12345678",
                            "country_code": "GB",
                            "region": null,
                            "company_type": "Private Limited Company",
                            "incorporation_date": "2015-03-12",
                            "registered_address": "1 Example Street, London, EC1A 1AA",
                            "tax_number": null,
                            "risk_level": null,
                            "verification_status": "verified",
                            "is_from_registry": true,
                            "fetch_status": "resolved",
                            "alternative_names": null,
                            "nature_of_business": "62012 - Business and domestic software development",
                            "registered_capital": "100 GBP",
                            "registered_capital_amount": "100.00",
                            "registered_capital_currency": "GBP",
                            "website": null,
                            "email": null,
                            "phone": null,
                            "legal_entity_identifier": null,
                            "location_of_registration": "England and Wales",
                            "financial_summary": null,
                            "officers": [
                              {
                                "uuid": "aaaa1111-bbbb-2222-cccc-333344445555",
                                "name": "Jane Smith",
                                "designation": "Director",
                                "role": "director",
                                "nationality": "British",
                                "is_active": true,
                                "kyc_status": "Approved",
                                "kyc_session_url": "https://verify.didit.me/session/abc123def456"
                              }
                            ],
                            "beneficial_owners": [
                              {
                                "uuid": "bbbb2222-cccc-3333-dddd-444455556666",
                                "name": "John Doe",
                                "first_name": "John",
                                "last_name": "Doe",
                                "entity_type": "person",
                                "roles": [
                                  "ubo",
                                  "shareholder"
                                ],
                                "ownership_min_shares": "50",
                                "ownership_max_shares": "75",
                                "is_active": true,
                                "kyc_status": "Pending",
                                "kyc_session_url": "https://verify.didit.me/session/def456ghi789",
                                "effective_ownership_percent": 75.0
                              }
                            ],
                            "addresses": [
                              {
                                "type": "registered",
                                "address": "1 Example Street, London, EC1A 1AA",
                                "country": "GB"
                              }
                            ],
                            "industries": [
                              {
                                "code": "62012",
                                "description": "Business and domestic software development"
                              }
                            ],
                            "accounts": null,
                            "registry_data": {},
                            "user_provided_data": {
                              "company_name": "ACME HOLDINGS",
                              "registration_number": "12345678"
                            },
                            "confirmed_by_user_at": "2026-06-10T12:01:30.000000Z",
                            "last_console_edit_at": null,
                            "is_editable": false
                          },
                          "ownership_structure": {
                            "shareholders": [
                              {
                                "name": "John Doe",
                                "first_name": "John",
                                "last_name": "Doe",
                                "date_of_birth": null,
                                "country_of_birth": null,
                                "company_name": null,
                                "registration_number": null,
                                "entity_type": "person",
                                "nationality": null,
                                "designation": null,
                                "roles": [
                                  "shareholder"
                                ],
                                "ownership_min_shares": "75",
                                "ownership_max_shares": "75",
                                "voting_min_shares": null,
                                "voting_max_shares": null,
                                "appointment_date": null,
                                "is_active": true,
                                "shareholding": {
                                  "share_class": "ORDINARY",
                                  "number_of_shares": 750.0,
                                  "currency": "GBP",
                                  "nominal_value": 1.0,
                                  "total_value": null,
                                  "percentage": 75.0
                                }
                              }
                            ],
                            "beneficial_owners": []
                          },
                          "warnings": []
                        }
                      ],
                      "aml_screenings": null,
                      "document_verifications": [
                        {
                          "status": "In Review",
                          "node_id": "feature_kyb_documents_1",
                          "items": [
                            {
                              "uuid": "eeee5555-ffff-6666-0000-777788889999",
                              "document_type": "LEGAL_PRESENCE",
                              "document_subtype": "CERTIFICATE_OF_INCORPORATION",
                              "document_group": "LEGAL_PRESENCE",
                              "file_url": "https://<media-host>/kyb/certificate-of-incorporation.pdf",
                              "original_filename": "certificate_of_incorporation.pdf",
                              "file_size": 482133,
                              "status": "Approved",
                              "created_at": "2026-06-10T12:03:11.000000Z",
                              "cross_check_result": {
                                "critical": {
                                  "company_name": {
                                    "document": "ACME HOLDINGS LTD",
                                    "registry": "ACME HOLDINGS LTD",
                                    "score": 1.0,
                                    "match": true
                                  },
                                  "registration_number": {
                                    "document": "12345678",
                                    "registry": "12345678",
                                    "match": true
                                  }
                                },
                                "non_critical": {},
                                "people": {}
                              },
                              "document_metadata": {
                                "file_size": 482133,
                                "content_type": "application/pdf",
                                "creation_date": "2015-03-12T09:00:00",
                                "modified_date": "2015-03-12T09:00:00",
                                "creator": null,
                                "producer": null,
                                "software": null,
                                "encryption": null,
                                "is_signed": true,
                                "is_tampered": false,
                                "signature_info": null,
                                "exif_original_date": null,
                                "exif_digitized_date": null,
                                "processed_by_known_editor": false,
                                "has_different_creation_mod_date": false,
                                "overlay_manipulation": null
                              },
                              "description": null,
                              "is_requested": false,
                              "ocr_data": {
                                "company_name": "ACME HOLDINGS LTD",
                                "registration_number": "12345678",
                                "incorporation_date": "2015-03-12"
                              },
                              "is_console_upload": false,
                              "is_confirmed": true
                            },
                            {
                              "uuid": "ffff6666-0000-7777-1111-888899990000",
                              "document_type": "OWNERSHIP_STRUCTURE",
                              "document_subtype": null,
                              "document_group": "OWNERSHIP_STRUCTURE",
                              "file_url": null,
                              "original_filename": null,
                              "file_size": null,
                              "status": "Not Finished",
                              "created_at": "2026-06-10T15:40:02.000000Z",
                              "cross_check_result": null,
                              "document_metadata": null,
                              "description": "Please upload an up-to-date shareholder registry",
                              "is_requested": true,
                              "ocr_data": null,
                              "is_console_upload": false,
                              "is_confirmed": true
                            }
                          ],
                          "groups": {
                            "LEGAL_PRESENCE": {
                              "total": 1,
                              "approved": 1,
                              "pending": 0,
                              "declined": 0,
                              "in_review": 0,
                              "other": 0,
                              "missing": 0
                            },
                            "OWNERSHIP_STRUCTURE": {
                              "total": 1,
                              "approved": 0,
                              "pending": 0,
                              "declined": 0,
                              "in_review": 0,
                              "other": 0,
                              "missing": 1
                            }
                          },
                          "required_groups": [
                            "LEGAL_PRESENCE",
                            "OWNERSHIP_STRUCTURE"
                          ],
                          "warnings": []
                        }
                      ],
                      "key_people_checks": [
                        {
                          "status": "In Review",
                          "node_id": "feature_kyb_key_people_1",
                          "registry": {
                            "officers": [
                              {
                                "uuid": "aaaa1111-bbbb-2222-cccc-333344445555",
                                "name": "Jane Smith",
                                "designation": "Director",
                                "role": "director",
                                "nationality": "British",
                                "appointment_date": "2015-03-12",
                                "termination_date": null,
                                "is_active": true,
                                "address": "1 Example Street, London, EC1A 1AA",
                                "aml_status": "Approved",
                                "kyc_status": "Approved",
                                "kyc_session_url": "https://verify.didit.me/session/abc123def456",
                                "kyc_session_id": "77777777-8888-9999-aaaa-bbbbbbbbbbbb",
                                "verification_workflow_type": "kyc",
                                "verification_workflow_id": "12121212-3434-5656-7878-909090909090",
                                "verification_workflow_label": "Key People KYC",
                                "verification_workflow_features": [
                                  {
                                    "feature": "ID_VERIFICATION",
                                    "status": "Approved"
                                  },
                                  {
                                    "feature": "LIVENESS",
                                    "status": "Approved"
                                  },
                                  {
                                    "feature": "AML",
                                    "status": "Approved"
                                  }
                                ],
                                "didit_internal_id": "99999999-0000-1111-2222-333333333333",
                                "kyc_document_type": "P",
                                "kyc_nationality": "GBR",
                                "kyc_liveness_passed": true,
                                "kyc_verified_at": "2026-06-10T14:22:31.123456Z",
                                "kyc_aml_categories": {
                                  "sanctions": "clear",
                                  "pep": "clear",
                                  "adverse_media": "clear",
                                  "warnings": "clear"
                                },
                                "kyc_notification_sent_at": "2026-06-09T09:00:00.000000Z"
                              }
                            ],
                            "beneficial_owners": [
                              {
                                "uuid": "bbbb2222-cccc-3333-dddd-444455556666",
                                "name": "John Doe",
                                "first_name": "John",
                                "last_name": "Doe",
                                "date_of_birth": "1980-05-04",
                                "country_of_birth": null,
                                "email": null,
                                "company_name": null,
                                "registration_number": null,
                                "entity_type": "person",
                                "nationality": "British",
                                "designation": null,
                                "roles": [
                                  "ubo",
                                  "shareholder"
                                ],
                                "ownership_min_shares": "50",
                                "ownership_max_shares": "75",
                                "is_active": true,
                                "aml_status": null,
                                "kyc_status": "In Progress",
                                "kyc_session_url": "https://verify.didit.me/session/def456ghi789",
                                "kyc_session_id": "88888888-9999-aaaa-bbbb-cccccccccccc",
                                "verification_workflow_type": "kyc",
                                "verification_workflow_id": "12121212-3434-5656-7878-909090909090",
                                "verification_workflow_label": "Key People KYC",
                                "verification_workflow_features": [
                                  {
                                    "feature": "ID_VERIFICATION",
                                    "status": "Not Finished"
                                  },
                                  {
                                    "feature": "LIVENESS",
                                    "status": "Not Finished"
                                  },
                                  {
                                    "feature": "AML",
                                    "status": "Not Finished"
                                  }
                                ],
                                "didit_internal_id": null,
                                "kyc_document_type": null,
                                "kyc_nationality": null,
                                "kyc_liveness_passed": null,
                                "kyc_verified_at": null,
                                "kyc_aml_categories": null,
                                "kyc_notification_sent_at": null,
                                "child_beneficial_owners": [],
                                "effective_ownership_percent": 75.0
                              }
                            ]
                          },
                          "submitted": {
                            "parties": [
                              {
                                "uuid": "cccc3333-dddd-4444-eeee-555566667777",
                                "entity_type": "person",
                                "source": "USER",
                                "name": "John Doe",
                                "first_name": "John",
                                "last_name": "Doe",
                                "company_name": null,
                                "registration_number": null,
                                "email": "john.doe@example.com",
                                "nationality": "GBR",
                                "phone_number": "+447700900123",
                                "date_of_birth": "1980-05-04",
                                "position": "Chief Executive Officer",
                                "custom_fields": {},
                                "is_active": true,
                                "is_skipped": false,
                                "requires_verification": true,
                                "roles": [
                                  {
                                    "role": "ubo",
                                    "ownership_percent": 75.0,
                                    "voting_percent": 75.0
                                  },
                                  {
                                    "role": "director",
                                    "ownership_percent": null,
                                    "voting_percent": null
                                  }
                                ],
                                "kyc_session_id": "88888888-9999-aaaa-bbbb-cccccccccccc",
                                "kyc_session_status": "In Progress",
                                "kyc_session_url": "https://verify.didit.me/session/def456ghi789",
                                "kyb_sub_session_id": null,
                                "kyb_sub_session_status": null,
                                "kyb_sub_session_url": null,
                                "verification_workflow_type": "kyc",
                                "verification_workflow_id": "12121212-3434-5656-7878-909090909090",
                                "verification_workflow_label": "Key People KYC",
                                "verification_workflow_features": [
                                  {
                                    "feature": "ID_VERIFICATION",
                                    "status": "Not Finished"
                                  },
                                  {
                                    "feature": "LIVENESS",
                                    "status": "Not Finished"
                                  },
                                  {
                                    "feature": "AML",
                                    "status": "Not Finished"
                                  }
                                ],
                                "didit_internal_id": null
                              }
                            ]
                          },
                          "ubo_kyc_summary": {
                            "total": 1,
                            "approved": 0,
                            "flagged": 0,
                            "pending": 1
                          },
                          "warnings": []
                        }
                      ],
                      "phone_verifications": null,
                      "email_verifications": null,
                      "questionnaire_responses": null,
                      "ip_analyses": null,
                      "reviews": [],
                      "contact_details": null,
                      "expected_details": {
                        "company_name": "Tesco PLC",
                        "registry_country": "GB",
                        "registration_number": "00445790"
                      },
                      "created_at": "2026-06-10T11:58:04.000000Z",
                      "expires_at": "2026-06-24T11:58:04.000000Z"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/SessionDecision"
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락되면 `403`이 반환되고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 실패 모드는 두 가지 `detail` 문자열로 구분됩니다.\n\n- `\"Authentication credentials were not provided or are invalid.\"` — `x-api-key` 헤더가 없거나(`Authorization: Bearer` token도 없음), 제공된 자격 증명의 인트로스펙션에 실패한 경우(취소됨, 만료됨 또는 잘못된 형식).\n- `\"You do not have permission to perform this action.\"` — 자격 증명은 유효하지만 이 세션을 읽을 수 있는 권한이 없는 경우: 콘솔 사용자 Bearer token에 `read:sessions` 권한이 없거나 소유 애플리케이션에 액세스할 수 없는 경우, 또는 API 키가 세션과 다른 조직에 속해 있는 경우.\n\n완전히 알 수 없는 `sessionId`의 경우 endpoint는 자격 증명을 검증하기 전에 소유 애플리케이션을 확인하므로, 자격 증명이 누락되었거나 유효하지 않더라도 세션이 존재하지 않으면 `404`가 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "Authentication credentials were not provided or are invalid."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 내부 검사(introspection)에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Insufficient permissions": {
                    "summary": "유효한 자격 증명이지만 read:sessions 권한 또는 소유 애플리케이션에 대한 접근 권한이 없습니다.",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션을 찾을 수 없습니다. 제공된 `sessionId`와 일치하는 사용자 인증(KYC) 또는 기업 확인(KYB) 라이브 세션이 없을 때 반환되며, 삭제된 세션도 여기에 해당합니다. 본문은 표준 `{\"detail\": ...}` 봉투 형식입니다.\n\n**두 가지 구별되는 `detail` 문자열.** `sessionId`가 KYC 및 KYB 세션 모두에서 알 수 없는 경우, 인증 전 소유자 조회가 실패하고 `{\"detail\": \"Not found.\"}`를 받게 됩니다. 이는 자격 증명 검증 전에 발생하므로 인증되지 않은 호출에서도 반환됩니다. 세션이 존재하지만 인증된 애플리케이션에서 조회할 수 없는 경우(예: 오래되었거나 방금 삭제된 레코드), 뷰는 `{\"detail\": \"Session not found.\"}`를 반환합니다. 둘 다 세션에 접근할 수 없다는 동일한 결과를 나타내므로 문자열 대신 `404` 상태 코드로 매칭하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "Not found."
                    }
                  }
                },
                "examples": {
                  "Unknown session id": {
                    "summary": "이 애플리케이션에 알 수 없는 sessionId입니다",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Session not retrievable": {
                    "summary": "세션이 존재하지만 이 애플리케이션에서 조회할 수 없습니다",
                    "value": {
                      "detail": "Session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. GET 요청은 **인증 정보당 분당 600회**(API 키, Bearer token, 또는 미인증 시 소스 IP)로 제한됩니다. `Retry-After` / `X-RateLimit-Reset`을 확인하고 백오프 후 재시도하세요. 결정을 폴링하는 중에 이 제한에 도달했다면 `status.updated` webhook으로 전환하여 상태 변경 시마다 결정을 한 번씩 가져오도록 변경하세요.",
            "headers": {
              "Retry-After": {
                "description": "요청을 재시도하기 전에 대기해야 하는 시간(초).",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "현재 윈도우에서 허용되는 최대 요청 수(GET 요청의 경우 600).",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남아 있는 요청 수입니다.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "현재 윈도우가 리셋되는 Unix 타임스탬프(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 1750000000
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "속도 제한 초과에 대한 사람이 읽기 쉬운 설명입니다.",
                      "example": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "summary": "동일한 자격 증명에서 1분 동안 600건을 초과하는 GET 요청 발생",
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "결정을 조회하려는 인증 세션의 UUID입니다. 이는 `POST /v3/session/`에서 반환된 `session_id`입니다. 사용자 인증(KYC) 및 기업 확인(KYB) 세션 모두 동일한 경로를 사용하며, 서버는 두 세션 유형에 대해 ID를 확인합니다.\n\n**유효한 UUID여야 합니다.** 라우트는 올바른 형식의 UUID만 일치시키므로, 잘못된 형식의 값은 애플리케이션 코드가 실행되기 전에 URL 라우터에 의해 거부되어 아래에 표시된 JSON `{\"detail\": ...}` 응답 형식 대신 `404` **HTML** 페이지를 반환합니다. 클라이언트 측에서 UUID 형식을 검증하여 입력 오류와 실제 세션 누락에 따른 `404`를 구분할 수 있도록 하십시오.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "include",
            "in": "query",
            "required": false,
            "description": "추가 payload 섹션의 쉼표로 구분된 목록입니다. 지원되는 값: `events`, `resubmissions`, 또는 둘 다(`events,resubmissions`). `include=events`가 전달되면 응답에 세션 이벤트 타임라인(세션 조회 페이지에 설명된 `WORKFLOW_BRANCH_EVALUATED` / `WORKFLOW_STATUS_NODE_REACHED` 라우팅 이벤트를 포함하는 `events`), 전체 활동 로그(`activity_reviews`), 차단 목록 플래그(`blocklisted`), 세션당 `cost_breakdown`, 워크플로 메타데이터(세션 상태를 설정한 마지막으로 기록된 워크플로 상태 노드이자 기록된 것이 없으면 `null`인 `workflow_terminal_node_id`, `workflow_type`, `workflow_version`, `workflow_version_id` - 수동 승인, 거부 또는 재제출에 의해 지워지지 않으며 이후의 워크플로 상태 노드로 대체되는 이력 정보), 세션 메타데이터(독립형 API 세션에만 설정되는 문자열 또는 `null`인 `api_service`, `API`, `HOSTED` 또는 `MIGRATED`인 `session_type`, 불리언 값인 `has_device_nfc_support`)가 추가로 포함됩니다. 기본 형태와 비교하여 두 가지 필드가 변경됩니다. 최상위 `session_kind` 구분자가 **생략**되며(events 형태는 사용자 세션에만 존재함), `features` 배열이 단순 문자열에서 `{feature, node_id}` 객체로 전환됩니다(이때 이메일 기능은 `EMAIL_VERIFICATION` 대신 `EMAIL`로 보고됨). 이 확장된 형태는 주로 Didit Console에서 사용되며, 대부분의 API 연동에서는 이 파라미터를 생략해야 합니다. **KYB 제한 사항:** `include=events`는 사용자(KYC) 세션에만 적용됩니다. 기업 세션(`session_kind = \"business\"`)은 항상 표준 기업 결정 형태를 반환합니다. 기업 세션에는 `events`, `activity_reviews`, `blocklisted`, `cost_breakdown` 및 추가 `workflow_*`/세션 메타데이터가 절대 반환되지 않으며, `features` 배열은 단순 문자열 배열로 유지됩니다. `include=resubmissions`를 사용하면(사용자 및 기업 세션 모두) 응답에 `resubmissions`도 포함됩니다. 재제출 요청당 하나의 항목이 가장 오래된 순서대로 포함되며, 각각 `number`, `created_at`, `previous_status`, `nodes`, `reasons`, `requested_by`, `results`(요청 전 재제출된 단계가 반환한 내용으로, 현재 결과와 동일한 키 및 형태로 제공됨)를 가집니다. 각 `cost_breakdown` 항목에는 `usage_type`, `price`, `details`, `created_at`이 포함됩니다. 다시 실행되는 재제출 단계는 새 항목으로 청구됩니다.",
            "schema": {
              "type": "string",
              "enum": [
                "events",
                "resubmissions",
                "events,resubmissions"
              ],
              "example": "events"
            }
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/decision/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Accept: application/json'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.retrieve_decision(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.retrieveDecision(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.RetrieveDecision(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsRetrieveDecisionParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().retrieveDecision(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->retrieveDecision('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.retrieve_decision(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.RetrieveDecisionAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/delete/": {
      "delete": {
        "summary": "인증 세션 삭제(KYC 또는 KYB)",
        "description": "`session_id`를 사용하여 사용자 인증(KYC) 또는 기업 확인(KYB) 단일 인증 세션을 삭제합니다. ID는 먼저 KYC 세션에서 조회한 다음 KYB 세션에서 조회하므로, 두 종류의 세션 모두 이 단일 URL을 통해 삭제됩니다.\n\n**삭제되는 항목:**\n- 세션 및 해당 세션이 보유한 모든 인증 시도(재제출로 대체된 결과 포함): 결정, 추출된 데이터, 모든 관련 기능 레코드(신분증 인증, 얼굴, 라이브니스, 얼굴 대조, AML, 등기부 확인, IP 분석 등), 해당 검토 내역 및 활동 로그.\n- 세션이 소유한 저장된 모든 파일: 신분증 앞면/뒷면 사진(전체, 잘림 및 개인정보 보호를 위한 블러 처리 버전), 신분증 촬영 동영상, 인물 사진 크롭본, NFC 칩 인물 사진 및 서명 이미지, 얼굴 기준 이미지, 라이브니스 동영상, 얼굴 대조 소스/타깃 이미지, 주소 증명 문서 및 업로드된 추가 파일(KYC); 업로드된 기업 문서 및 추가 파일(KYB). 전자 서명 문서, 서명된 PDF, 증빙 PDF 및 서명 이미지(KYC 및 KYB): 다운로드 경로 작동이 중단됩니다. 이전에 발급된 미디어 URL(`https://<media-host>/...`)은 더 이상 확인되지 않습니다.\n- 세션의 얼굴 데이터. 이미지가 없는 템플릿을 유지하도록 선택하지 않는 한(참조: **얼굴 생체 인식 데이터**) 얼굴 임베딩도 삭제됩니다.\n- 세션에 대해 대기열에 아직 남아 있는 webhook 전송 및 재시도. 이미 전송된 webhook은 영향을 받지 않습니다.\n- 기업 확인(KYB) 세션의 경우: 주요 인물(KYC) 및 법인 소유자(KYB)를 위해 생성된 인증이 재귀적으로 삭제되며 `deleted_child_verifications`로 보고됩니다. 재사용된 기존 승인 완료 KYC와 같이 단순히 링크된 인증은 삭제되지 않습니다.\n\n세션은 모든 읽기 endpoint에서 즉시 사라집니다. `GET /v3/session/{sessionId}/decision/`은 `404`를 반환하고 `GET /v3/sessions/`는 목록 표시를 중단합니다. 삭제된 인증으로 인해 시작된 지속적인 AML 모니터링 및 KYB 등기부 모니터링이 중단됩니다.\n\n**영향을 받지 않는 항목:** 이 세션에서 생성된 차단 목록 항목(얼굴 또는 문서)은 제거되지 **않습니다**. 해당 항목은 차단 목록 endpoint에서 관리하십시오. 세션에 대해 발급된 공유 token은 취소되지 않지만, 가져올 대상이 남아 있지 않습니다. 해당 token을 사용한 가져오기는 `{\"share_token\": [\"Original session does not exist.\"]}`와 함께 `400`을 반환합니다. 이미 사용된 크레딧은 환불되지 **않습니다**. 상위 사용자(User) 또는 기업(Business) 엔티티는 삭제되지 **않습니다**. 이에 대해서는 `POST /v3/users/delete/` 또는 `POST /v3/businesses/delete/`를 사용하십시오. 사용자의 프로필 인물 사진이 이 세션에서 생성된 경우, 해당 인물 사진도 세션과 함께 제거됩니다.\n\n**얼굴 생체 인식 데이터:** 기본적으로 세션의 얼굴 임베딩은 세션과 함께 삭제됩니다(`face_retention_outcome: deleted`). 생체 인식 템플릿 보존을 선택한 애플리케이션(`PATCH /v3/webhook/`에서 `face_retention_policy: retain_until_user_deleted`) 또는 `retain_face_embeddings: true`가 포함된 요청은 중복 감지, 얼굴 검색 및 생체 인증이 계속 작동할 수 있도록 세션의 사용자에 고정된, 이미지가 없는 별도 관리 얼굴 생체 인식 템플릿 하나를 유지합니다(`retained_with_user`). 템플릿에는 얼굴 이미지, 미디어, 신원 필드, 결정 또는 삭제된 세션의 id가 절대 포함되지 않습니다. 이는 `biometric_template_expires_at`에 삭제되거나, 사용자 삭제, 개인정보 삭제 또는 `/v3/biometric-templates/`를 통한 명시적 영구 삭제 시 더 일찍 삭제되는 생체 인식 데이터입니다. 연결된 사용자가 없는 세션은 템플릿을 유지할 수 없습니다(`ineligible_no_vendor_user`). 정보주체 권리 행사 요청의 경우 `deletion_instruction: privacy_erasure`를 전송하십시오. 해당 사용자에 대해 보존된 모든 템플릿을 완전히 삭제하며 새 템플릿을 보존하지 않습니다.\n\n**되돌릴 수 없음:** 삭제는 영구적이며 복원 endpoint는 없습니다. 호출하기 전에 필요한 모든 항목(예: 결정 PDF)을 내보내십시오.\n\n**부작용:** 삭제에 대해서는 webhook이 발생하지 않습니다.\n\n**응답:** 삭제가 완료되면 `face_retention_outcome`, 보존된 템플릿의 만료 시간, KYB 세션의 경우 `deleted_child_verifications`를 보고하는 JSON 본문과 함께 `200 OK`가 반환됩니다. 이 endpoint의 이전 버전은 `204 No Content`를 반환했습니다. `204`를 검증하는 클라이언트를 업데이트하십시오. 자체 삭제 로그에 `instruction_id`를 보관하십시오.\n\n**멱등성:** HTTP 수준에서 멱등성을 지원하지 않습니다. 첫 번째 호출은 `200`을 반환하지만, 세션이 더 이상 확인되지 않으므로 반복 호출 시 `404`를 반환합니다. `503` 이후에도 세션은 여전히 유지되므로 동일한 요청을 반복하여 삭제를 완료하십시오.\n\n**인증:** `x-api-key` 헤더에 애플리케이션의 API 키를 전송하십시오. 세션은 해당 애플리케이션에 속해야 합니다. 콘솔 사용자 액세스 토큰(`Authorization: Bearer ...`)도 `delete:sessions` 권한을 보유한 경우 이 endpoint를 호출할 수 있습니다. 인증 실패 및 권한 실패는 모두 `403`을 반환합니다. 이 API는 `401`을 절대 반환하지 않습니다.\n\n**속도 제한:** 모든 POST/PATCH/DELETE endpoint 전반에 걸쳐 API 키당 분당 300회의 공유 쓰기 할당량이 적용되며, 초과 시 `429`를 반환합니다.\n\n숫자 `session_number`를 기준으로 KYC 세션을 일괄 삭제하려면 대신 `POST /v3/sessions/delete/`를 사용하십시오.\n\n**제출된 규제 보고서:** 선택한 데이터가 확정된 규제 보고서에 포함되어 있는 경우 전체 요청이 `409`와 함께 거부되며 아무것도 삭제되지 않습니다. 본문은 `code: in_filed_report`를 사용하며 각 보고서의 `uuid`, `report_number`, `report_type`, `case_uuid`를 명시합니다. 보고서를 삭제한 후 요청을 다시 시도하십시오.",
        "operationId": "delete_v3_session_by_id",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "삭제할 사용자 인증(KYC) 또는 기업 확인(KYB) 세션의 UUID(`session_id`)로, 세션 생성 시 반환된 값입니다. 표준 하이픈 형식의 UUID여야 합니다. UUID가 아닌 값은 라우트와 일치하지 않아 `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "세션이 삭제되었습니다. 본문에는 세션의 얼굴 생체 인식 데이터에 발생한 작업 내용과, KYB 세션의 경우 해당 세션이 생성한 인증 중 세션과 함께 삭제된 인증의 수가 보고됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "삭제된 세션입니다."
                    },
                    "session_number": {
                      "type": "integer",
                      "nullable": true,
                      "description": "삭제된 세션의 번호입니다."
                    },
                    "face_retention_outcome": {
                      "type": "string",
                      "enum": [
                        "retained_with_user",
                        "deleted",
                        "none",
                        "ineligible_no_vendor_user"
                      ],
                      "description": "세션의 얼굴 생체 인식 데이터에 대해 수행된 작업입니다. `deleted`: 얼굴 임베딩이 세션과 함께 삭제되었습니다(기본값). `retained_with_user`: 세션은 삭제되고 이미지가 포함되지 않은 생체 인식 템플릿 하나가 사용자에 연결된 상태로 유지됩니다. `biometric_template_uuid`를 참조하세요. `none`: 세션에 얼굴 임베딩이 없었습니다(예: KYB 세션 또는 라이브니스 셀피가 없는 KYC 세션). `ineligible_no_vendor_user`: 보존이 요청되었으나 세션에 연결된 사용자가 없어 얼굴 임베딩이 세션과 함께 삭제되었습니다. 이 endpoint에서는 생체 인식 저장소 오류가 이 필드를 통해 보고되지 않으며, `503`을 반환하고 세션은 삭제되지 않습니다."
                    },
                    "biometric_template_uuid": {
                      "type": "string",
                      "format": "uuid",
                      "nullable": true,
                      "description": "`face_retention_outcome`이 `retained_with_user`일 때 보존된 생체 인식 템플릿의 ID입니다. 그 외의 경우 `null`입니다. `/v3/biometric-templates/{template_uuid}/`를 통해 관리합니다."
                    },
                    "biometric_template_expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "`face_retention_outcome`이 `retained_with_user`일 때 보존된 생체 인식 템플릿이 삭제되는 시점입니다. 템플릿이 보존되지 않은 경우 `null`입니다."
                    },
                    "deleted_child_verifications": {
                      "type": "integer",
                      "description": "기업 확인(KYB) 세션의 경우: 해당 세션이 생성하여 함께 삭제된 인증 건수(주요 인물의 KYC 세션 및 법인 소유자의 KYB 세션을 재귀적으로 포함)입니다. KYC 세션의 경우 항상 `0`입니다."
                    }
                  }
                },
                "examples": {
                  "Deleted (default)": {
                    "value": {
                      "session_id": "4c5c7f3a-3b1d-4b7e-9c39-2b4f7e6a1d02",
                      "session_number": 1024,
                      "face_retention_outcome": "deleted",
                      "biometric_template_uuid": null,
                      "biometric_template_expires_at": null,
                      "deleted_child_verifications": 0
                    }
                  },
                  "Retained with User": {
                    "value": {
                      "session_id": "4c5c7f3a-3b1d-4b7e-9c39-2b4f7e6a1d02",
                      "session_number": 1024,
                      "face_retention_outcome": "retained_with_user",
                      "biometric_template_uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                      "biometric_template_expires_at": "2027-10-09T10:15:00Z",
                      "deleted_child_verifications": 0
                    }
                  },
                  "Ineligible: no User": {
                    "summary": "vendor_data 없이 생성된 세션에서 보존이 요청됨",
                    "value": {
                      "session_id": "7a1e9c2d-5f4b-4c3a-8e2d-1b0a9f8e7d6c",
                      "session_number": 1031,
                      "face_retention_outcome": "ineligible_no_vendor_user",
                      "biometric_template_uuid": null,
                      "biometric_template_expires_at": null,
                      "deleted_child_verifications": 0
                    }
                  },
                  "KYB session": {
                    "value": {
                      "session_id": "0f3c9b7e-2d1a-4e5f-8c6b-7a9d8e1f2c3b",
                      "session_number": 88,
                      "face_retention_outcome": "none",
                      "biometric_template_uuid": null,
                      "biometric_template_expires_at": null,
                      "deleted_child_verifications": 3
                    },
                    "summary": "기업 확인(KYB) 및 해당 주요 인물을 위해 생성된 3건의 인증이 함께 삭제되었습니다"
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 오류 — 아무것도 삭제되지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Privacy erasure cannot retain": {
                    "value": {
                      "retain_face_embeddings": [
                        "Privacy erasure cannot retain biometric templates."
                      ]
                    }
                  },
                  "No finite retention duration": {
                    "summary": "요청 또는 애플리케이션에 face_retention_days 없이 보존이 요청됨",
                    "value": {
                      "detail": "A finite biometric-template retention duration is required."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 오류입니다. 키가 누락된 경우에도 `403`이 반환되며, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 예외: `sessionId`가 라이브 세션으로 확인되지 않는 경우, 인증 전 소유자 조회에서 자격 증명이 누락되었거나 유효하지 않더라도 먼저 `404`가 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "x-api-key 헤더가 없거나 키가 유효하지 않습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Insufficient permission": {
                    "summary": "delete:sessions 권한이 없는 사용자 token이거나 해당 세션을 소유하지 않은 애플리케이션의 자격 증명입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 `session_id`를 가진 프로덕션 KYC 또는 KYB 세션이 존재하지 않습니다. id를 알 수 없거나 세션이 이미 삭제되었습니다(성공한 삭제를 반복하면 여기에 도달함).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not Found": {
                    "summary": "알 수 없거나 이미 삭제된 세션",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "공유 쓰기 속도 제한을 초과했습니다(API 키당 분당 300개의 POST/PATCH/DELETE 요청). 재시도하기 전에 `Retry-After` 및 `X-RateLimit-*` 응답 헤더를 확인하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "쓰기 예산 소진됨",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "스토리지 서비스, 생체 인식 저장소 또는 모니터링 공급자를 사용할 수 없어 삭제를 완료하지 못했습니다. 세션은 여전히 유지되므로 `200`을 반환할 때까지 동일한 요청을 반복하십시오. 저장된 일부 파일이나 얼굴 임베딩은 이미 삭제되었을 수 있으므로 `503` 이후에는 이에 의존하지 마십시오. 재시도는 단일 템플릿으로 수렴합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Session deletion unavailable": {
                    "summary": "스토리지 서비스 또는 모니터링 공급자를 일시적으로 사용할 수 없습니다.",
                    "value": {
                      "detail": "The session could not be deleted because a storage service or a monitoring provider is unavailable. The session is still in place; repeat the request to finish deleting it."
                    }
                  },
                  "Biometric store unavailable": {
                    "summary": "템플릿을 보존하거나 삭제하는 동안 생체 인식 저장소를 사용할 수 없었습니다",
                    "value": {
                      "detail": "The biometric-template operation could not finish because an external store is unavailable. The operation is retryable."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "세션이 확정된 규제 보고서의 일부입니다. 아무것도 삭제되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InFiledReportError"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl (default policy)",
            "source": "curl -X DELETE \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/delete/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "curl",
            "label": "curl (retain template)",
            "source": "curl -X DELETE \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/delete/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"retain_face_embeddings\": true, \"face_retention_days\": 365}'"
          },
          {
            "lang": "curl",
            "label": "curl (privacy erasure)",
            "source": "curl -X DELETE \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/delete/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"deletion_instruction\": \"privacy_erasure\", \"instruction_id\": \"dsar-2026-0142\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n    retain_face_embeddings=True,\n    face_retention_days=365,\n    instruction_id=\"post-approval-cleanup-2026-08\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.delete(\"11111111-2222-3333-4444-555555555555\", {\n  retain_face_embeddings: true,\n  face_retention_days: 365,\n  instruction_id: \"post-approval-cleanup-2026-08\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Delete(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsDeleteParams{\n\tRetainFaceEmbeddings: didit.Bool(true),\n\tFaceRetentionDays:    didit.Int(365),\n\tInstructionID:        didit.String(\"post-approval-cleanup-2026-08\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().delete(\"11111111-2222-3333-4444-555555555555\", SessionsDeleteParams.builder()\n        .retainFaceEmbeddings(true)\n        .faceRetentionDays(365L)\n        .instructionId(\"post-approval-cleanup-2026-08\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->delete('11111111-2222-3333-4444-555555555555', [\n    'retain_face_embeddings' => true,\n    'face_retention_days' => 365,\n    'instruction_id' => 'post-approval-cleanup-2026-08',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  retain_face_embeddings: true,\n  face_retention_days: 365,\n  instruction_id: \"post-approval-cleanup-2026-08\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.DeleteAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsDeleteParams\n{\n    RetainFaceEmbeddings = true,\n    FaceRetentionDays = 365,\n    InstructionId = \"post-approval-cleanup-2026-08\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": false,
          "description": "선택 사항입니다. 운영 삭제를 통해 애플리케이션의 보존 정책을 따르려면 본문을 완전히 생략하세요.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "retain_face_embeddings": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "이번 삭제에 대해 애플리케이션의 `face_retention_policy`를 재정의합니다. `true`는 세션이 삭제된 후에도 세션의 사용자에 연결된 이미지가 없는 얼굴 생체 인식 템플릿 하나를 유지합니다. `false`는 세션과 함께 얼굴 임베딩을 삭제합니다. 생략하거나 `null`로 설정하면 애플리케이션 정책을 따릅니다. KYB 세션 및 얼굴 임베딩이 없는 세션의 경우 무시됩니다.",
                    "example": true
                  },
                  "face_retention_days": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 3650,
                    "description": "보존된 템플릿의 유한 보존 기간(일 단위)입니다. 애플리케이션에서 이미 `face_retention_days`를 설정하지 않은 한 템플릿이 보존될 때 필수입니다. 템플릿의 `expires_at`은 이 기간, 애플리케이션의 일반 데이터 보존 기간, 그리고 `face_retention_deadline` 중 가장 빠른 시점으로 설정됩니다.",
                    "example": 365
                  },
                  "face_retention_deadline": {
                    "type": "string",
                    "format": "date-time",
                    "description": "보존된 템플릿의 선택적 강제 만료일입니다. 미래 시점이어야 합니다.",
                    "example": "2027-08-28T00:00:00Z"
                  },
                  "deletion_instruction": {
                    "type": "string",
                    "enum": [
                      "operational_session_delete",
                      "privacy_erasure"
                    ],
                    "default": "operational_session_delete",
                    "description": "제공하는 지시의 유형입니다. `operational_session_delete`는 세션을 삭제하고 정책 또는 `retain_face_embeddings`에 명시된 경우에만 템플릿을 보존합니다. `privacy_erasure`는 세션을 삭제하기 전에 세션의 사용자에 고정된 보존된 모든 생체 인식 템플릿을 제거하며, 애플리케이션 정책으로 재정의할 수 없고 `retain_face_embeddings: true`와 함께 사용할 수 없습니다(`400`).",
                    "example": "operational_session_delete"
                  },
                  "instruction_id": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "이 삭제 지침에 대한 귀하의 영구 참조값입니다(예: 삭제 티켓 id). 감사 로그 및 보존되는 템플릿에 기록됩니다. 생략 시 Didit이 생성합니다.",
                    "example": "dsar-2026-0142"
                  }
                }
              },
              "examples": {
                "Retain a biometric template": {
                  "summary": "세션을 삭제하고 이미지가 없는 템플릿은 365일간 유지",
                  "value": {
                    "retain_face_embeddings": true,
                    "face_retention_days": 365,
                    "instruction_id": "post-approval-cleanup-2026-08"
                  }
                },
                "Force deletion on an opted-in application": {
                  "summary": "애플리케이션 정책과 관계없이 얼굴 임베딩 삭제",
                  "value": {
                    "retain_face_embeddings": false
                  }
                },
                "Privacy erasure": {
                  "summary": "정보주체 요청: 세션을 삭제하고 해당 정보주체에 대해 보존된 모든 템플릿을 영구 삭제합니다",
                  "value": {
                    "deletion_instruction": "privacy_erasure",
                    "instruction_id": "dsar-2026-0142"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/session/{sessionId}/generate-pdf/": {
      "get": {
        "summary": "인증 세션의 PDF 보고서 다운로드",
        "description": "완료된 인증 세션에 대해 컴플라이언스 제출용 PDF 보고서를 렌더링하고 다운로드합니다. 동일한 경로에서 사용자 인증(KYC) 및 기업 확인(KYB) 세션을 모두 지원합니다. 서버가 두 세션 유형에 대해 `sessionId`를 확인하고 일치하는 보고서 템플릿을 선택합니다.\n\n**대상 상태.** 세션이 이미 최종 상태이거나 검토 가능한 상태여야 합니다.\n\n- KYC 세션: `Approved`, `Declined`, `In Review` 또는 `Kyc Expired`\n- KYB 세션: `Approved`, `Declined` 또는 `In Review`\n\n다른 모든 상태(`Not Started`, `In Progress`, `Expired`, `Abandoned` 등)는 설명이 포함된 `detail` 문자열과 함께 `403`을 반환합니다(아래 `403` 응답 참조).\n\n**보고서 내용.** PDF는 요청 시점의 콘솔 세션 화면을 그대로 반영합니다.\n\n- **KYC** — 취합된 세션 상태, 경고 목록, 실행된 기능별 섹션: 신분증 인증(문서 이미지 및 추출된 필드), NFC, 라이브니스, 얼굴 대조, 이메일 인증, 전화번호 인증, 주소 증명, 설문지 답변, 데이터베이스 검증, AML 스크리닝, IP 분석. 이어서 세션 태그, 콘솔 검토 활동(댓글 및 상태 변경) 및 세션 이벤트 타임라인이 포함됩니다.\n- **KYB** — 등기부 확인(기업 데이터), AML 스크리닝, 기업 문서 검증, 주요 인물 확인, 설문지 응답, 전화번호/이메일 인증, IP 분석, 세션 이벤트 타임라인, 그리고 태그 및 검토 활동이 포함됩니다.\n\n**브랜딩.** 애플리케이션에 화이트 라벨 맞춤 설정이 적용된 경우 보고서는 고객사의 로고와 개인정보 처리방침 URL 링크로 렌더링됩니다. 그렇지 않은 경우 Didit 브랜딩이 적용됩니다. 보고서는 영어로 렌더링되며, 언어 파라미터는 제공되지 않습니다.\n\n**캐싱 없음.** 모든 호출은 현재 세션 데이터에서 PDF를 다시 렌더링하므로 수동 검토 후에 생성된 보고서에는 검토자의 결정이 반영됩니다. 동일한 세션에 대해 두 번 호출하면 바이트 단위로 서로 다른 파일이 생성될 수 있으므로 변경 불가능한 사본이 필요한 경우 다운로드한 파일을 보관하세요.\n\n**지연 시간.** 렌더링 시 PDF를 구성하기 전에 저장된 모든 이미지(문서 앞뒷면, 셀피, 추가 파일)를 다운로드하므로 미디어가 많은 세션은 몇 초 정도 걸릴 수 있습니다. 클라이언트 읽기 제한 시간을 넉넉하게 설정(60초 권장)하고 본문을 디스크로 스트리밍하세요.\n\n**트레일링 슬래시.** 정식 경로는 트레일링 슬래시(`…/generate-pdf/`)로 끝납니다. 슬래시가 없는 요청도 동일한 응답으로 직접 처리됩니다. `301` 리디렉션이 발생하지 않으므로 클라이언트가 리디렉션을 따를 필요가 없으며 `curl`에 `-L`을 사용할 필요가 없습니다. 샘플에 나와 있는 것처럼 슬래시가 포함된 URL을 사용하세요.\n\n렌더링된 보고서 대신 원본 데이터가 JSON으로 필요한 경우 `GET /v3/session/{sessionId}/decision/`을 사용하세요. 단일 문서에서 한 사용자의 보고 가능한 모든 세션을 확인하려면 `GET /v3/users/{vendor_data}/generate-pdf/`를 사용하세요.",
        "operationId": "get_v3_session_generate_pdf",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "generate_pdf",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "렌더링할 사용자 인증(KYC) 또는 기업 확인(KYB) 세션의 UUID입니다(`POST /v3/session/`에서 반환된 `session_id`). 두 세션 유형 모두 동일한 경로가 작동하며, 수신된 보고서 유형을 확인하려면 응답의 `Content-Disposition` 파일명을 사용하십시오.\n\n**반드시 올바른 형식의 소문자 UUID여야 합니다.** 라우트는 유효한 UUID만 일치시키므로, 잘못된 형식의 값은 애플리케이션 코드가 실행되기 전에 URL 라우터에 의해 거부되며 응답은 아래 표시된 JSON `{\"detail\": ...}` 형식이 아닌 `404` **HTML** 페이지로 반환됩니다. 라우트의 UUID 변환기는 표준 소문자 형식만 일치시키므로 대문자 16진수 UUID는 HTML 404로 거부됩니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "렌더링된 PDF 문서로, 바이너리 `application/pdf` 형식으로 직접 반환됩니다. JSON 래퍼나 다운로드 URL 간접 참조가 없습니다. 본문은 `%PDF` 매직 바이트(PDF 1.7)로 시작합니다. `.pdf` 파일로 저장하거나 호출자에게 스트리밍하세요.",
            "headers": {
              "Content-Disposition": {
                "description": "KYC 세션의 경우 `attachment; filename=session_{sessionId}.pdf`, KYB 세션의 경우 `attachment; filename=business_{sessionId}.pdf`입니다. 접두사를 통해 렌더링된 보고서 템플릿을 확인할 수 있습니다.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=session_11111111-2222-3333-4444-555555555555.pdf"
                }
              },
              "Content-Length": {
                "description": "PDF의 총 크기(바이트 단위)이며, 본문은 청크로 분할되지 않습니다.",
                "schema": {
                  "type": "integer",
                  "example": 25191
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "인증, 권한 부여 또는 세션 상태 실패입니다. 키가 누락된 경우 `403`이 반환되며, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 실패 모드는 `detail` 문자열로 구분하십시오.\n\n- `\"Authentication credentials were not provided or are invalid.\"` — `x-api-key` 헤더(및 `Authorization: Bearer` token)가 없거나, 제공된 자격 증명의 인트로스펙션에 실패했습니다(취소됨, 만료됨 또는 형식 오류).\n- `\"You do not have permission to perform this action.\"` — 자격 증명은 유효하지만 이 세션을 읽을 수 없습니다. 콘솔 사용자 Bearer token에 `read:sessions` 권한이 없거나 소유 애플리케이션에 접근할 수 없거나, API 키가 세션과 다른 조직에 속해 있습니다.\n- `\"You can only generate a PDF for sessions in review, declined, approved or kyc expired\"` — KYC 세션이 존재하지만 아직 보고서 생성이 가능한 상태(예: `Not Started` 또는 `In Progress`)가 아닙니다. 보고서를 요청하기 전에 `status.updated` webhook을 기다리십시오.\n- `\"You can only generate a PDF for sessions in review, declined or approved\"` — KYB 세션에 대한 동일한 조건입니다.\n\n완전히 알 수 없는 `sessionId`의 경우 endpoint는 자격 증명을 검증하기 전에 소유 애플리케이션을 먼저 확인하므로, 자격 증명이 누락되었거나 유효하지 않더라도 누락된 세션은 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "You can only generate a PDF for sessions in review, declined, approved or kyc expired"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 내부 검사(introspection)에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Insufficient permissions": {
                    "summary": "유효한 자격 증명이지만 read:sessions 권한 또는 소유 애플리케이션에 대한 접근 권한이 없습니다.",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "KYC session not finished": {
                    "summary": "KYC 세션이 아직 시작되지 않음 / 진행 중임",
                    "value": {
                      "detail": "You can only generate a PDF for sessions in review, declined, approved or kyc expired"
                    }
                  },
                  "KYB session not finished": {
                    "summary": "KYB 세션이 아직 시작되지 않음 / 진행 중임",
                    "value": {
                      "detail": "You can only generate a PDF for sessions in review, declined or approved"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 `sessionId`를 가진 활성 세션이 존재하지 않습니다. 생성된 적이 없거나 삭제되었습니다. 자격 증명 검증보다 소유자 확인이 먼저 이루어지므로 인증되지 않은 요청에 대해서도 이 `404`가 반환됩니다. 조회 실패 위치에 따라 `detail` 문자열은 `\"Not found.\"`(일반적인 경우) 또는 `\"Session not found.\"`가 됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "Not found."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "sessionId가 어떠한 KYC 또는 KYB 세션과도 일치하지 않습니다",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Recently deleted session": {
                    "summary": "조회 도중 세션이 삭제되었습니다",
                    "value": {
                      "detail": "Session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. PDF 생성에는 전역 GET 한도인 분당 600회 외에 **인증 정보당 분당 50회**(API 키, Bearer token, 또는 미인증 시 소스 IP)의 전용 한도가 적용됩니다. `Retry-After`초(`X-RateLimit-*` 헤더에도 반영됨) 동안 대기한 후 재시도하세요. 보고서는 서버 측에 캐시되지 않으므로, 다시 가져오는 대신 각 보고서를 한 번 다운로드하여 파일을 저장해 두세요.",
            "headers": {
              "Retry-After": {
                "description": "요청을 재시도하기 전에 대기해야 하는 시간(초).",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "현재 윈도우에서 허용되는 최대 PDF 생성 횟수(50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남아 있는 요청 수입니다.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "현재 윈도우가 리셋되는 Unix 타임스탬프(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 1750000000
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "속도 제한 초과에 대한 사람이 읽기 쉬운 설명입니다.",
                      "example": "Session PDF generation rate limit exceeded. You can make up to 50 requests per minute."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "summary": "동일한 자격 증명에서 1분 동안 50회를 초과하는 PDF 생성 발생",
                    "value": {
                      "detail": "Session PDF generation rate limit exceeded. You can make up to 50 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --fail \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/generate-pdf/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  --output report.pdf"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.generate_pdf(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.generatePdf(\"11111111-2222-3333-4444-555555555555\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.GeneratePDF(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().generatePdf(\"11111111-2222-3333-4444-555555555555\")\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->sessions->generatePdf('11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.generate_pdf(\"11111111-2222-3333-4444-555555555555\")\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.GeneratePdfAsync(\"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/sandbox/arm/": {
      "post": {
        "summary": "세션에서 샌드박스 시나리오 활성화",
        "description": "`Not Started` 상태인 세션에 샌드박스 시나리오를 유지하고 번들된 매직 값(이메일, 전화번호 또는 `expected_details` 필드)을 세션에 적용하여, 플로우가 실행되면 모의 제공자가 시나리오의 결과를 재현하도록 합니다. 이 endpoint는 Didit의 호스팅 인증 UI에 있는 플로우 사전 시나리오 선택기에서 테스터가 캡처를 시작하기 전에 결과를 선택할 때 호출합니다. 이에 맞춰 자체 선택기를 구축하거나 샌드박스 테스트 하네스에서 직접 호출할 수 있습니다.\n\n애플리케이션 `x-api-key`가 아닌 세션 자체의 `Session-Token`([Create Session](/ko/sessions-api/create-session)의 `session_token`으로 반환됨)으로 인증하세요. 이 endpoint는 백엔드가 아닌 클라이언트에서 호출하도록 설계되었습니다. 시나리오는 `status`가 `Not Started`인 동안에만 수락됩니다. 여전히 `Not Started`인 상태에서 다시 호출하면 세션이 재준비(re-arm)됩니다. 새 시나리오의 매직 값으로 교체되고 *이전* 시나리오가 작성한 값만 지워지므로, 사용자가 이미 직접 입력한 값(이메일, 이름 등)은 재준비 후에도 유지됩니다. `Not Started`를 지난 세션이나 라이브(비샌드박스) 애플리케이션에 속한 세션을 준비하려고 하면 거부됩니다.\n\n전체 시나리오 카탈로그와 결과를 유도하는 다른 두 가지 방법(세션 생성 시 `sandbox_scenario` 지정 및 매직 값 직접 입력)은 [샌드박스 및 테스트 데이터](/ko/integration/sandbox-testing)를 참조하세요.",
        "operationId": "post_v3_session_sandbox_arm",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "arm_sandbox",
          "auth": "device_token",
          "server": false
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "SessionTokenAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "활성화할 샌드박스 인증 세션의 UUID입니다. 인증에 사용된 Session-Token에 인코딩된 세션과 일치해야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "scenario"
                ],
                "properties": {
                  "scenario": {
                    "type": "string",
                    "description": "준비할 시나리오의 슬러그입니다. GET /v1/sandbox/scenarios/의 카탈로그 또는 [샌드박스 및 테스트 데이터](/ko/integration/sandbox-testing)의 시나리오 표를 참조하십시오.",
                    "example": "decline_document_expired"
                  }
                }
              },
              "examples": {
                "Arm": {
                  "summary": "AML PEP 히트 시나리오 활성화",
                  "value": {
                    "scenario": "decline_aml_hit"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "시나리오가 준비되었습니다. 해당 매직 값이 이제 세션에 적용되었습니다. `status`는 세션의 현재 상태를 반영하며, 이 호출로는 절대 변경되지 않습니다. 성공 시 항상 `Not Started`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "scenario": {
                      "type": "string",
                      "description": "활성화된 시나리오 슬러그입니다(요청 내용을 그대로 반영)."
                    },
                    "status": {
                      "type": "string",
                      "example": "Not Started"
                    }
                  }
                },
                "examples": {
                  "Armed": {
                    "summary": "Not Started 상태의 세션에 준비된 시나리오",
                    "value": {
                      "session_id": "11111111-2222-3333-4444-555555555555",
                      "scenario": "decline_aml_hit",
                      "status": "Not Started"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류: 알 수 없는 시나리오 슬러그이거나 세션이 이미 `Not Started` 단계를 지났습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown Scenario": {
                    "summary": "시나리오가 카탈로그에 없습니다",
                    "value": {
                      "scenario": [
                        "Unknown sandbox scenario: 'not-a-real-scenario'."
                      ]
                    }
                  },
                  "Already Started": {
                    "summary": "세션이 Not Started 단계를 지났습니다",
                    "value": [
                      "Scenario can only be armed before the verification starts."
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Session-Token이 이 `session_id`로 확인되지 않거나, 세션이 프로덕션(비샌드박스) 애플리케이션에 속해 있습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "진행 중인 세션이거나, session_id / token이 일치하지 않음",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/sandbox/arm/ \\\n  -H 'Session-Token: YOUR_SESSION_TOKEN' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"scenario\": \"decline_aml_hit\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import requests\n\nresponse = requests.post(\n    \"https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/sandbox/arm/\",\n    headers={\n        \"Session-Token\": \"YOUR_SESSION_TOKEN\",\n        \"Content-Type\": \"application/json\",\n    },\n    json={\"scenario\": \"decline_aml_hit\"},\n)\nresponse.raise_for_status()\nprint(response.json())  # {'session_id': '...', 'scenario': 'decline_aml_hit', 'status': 'Not Started'}"
          },
          {
            "lang": "javascript",
            "label": "JavaScript",
            "source": "const response = await fetch(\n  'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/sandbox/arm/',\n  {\n    method: 'POST',\n    headers: {\n      'Session-Token': sessionToken,\n      'Content-Type': 'application/json',\n    },\n    body: JSON.stringify({ scenario: 'decline_aml_hit' }),\n  },\n);\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst { session_id, scenario, status } = await response.json();"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/update-status/": {
      "patch": {
        "summary": "인증 세션 승인, 거부 또는 재제출 요청",
        "description": "KYC 또는 KYB 인증 세션의 최종 결정을 수동으로 재지정합니다. `new_status`를 `Approved` 또는 `Declined`로 설정하여 수동 결정을 기록하거나, `Resubmitted`로 설정하여 특정 인증 단계를 초기화하고 사용자가 동일한 인증 URL을 통해 해당 단계를 다시 진행하도록 할 수 있습니다. 이 endpoint는 사용자(KYC) 및 기업(KYB) 세션 ID를 모두 허용합니다.\n\n세션이 검토 가능한 상태에 도달한 후에 호출하십시오. 현재 상태는 `Approved`, `Declined`, `In Review`, `Kyc Expired`, `Abandoned` 또는 `Resubmitted`여야 합니다. 여전히 `Not Started`, `In Progress` 또는 `Awaiting User` 상태이거나 `Expired`로 종료된 세션은 `400`을 반환합니다. API 키에는 `write:sessions` 권한이 필요합니다(범위가 지정된 API 키에는 결정에 대한 쓰기 권한이 필요함). 대상 상태 확인은 본문 유효성 검사 전에 실행되므로, 부적격한 세션은 payload 역시 유효하지 않더라도 `Wrong Current Status` 오류를 반환합니다.\n\n`Resubmitted`의 경우, 사용자가 다시 진행해야 하는 워크플로 단계를 선택하려면 `nodes_to_resubmit`을 전달하고, 재제출 가능한 상태(`Declined`, `In Review`, `Not Finished`, `Expired`)에 있는 기존 기능 시도를 자동으로 선택하려면 이를 생략하십시오. 한 번도 시도하지 않은 기능은 자동 선택되지 않습니다. `nodes_to_resubmit`에 명시적으로 나열해야 하며, 그렇지 않고 재제출이 필요한 기록된 시도가 없으면 요청은 `400`을 반환합니다. 선택한 단계의 이전 결과는 재제출 내역(`include=resubmissions`를 사용한 Get Decision으로 반환됨)으로 이동되고, 단계는 워크플로 그래프와 일치하도록 재정렬되며, 세션의 만료 기간이 다시 시작되고 원래의 인증 URL을 다시 사용할 수 있게 됩니다. 목록 맨 앞의 백엔드 전용 단계(`AML`, `DATABASE_VALIDATION`, `IP_ANALYSIS`)는 사용자 상호작용 없이 즉시 실행됩니다. 재제출된 모든 단계가 백엔드 전용인 경우, 세션은 동일한 요청 내에서 다시 완료됩니다. `KYB_REGISTRY` 및 `KYB_KEY_PEOPLE`은 직접 재제출할 수 없습니다. 대신 관련 하위 KYC 세션을 재제출하면 상위 기업 세션이 자동으로 다시 계산됩니다.\n\n상태를 변경하는 모든 호출은 변경 사항이 커밋되면 `status.updated` [webhook](/ko/integration/webhooks)을 트리거하고 세션의 `reviews`에 행위자 정보 및 `comment`가 포함된 활동 항목을 추가하며, 이는 [Get Decision](#get-/v3/session/-sessionId-/decision/) 및 콘솔 활동 타임라인에서 확인할 수 있습니다. 세션의 `vendor_data`에 연결된 사용자 프로필 집계도 업데이트됩니다. 거부하면 세션에 대한 지속적인 AML 모니터링이 비활성화되며, 워크플로에서 모니터링이 켜져 있는 경우 재승인(`Resubmitted`, `Declined` 또는 `Kyc Expired` 상태에서) 시 다시 활성화됩니다. KYB 주요 인물 확인에 속한 하위 KYC를 승인하거나 거부하면 상위 기업 세션의 상태가 다시 계산됩니다. 사용자에게 알리려면 `send_email: true`를(`email_address`와 함께) 설정하십시오. `Approved`/`Declined`의 경우 상태 알림이, `Resubmitted`의 경우 인증 링크와 단계별 사유가 포함된 재제출 이메일이 전송됩니다. 이메일을 먼저 확인하려면 [Preview Decision Email](/ko/sessions-api/preview-decision-email)(`Approved`, `Declined`) 또는 [Preview Resubmission Email](/ko/sessions-api/preview-resubmission)(`Resubmitted`)을 통해 미리 확인하고 해당 `preview_token`을 `email_preview_token`으로 전달하십시오. 그러면 업데이트 시 정확히 미리 본 이메일이 전송되거나, 미리 보기 이후 이메일 또는 세션이 변경되었거나 영수증이 15분보다 오래된 경우 변경 사항을 적용하기 전에 `409`를 반환합니다.\n\n이미 해당 상태인 세션에 대해 `Approved` 또는 `Declined`를 반복하면 아무것도 변경되지 않고 `200`이 반환됩니다(webhook 없음, 활동 항목 없음, 이메일 없음). `Resubmitted`를 반복하면 `400`(`The new status is the same as the current status.`)이 반환됩니다. 자격 증명이 누락되었거나 유효하지 않은 경우 및 권한이 누락된 경우 `403`이 반환되며, 만료된 범위 지정 API 키는 `401`을 반환합니다.",
        "operationId": "patch_v3_session_update_status",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "업데이트할 인증 세션의 UUID입니다. 사용자(KYC) 및 기업(KYB) 세션 ID를 모두 지원하며, 서비스는 두 세션 유형 전체에서 ID를 확인합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "new_status"
                ],
                "properties": {
                  "new_status": {
                    "type": "string",
                    "description": "대상 상태입니다. `Approved` 및 `Declined`는 최종 수동 결정을 기록합니다(서로를 번복할 수도 있음). `Resubmitted`는 선택한 단계를 지우고 세션을 사용자에게 다시 보냅니다. 다른 값은 `400`을 반환합니다.",
                    "enum": [
                      "Approved",
                      "Declined",
                      "Resubmitted"
                    ],
                    "example": "Approved"
                  },
                  "comment": {
                    "type": "string",
                    "description": "변경에 대한 자유 형식 사유로, 세션의 검토 기록에 저장되며 [Get Decision](#get-/v3/session/-sessionId-/decision/)의 `reviews` 배열로 반환됩니다. 예: `Duplicated user`.",
                    "example": "All checks passed manual review"
                  },
                  "nodes_to_resubmit": {
                    "type": "array",
                    "description": "사용자가 다시 진행해야 하는 워크플로 단계입니다. `new_status`가 `Resubmitted`인 경우에만 처리됩니다. `Approved`/`Declined`의 경우 항목에 대한 스키마 유효성 검사는 계속 수행되지만(유효하지 않은 `feature` 값은 `400` 반환), 유효한 항목은 의미론적으로 무시됩니다. 생략할 경우, 서버는 상태가 `Declined`, `In Review`, `Not Finished` 또는 `Expired`인 기존 OCR, Liveness, Face Match, POA, Phone, Email, AML, Database Validation, Questionnaire 시도를 자동으로 선택합니다(NFC, IP 분석, 연령 추정, 얼굴 검색 및 KYB 문서 시도는 절대 자동 선택되지 않으며, 얼굴 대조가 아닌 얼굴 시도는 `LIVENESS`로 선택됨). 사용자가 시도한 적 없는 기능(기록된 시도 없음)은 선택되지 않으므로 시도가 0건인 세션은 승인된 항목이 없더라도 `400`(\"No features found that need resubmission\")을 반환합니다. 이 경우에는 `nodes_to_resubmit`을 명시적으로 전달하십시오. 단계는 전송 순서와 관계없이 워크플로 그래프 순서대로 실행됩니다. `KYB_REGISTRY`, `KYB_KEY_PEOPLE` 및 `KYB` 별칭은 `400`으로 거부됩니다. 이러한 상위 검사는 하위 KYC 세션에서 다시 계산됩니다.",
                    "items": {
                      "type": "object",
                      "required": [
                        "node_id",
                        "feature"
                      ],
                      "properties": {
                        "node_id": {
                          "type": "string",
                          "description": "세션의 워크플로 정의에 표시되는 노드 식별자(예: `feature_ocr`, `feature_liveness`).",
                          "example": "feature_ocr"
                        },
                        "feature": {
                          "type": "string",
                          "description": "노드의 기능 유형입니다. `ID_VERIFICATION`, `POA`, `PHONE`, `EMAIL` 별칭은 서버 측에서 `OCR`, `PROOF_OF_ADDRESS`, `PHONE_VERIFICATION`, `EMAIL_VERIFICATION`으로 정규화됩니다. `KYB_REGISTRY`, `KYB_KEY_PEOPLE`, `KYB`는 스키마 유효성 검사를 통과하지만 예시에 표시된 비즈니스 규칙 `400` 오류로 항상 거부됩니다.",
                          "enum": [
                            "OCR",
                            "OCR_BACK",
                            "NFC",
                            "AML",
                            "FACE",
                            "LIVENESS",
                            "FACE_MATCH",
                            "IP_ANALYSIS",
                            "AGE_ESTIMATION",
                            "PROOF_OF_ADDRESS",
                            "PHONE_VERIFICATION",
                            "EMAIL_VERIFICATION",
                            "FACE_SEARCH",
                            "DATABASE_VALIDATION",
                            "QUESTIONNAIRE",
                            "DOCUMENT_AI",
                            "KYB_DOCUMENTS",
                            "ID_VERIFICATION",
                            "POA",
                            "PHONE",
                            "EMAIL",
                            "KYB_REGISTRY",
                            "KYB_KEY_PEOPLE",
                            "KYB",
                            "GEOLOCATION"
                          ],
                          "example": "OCR"
                        }
                      }
                    }
                  },
                  "send_email": {
                    "type": "boolean",
                    "description": "사용자에게 변경 사항에 대한 이메일을 보낼지 여부입니다. `email_address`가 필요합니다. `Approved`/`Declined`의 경우 사용자는 상태 알림을 받으며, `Resubmitted`의 경우 이메일에 인증 링크와 단계별 재제출 사유가 포함됩니다.",
                    "default": false,
                    "example": false
                  },
                  "email_address": {
                    "type": "string",
                    "format": "email",
                    "description": "알림 이메일을 수신할 수취인입니다. **`send_email`이 `true`일 때 필수**이며, 생략 시 `400`이 반환됩니다.",
                    "example": "user@example.com"
                  },
                  "email_language": {
                    "type": "string",
                    "description": "알림 이메일 언어입니다. 스키마 수준에서 모든 문자열을 허용하며, 지원되지 않는 코드는 영어(`en`)로 자동 대체됩니다.",
                    "default": "en",
                    "example": "en"
                  },
                  "email_preview_token": {
                    "type": "string",
                    "writeOnly": true,
                    "minLength": 1,
                    "maxLength": 512,
                    "description": "[Preview Decision Email](/ko/sessions-api/preview-decision-email)(`Approved` 및 `Declined`용) 또는 [Preview Resubmission Email](/ko/sessions-api/preview-resubmission)(`Resubmitted`용)의 선택적 영수증인 `preview_token`입니다. `send_email: true`일 때만 유효하며, 그렇지 않으면 요청이 `400`을 반환합니다. 수신자, 언어, 세션 상태, 발신자 및 이메일(재제출의 경우 선택한 단계 포함)이 미리보기와 계속 일치해야 하며, 영수증은 15분 후에 만료됩니다. 그렇지 않으면 세션이 변경되거나 이메일이 전송되기 전에 요청이 `409`를 반환합니다. 기존 연동에서는 이 필드를 생략할 수 있습니다."
                  }
                }
              },
              "examples": {
                "Approve Session": {
                  "summary": "수동 검토 후 세션 승인",
                  "value": {
                    "new_status": "Approved",
                    "comment": "All checks passed manual review"
                  }
                },
                "Decline Session": {
                  "summary": "세션 거부",
                  "value": {
                    "new_status": "Declined",
                    "comment": "Suspected fraud"
                  }
                },
                "Resubmit Specific Steps": {
                  "summary": "선택한 단계 재제출 요청(이메일 포함)",
                  "value": {
                    "new_status": "Resubmitted",
                    "nodes_to_resubmit": [
                      {
                        "node_id": "feature_ocr",
                        "feature": "OCR"
                      },
                      {
                        "node_id": "feature_liveness",
                        "feature": "LIVENESS"
                      }
                    ],
                    "send_email": true,
                    "email_address": "user@example.com",
                    "email_language": "en"
                  }
                },
                "Resubmit Auto-select": {
                  "summary": "재제출 요청(미승인 단계 자동 선택)",
                  "value": {
                    "new_status": "Resubmitted"
                  }
                },
                "Approve With Previewed Email": {
                  "summary": "결정 이메일 미리보기에서 반환된 이메일을 승인하고 발송",
                  "value": {
                    "new_status": "Approved",
                    "send_email": true,
                    "email_address": "person@example.com",
                    "email_language": "en",
                    "email_preview_token": "eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "상태가 업데이트되었습니다. 응답에는 `session_id`만 포함됩니다. 업데이트된 세션은 [결정 조회](#get-/v3/session/-sessionId-/decision/)를 통해 가져오십시오. 변경 사항이 커밋되면 `status.updated` webhook이 트리거됩니다. `Approved` 또는 `Declined`를 반복 호출하면 동일한 본문이 반환되고 아무것도 변경되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "업데이트된 세션의 UUID입니다."
                    }
                  }
                },
                "examples": {
                  "Updated": {
                    "summary": "Approved, Declined 및 Resubmitted 모두에 대해 반환됨",
                    "value": {
                      "session_id": "3472fb7c-8f7c-4d1a-9cf4-cf3d74ce1a60"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 필드 오류는 `{\"<field>\": [\"<message>\"]}`로 전달되고(일부 비즈니스 규칙 거부는 문자열 값을 대신 사용: `{\"nodes_to_resubmit\": \"<message>\"}`), 상태 간 오류는 `{\"detail\": \"<message>\"}`로, 동일 상태 오류는 단순 JSON 배열로 전달됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Wrong Current Status": {
                    "summary": "세션이 업데이트 가능한 상태가 아닙니다",
                    "value": {
                      "detail": "Only sessions with status Approved, Declined, In Review, Kyc Expired, Abandoned, Resubmitted can be updated. Current status: In Progress"
                    }
                  },
                  "Invalid Status Value": {
                    "summary": "new_status가 실제 세션 상태이지만 Approved/Declined/Resubmitted 중 하나가 아님",
                    "value": {
                      "new_status": [
                        "You can only update the status to 'Approved', 'Declined', or 'Resubmitted'."
                      ]
                    }
                  },
                  "Missing new_status": {
                    "summary": "필수 필드가 누락됨",
                    "value": {
                      "new_status": [
                        "This field is required."
                      ]
                    }
                  },
                  "Same Status": {
                    "summary": "이미 재제출된 세션에 재제출이 요청됨",
                    "value": [
                      "The new status is the same as the current status."
                    ]
                  },
                  "Email Address Required": {
                    "summary": "email_address 없이 send_email이 true입니다",
                    "value": {
                      "email_address": [
                        "Email address is required when send_email is true."
                      ]
                    }
                  },
                  "Non-resubmittable Feature": {
                    "summary": "재제출은 KYB 상위 검사를 대상으로 합니다",
                    "value": {
                      "nodes_to_resubmit": "The following features cannot be resubmitted directly: KYB_REGISTRY. Resubmit the relevant child KYC sessions instead; the parent will recompute automatically."
                    }
                  },
                  "Nothing To Resubmit": {
                    "summary": "자동 선택 결과 승인되지 않은 기능을 찾지 못했습니다",
                    "value": {
                      "nodes_to_resubmit": "No features found that need resubmission. All features are already approved."
                    }
                  },
                  "Invalid Feature Choice": {
                    "summary": "nodes_to_resubmit의 알 수 없는 기능",
                    "value": {
                      "nodes_to_resubmit": [
                        {
                          "feature": [
                            "\"BOGUS\" is not a valid choice. Valid choices are: OCR, OCR_BACK, NFC, AML, FACE, LIVENESS, FACE_MATCH, IP_ANALYSIS, AGE_ESTIMATION, PROOF_OF_ADDRESS, PHONE_VERIFICATION, EMAIL_VERIFICATION, FACE_SEARCH, DATABASE_VALIDATION, QUESTIONNAIRE, KYB_REGISTRY, KYB_DOCUMENTS, KYB_KEY_PEOPLE, ID_VERIFICATION, POA, PHONE, EMAIL, KYB"
                          ]
                        }
                      ]
                    }
                  },
                  "Invalid Status Value (not a status at all)": {
                    "summary": "new_status가 올바른 StatusChoices 값이 아님",
                    "value": {
                      "new_status": [
                        "\"Bogus\" is not a valid choice."
                      ]
                    }
                  },
                  "Preview Receipt Without Email": {
                    "summary": "send_email: true 없이 전송된 email_preview_token",
                    "value": {
                      "email_preview_token": [
                        "A preview receipt is only valid when the email is sent."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "만료일이 지난 스코프 지정 API 키",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나 권한이 부족합니다. 또는 다른 애플리케이션에 속한 `session_id`입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "API 키에 write:sessions 권한이 없습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 `session_id`를 가진 KYC 또는 KYB 세션이 존재하지 않습니다(삭제된 세션도 `404`를 반환합니다).",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "알 수 없는 session_id",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "백엔드 전용 기능(AML, DATABASE_VALIDATION, IP_ANALYSIS)만을 대상으로 하는 재제출이 30초 쿨다운 기간 내에 반복되었습니다. 즉각적인 반복 호출로는 결과를 변경할 수 없습니다. 잠시 후 `Retry-After`에 표시된 간격이 지난 뒤 다시 시도하십시오.",
            "content": {
              "application/json": {
                "examples": {
                  "Backend-only resubmit throttled": {
                    "value": {
                      "detail": "This session was already resubmitted for backend-only features within the last 30 seconds; repeating it cannot change the outcome. Wait before resubmitting again."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "이메일 미리보기가 변경되었거나 만료되었습니다. 확인하기 전에 새 미리보기를 생성하세요. 세션 변경이나 이메일 전송은 발생하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Preview Changed": {
                    "summary": "영수증이 더 이상 일치하지 않거나 15분이 경과했습니다.",
                    "value": {
                      "detail": "This email preview changed or expired. Preview the message again before confirming."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-status/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"new_status\": \"Approved\",\n    \"comment\": \"All checks passed manual review\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_status(\n    \"11111111-2222-3333-4444-555555555555\",\n    new_status=\"Approved\",\n    comment=\"All checks passed manual review\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateStatus(\"11111111-2222-3333-4444-555555555555\", {\n  new_status: \"Approved\",\n  comment: \"All checks passed manual review\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateStatusParams{\n\tNewStatus: \"Approved\",\n\tComment:   didit.String(\"All checks passed manual review\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateStatus(\"11111111-2222-3333-4444-555555555555\", SessionsUpdateStatusParams.builder()\n        .newStatus(SessionsUpdateStatusParams.NewStatus.of(\"Approved\"))\n        .comment(\"All checks passed manual review\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateStatus('11111111-2222-3333-4444-555555555555', [\n    'new_status' => 'Approved',\n    'comment' => 'All checks passed manual review',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_status(\n  \"11111111-2222-3333-4444-555555555555\",\n  new_status: \"Approved\",\n  comment: \"All checks passed manual review\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateStatusAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdateStatusParams\n{\n    NewStatus = \"Approved\",\n    Comment = \"All checks passed manual review\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/id-verification/": {
      "post": {
        "summary": "신분증 인증 (문서 OCR + 사기 확인)",
        "description": "한 번의 호출로 신분증 문서를 OCR하고 문서 사기 검사를 실행합니다. 추출된 소지자 필드, 파싱된 MRZ, `Approved`/`Declined`/`In Review` `status`, 발견된 모든 문제를 설명하는 `warnings` 목록을 반환합니다. 220+개 국가 및 지역의 14,000+개 문서 유형을 지원합니다.\n\n**작동 방식.** 문서의 `front_image`(필수)와 양면 문서의 경우 `back_image`를 전송합니다. 문서의 네 모서리가 모두 보이는 자르지 않은 사진을 업로드하세요. 서비스가 문서를 직접 감지하고 정렬한 후 자르므로 미리 자르지 마십시오. 문서는 자동으로 분류되며(국가나 문서 유형을 직접 선언할 필요가 없음), 시각 영역은 OCR로 판독되고, MRZ 및 모든 바코드가 디코딩됩니다. 그런 다음 교차 검증을 통해 날짜, 번호 형식, MRZ 검사 숫자의 유효성을 확인하고 시각 영역과 MRZ를 비교합니다. `perform_document_liveness=true`인 경우 이미지를 추가로 검사하여 화면 재생, 인쇄된 사본, 인물 사진 변조 여부를 확인합니다.\n\n**결정 로직.** 적어도 하나의 경고가 거부로 처리되는 경우를 제외하면 `status`는 `Approved`입니다. 사기 및 중대한 실패 위험은 항상 거부됩니다: `DOCUMENT_EXPIRED`, `SCREEN_CAPTURE_DETECTED`, `PRINTED_COPY_DETECTED`, `PORTRAIT_MANIPULATION_DETECTED`, `PUBLIC_DOCUMENT_IMAGE_DETECTED` 및 추출 실패(`NAME_NOT_DETECTED`, `DATE_OF_BIRTH_NOT_DETECTED`, `DOCUMENT_NUMBER_NOT_DETECTED`). (`PORTRAIT_IMAGE_NOT_DETECTED`, `INVALID_DATE`, `MRZ_NOT_DETECTED`는 워크플로 세션에 존재하지만 이 독립 실행형 endpoint에서는 생성되지 않습니다. `COULD_NOT_DETECT_DOCUMENT_TYPE`은 앞면 이미지가 높은 신뢰도로 알려진 공식 문서 디자인과 일치하지 않을 때 여기서 반환되며 요청을 거부합니다.) 세 가지 위험 그룹은 `invalid_mrz_action`, `inconsistent_data_action`, `expiration_date_not_detected_action`을 통해 요청별로 설정할 수 있습니다(`DECLINE` 또는 `NO_ACTION`). 다른 모든 경고(예: `POSSIBLE_DUPLICATED_USER`)는 정보 제공용이며 그 자체로 거부되지 않습니다. `perform_document_liveness=true`(기본값)이고 위조 검사에서 사용 가능한 점수를 반환하지 않는 경우(공급자 실패, 200 외 응답, 또는 `status=\"ERR\"`인 HTTP 200 응답) 호출은 `Approved` 대신 `status: \"In Review\"` 및 `DOCUMENT_LIVENESS_NOT_COMPUTED` 경고(`log_type: \"warning\"`)와 함께 `200`을 반환합니다. 실행되지 않은 검사는 문서가 진짜라는 증거가 되지 않기 때문입니다. 이 에스컬레이션은 설정할 수 없으며 `Declined`를 절대 재정의하지 않습니다. `perform_document_liveness=false`인 경우 해당 검사는 건너뛰고 상태는 이전과 같이 나머지 경고를 따릅니다. 전혀 처리할 수 없는 문서는 `{\"error\": \"COULD_NOT_RECOGNIZE_DOCUMENT\"}`와 함께 `400`을 반환합니다. 판독할 수 있지만 문제가 있는 문서는 `status: \"Declined\"`와 함께 `200`을 반환하므로, HTTP 코드뿐만 아니라 항상 `id_verification.status` 및 `id_verification.warnings`를 확인하세요.\n\n**결제.** 각 `200` 응답은 신분증 인증 API 크레딧 1개를 소모합니다(요금제 크레딧 또는 충전 잔액에서 차감). 조직의 잔액으로 호출 비용을 충당할 수 없는 경우 endpoint는 이미지 처리가 시작되기 전에 크레딧 부족 오류와 함께 `403`을 반환합니다.\n\n**세션 지속성(`save_api_request`, 기본값 `true`).** `true`인 경우 호출은 API 유형 세션으로 유지됩니다. Business Console에 표시되고, 반환된 `request_id`는 `GET /v3/session/{sessionId}/decision/`에 전달할 수 있는 실제 세션 ID이며, 잘라낸 문서/인물 사진 이미지가 저장되어 수명이 짧은 미디어 URL(`https://<media-host>/ocr/...`)로 반환되고, 설정된 webhook endpoint로 `status.updated` webhook이 전송됩니다. `false`인 경우 아무것도 저장되지 않고, `request_id`는 일회성 연관 UUID이며, `portrait_image`/`front_image`/`back_image`는 base64로 인코딩된 JPEG 문자열로 인라인 반환됩니다.\n\n**샌드박스.** 샌드박스 API 키는 모든 처리 및 결제를 건너뜁니다. 요청 검증 후(잘못된 형식의 입력은 여전히 `400` 반환) endpoint는 정적 `Approved` 모의 payload(가상의 \"Sandbox User\" 미국 신분증)를 반환하며, 세션은 유지되지 않고 크레딧도 소모되지 않습니다.\n\n**인증.** 애플리케이션의 API 키를 `x-api-key` 헤더에 담아 전송하세요. 자격 증명이 누락되었거나 유효하지 않은 경우 `403`(`{\"detail\": \"You do not have permission to perform this action.\"}`)을 반환하며, 이 API는 절대 `401`을 반환하지 않습니다.\n\n**속도 제한.** 모든 POST/PATCH/DELETE endpoint에 걸쳐 API 키당 300건/분의 공유 쓰기 예산이 적용되며, 초과 시 `429`가 반환됩니다.",
        "operationId": "post_v3id-verification",
        "x-didit-sdk": {
          "resource": "id_verification",
          "method": "verify",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "front_image"
                ],
                "properties": {
                  "front_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "신분증 앞면입니다. 허용되는 확장자: `tiff`, `jpg`, `jpeg`, `png`, `webp`, `pdf`. 최대 업로드 크기: **10 MB**(더 큰 파일은 `400` 오류로 거부됨). PDF는 OCR 전에 이미지로 렌더링되며, 암호화된 PDF는 `front_image_password`가 필요합니다. 이미지는 자동으로 ~0.5 MB로 압축되고 EXIF 방향이 적용됩니다. 문서의 네 모서리가 모두 보이는 잘리지 않은 전체 캡처본을 업로드하세요."
                  },
                  "front_image_password": {
                    "type": "string",
                    "description": "`front_image`가 암호화된 PDF인 경우 복호화하기 위한 비밀번호입니다. 비밀번호 없이(또는 잘못된 비밀번호로) 암호화된 PDF를 전송하면 `400`이 반환됩니다.",
                    "writeOnly": true
                  },
                  "back_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "문서의 뒷면입니다. 문서에 뒷면이 있는 경우 항상 전송하십시오(많은 신분증은 뒷면에 MRZ나 바코드가 있습니다. 뒷면을 생략하면 응답에서 MRZ 및 뒷면 필드가 비어 있게 되며, 이 endpoint는 MRZ 누락 경고를 발생시키지 않습니다). `front_image`와 동일한 형식 및 크기 제한이 적용됩니다. 생략된 경우 응답의 `back_image` 및 뒷면 필드는 `null`이 됩니다."
                  },
                  "back_image_password": {
                    "type": "string",
                    "description": "`back_image`가 암호화된 PDF인 경우 복호화하기 위한 비밀번호입니다.",
                    "writeOnly": true
                  },
                  "perform_document_liveness": {
                    "type": "boolean",
                    "default": true,
                    "description": "두 이미지 모두에서 프레젠테이션 부정행위를 스크리닝합니다. 화면 재생(`SCREEN_CAPTURE_DETECTED`), 인쇄된 사본(`PRINTED_COPY_DETECTED`), 인물 사진 조작(`PORTRAIT_MANIPULATION_DETECTED`)을 감지합니다. 이 중 하나라도 해당되면 자동으로 거부됩니다. 기본적으로 활성화되어 있으며, 사기 스크리닝을 건너뛰고 지연 시간을 줄이려면 `false`로 설정하십시오. 활성화된 상태에서 공급자가 사용 가능한 점수를 반환하지 않으면 응답은 `Approved` 대신 `DOCUMENT_LIVENESS_NOT_COMPUTED` 경고와 함께 `In Review`가 됩니다.",
                    "example": true
                  },
                  "minimum_age": {
                    "type": "integer",
                    "nullable": true,
                    "default": null,
                    "minimum": 1,
                    "maximum": 120,
                    "description": "허용 및 유효성 검사(1–120)가 수행되지만 이 endpoint에서는 **현재 적용되지 않음** — 이 필드에서는 `MINIMUM_AGE_NOT_MET` 경고가 생성되지 않습니다. 반환된 `date_of_birth`/`age`를 기반으로 연령 규칙을 적용하거나 연령 제한이 있는 인증 세션 워크플로를 사용하십시오."
                  },
                  "expiration_date_not_detected_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "만료일을 읽을 수 없을 때(`EXPIRATION_DATE_NOT_DETECTED`) 수행할 작업입니다. 상당수의 신분증에 만료일이 인쇄되어 있지 않으므로 기본값은 `NO_ACTION`입니다. 참고: 이 옵션과 관계없이 *감지되었으나 이미 지난* 만료일은 항상 거부됩니다(`DOCUMENT_EXPIRED`)."
                  },
                  "invalid_mrz_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "DECLINE",
                    "description": "추출된 MRZ가 체크 디지트 유효성 검사에 실패할 때 수행할 작업입니다 (`MRZ_VALIDATION_FAILED`). MRZ가 누락된 경우 이 endpoint에서는 경고가 발생하지 않습니다. MRZ가 포함된 문서에만 해당합니다. 이 endpoint에서는 `REVIEW`가 지원되지 않으며 `400`을 반환합니다."
                  },
                  "inconsistent_data_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "DECLINE",
                    "description": "추출된 데이터 내부에 불일치가 있을 때 수행할 작업입니다: `DATA_INCONSISTENT`, `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME`(시각적 영역과 MRZ 불일치) 또는 `DOCUMENT_NAME_DIFFERENT_FROM_OTHER_APPROVED_DOCUMENTS`."
                  },
                  "critical_field_occlusion_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "DECLINE",
                    "description": "촬영본에서 식별 번호, 이름, 생년월일 또는 만료일과 같은 중요한 인쇄 필드가 물리적으로 가려진 경우(`CRITICAL_FIELD_OCCLUSION_DETECTED`) 수행할 작업입니다. 이 endpoint의 다른 문서 무결성 위험과 마찬가지로 기본적으로 거부됩니다. 보고서 대조에 필요한 번호를 가리는 것은 수정(redact)된 문서의 전형적인 형태이기 때문입니다. 가려진 필드에서 읽은 값은 추출 결과에서 제외되므로, 일반적으로 일치하는 `*_NOT_DETECTED` 경고가 함께 동반됩니다. 이 endpoint에서는 `REVIEW`가 지원되지 않으며 `400`을 반환합니다."
                  },
                  "document_or_personal_number_format_mismatch_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "번호가 해당 문서 유형에 대해 발급 기관이 사용하는 형식과 일치하지 않을 때(`DOCUMENT_NUMBER_FORMAT_MISMATCH`, `PERSONAL_NUMBER_FORMAT_MISMATCH`) 수행할 작업입니다. 기본값은 `NO_ACTION`으로, 상태를 변경하지 않고 경고만 보고합니다. 이 endpoint에서는 `REVIEW`가 지원되지 않으며 `400`을 반환합니다."
                  },
                  "preferred_characters": {
                    "type": "string",
                    "enum": [
                      "latin",
                      "non_latin"
                    ],
                    "default": "latin",
                    "description": "라틴 문자와 비라틴 문자(아랍어, 키릴 자모, CJK 등)가 모두 인쇄된 문서의 성명/주소 필드에 선호하는 문자 체계입니다. `latin`은 음차/라틴 문자로 표기된 값을 반환하고, `non_latin`은 현지 고유 문자 체계를 우선합니다."
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "`true`(기본값)인 경우 호출을 API 유형 세션으로 저장합니다. Business Console에서 확인할 수 있고 반환된 `request_id`를 사용하여 `GET /v3/session/{sessionId}/decision/`을 통해 조회할 수 있으며 `status.updated` webhook을 통해 알림이 전송되고 문서 이미지가 미디어 URL로 반환됩니다. `false`인 경우 아무것도 저장되지 않고 `request_id`는 일시적인 UUID이며 이미지는 base64 JPEG 문자열로 인라인 반환됩니다.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "저장된 세션에 저장되고 응답에 다시 반환되는 선택적 불투명 문자열(내부 사용자 ID, 이메일, UUID 등)입니다. API 호출을 자체 기록과 연관 짓고 나중에 세션을 필터링하는 데 사용합니다.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "세션과 함께 저장되고(`save_api_request=true`인 경우) 응답에 그대로 반환되는 선택적 JSON 객체입니다. multipart 요청에서는 JSON 인코딩된 문자열 필드(예: `metadata={\"flow\":\"onboarding\"}`)로 전송하십시오. 객체로 파싱됩니다.",
                    "example": {
                      "flow": "onboarding"
                    }
                  }
                }
              },
              "example": {
                "front_image": "(binary JPEG/PNG/PDF of the document front)",
                "back_image": "(binary JPEG/PNG/PDF of the document back)",
                "perform_document_liveness": true,
                "save_api_request": true,
                "vendor_data": "user-123",
                "metadata": {
                  "flow": "onboarding"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "문서가 처리되었습니다. `id_verification.status`는 `Approved`, `Declined` 또는 `In Review`입니다. 감지된 모든 문제는 `id_verification.warnings`에 항목별로 나열됩니다. 요청된 문서 라이브니스 검사에서 사용 가능한 결과가 생성되지 않은 경우(`DOCUMENT_LIVENESS_NOT_COMPUTED`) `In Review`가 반환됩니다. 문제가 있는 문서라도 `status: \"Declined\"`와 함께 `200`을 반환하므로 HTTP 코드뿐만 아니라 본문도 검사해야 합니다. `save_api_request=true`인 경우 `request_id`는 저장된 세션 ID이고 이미지 필드는 수명이 짧은 미디어 URL입니다. `save_api_request=false`인 경우 인라인 base64 JPEG 문자열입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Approved": {
                    "summary": "양면 신분증이 문제없이 판독됨(저장됨 — 이미지는 미디어 URL로 제공)",
                    "value": {
                      "request_id": "11d219ed-d59c-4b1d-8d65-9b933f12d5b8",
                      "id_verification": {
                        "status": "Approved",
                        "document_type": "Identity Card",
                        "document_subtype": "ID_CARD_GENERIC",
                        "document_number": "CBX164224",
                        "personal_number": "20446581H",
                        "portrait_image": "https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-portrait_image-8c2f.jpg?signature=...",
                        "front_image": "https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-front_image-4a1e.jpg?signature=...",
                        "back_image": "https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-back_image-77b0.jpg?signature=...",
                        "front_image_camera_front": null,
                        "back_image_camera_front": null,
                        "front_image_camera_front_face_match_score": null,
                        "back_image_camera_front_face_match_score": null,
                        "front_image_quality_score": {
                          "focus_score": 78.0,
                          "brightness_score": 83.2,
                          "brightness_issue": "ok",
                          "is_document_fully_visible": true,
                          "resolution_score": 40.7,
                          "overall_score": 70.2
                        },
                        "back_image_quality_score": {
                          "focus_score": 100.0,
                          "brightness_score": 95.6,
                          "brightness_issue": "ok",
                          "is_document_fully_visible": true,
                          "resolution_score": 43.0,
                          "overall_score": 84.4
                        },
                        "date_of_birth": "1980-01-13",
                        "age": 46,
                        "expiration_date": "2032-03-31",
                        "date_of_issue": "2022-03-31",
                        "issuing_state": "ESP",
                        "issuing_state_name": "Spain",
                        "first_name": "Julio Francisco",
                        "last_name": "Fores Sena",
                        "full_name": "Julio Francisco Fores Sena",
                        "gender": "M",
                        "address": "Brda. Urb. El Cardonal 0052 52 Po3 B,Taco,San Cristobal De La Laguna,Santa Cruz De Tenerife",
                        "formatted_address": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain",
                        "place_of_birth": "Valencia, Valencia",
                        "marital_status": "UNKNOWN",
                        "nationality": "ESP",
                        "extra_fields": {
                          "first_surname": "Fores",
                          "second_surname": "Sena"
                        },
                        "mrz": {
                          "surname": "FORES SENA",
                          "name": "JULIO FRANCISCO",
                          "country": "ESP",
                          "nationality": "ESP",
                          "birth_date": "800113",
                          "expiry_date": "320331",
                          "sex": "M",
                          "document_type": "ID",
                          "document_number": "CBX164224",
                          "optional_data": "20446581H",
                          "optional_data_2": "",
                          "birth_date_hash": "9",
                          "expiry_date_hash": "8",
                          "document_number_hash": "3",
                          "final_hash": "3",
                          "personal_number": "20446581H",
                          "warnings": [],
                          "errors": [],
                          "mrz_type": "TD1",
                          "mrz_string": "IDESPCBX164224320446581H<<<<<<\n8001139M3203318ESP<<<<<<<<<<<3\nFORES<SENA<<JULIO<FRANCISCO<<<",
                          "mrz_key": "CBX164224380011393203318"
                        },
                        "parsed_address": {
                          "street_1": "Avenida el Cardonal 52",
                          "street_2": "b",
                          "city": "La Laguna",
                          "region": "Canarias",
                          "country": "ES",
                          "postal_code": "38108",
                          "address_type": "Avenida",
                          "formatted_address": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain",
                          "raw_results": {
                            "address_components": [
                              {
                                "long_name": "b",
                                "short_name": "b",
                                "types": [
                                  "subpremise"
                                ]
                              },
                              {
                                "long_name": "52",
                                "short_name": "52",
                                "types": [
                                  "street_number"
                                ]
                              },
                              {
                                "long_name": "Avenida el Cardonal",
                                "short_name": "Av. el Cardonal",
                                "types": [
                                  "route"
                                ]
                              },
                              {
                                "long_name": "La Laguna",
                                "short_name": "La Laguna",
                                "types": [
                                  "locality",
                                  "political"
                                ]
                              },
                              {
                                "long_name": "Spain",
                                "short_name": "ES",
                                "types": [
                                  "country",
                                  "political"
                                ]
                              },
                              {
                                "long_name": "38108",
                                "short_name": "38108",
                                "types": [
                                  "postal_code"
                                ]
                              }
                            ],
                            "formatted_address": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain",
                            "geometry": {
                              "location": {
                                "lat": 28.4501161,
                                "lng": -16.3004407
                              },
                              "location_type": "ROOFTOP"
                            },
                            "types": [
                              "street_address",
                              "subpremise"
                            ]
                          },
                          "document_location": {
                            "latitude": 28.4501161,
                            "longitude": -16.3004407
                          },
                          "label": "Spain Identity Card Address",
                          "is_verified": true,
                          "category": "Residential"
                        },
                        "warnings": [],
                        "barcodes": []
                      },
                      "vendor_data": "user-123",
                      "metadata": {
                        "flow": "onboarding"
                      },
                      "created_at": "2026-06-12T02:21:56.013573+00:00"
                    }
                  },
                  "Declined - expired document": {
                    "summary": "만료된 신분증의 앞면만 업로드",
                    "value": {
                      "request_id": "f61681b8-9422-4378-ac3e-04c6a247fb45",
                      "id_verification": {
                        "status": "Declined",
                        "document_type": "Identity Card",
                        "document_subtype": "ID_CARD_GENERIC",
                        "document_number": "BNK123072",
                        "personal_number": "21771255F",
                        "portrait_image": "https://<media-host>/ocr/f61681b8-9422-4378-ac3e-04c6a247fb45-portrait_image-1d9a.jpg?signature=...",
                        "front_image": "https://<media-host>/ocr/f61681b8-9422-4378-ac3e-04c6a247fb45-front_image-5c2b.jpg?signature=...",
                        "back_image": null,
                        "front_image_camera_front": null,
                        "back_image_camera_front": null,
                        "front_image_camera_front_face_match_score": null,
                        "back_image_camera_front_face_match_score": null,
                        "front_image_quality_score": {
                          "focus_score": 100.0,
                          "brightness_score": 95.7,
                          "brightness_issue": "ok",
                          "is_document_fully_visible": true,
                          "resolution_score": 22.2,
                          "overall_score": 79.3
                        },
                        "back_image_quality_score": null,
                        "date_of_birth": "1997-01-30",
                        "age": 29,
                        "expiration_date": "2025-11-26",
                        "date_of_issue": null,
                        "issuing_state": "ESP",
                        "issuing_state_name": "Spain",
                        "first_name": "Lucia",
                        "last_name": "Marin Castro",
                        "full_name": "Lucia Marin Castro",
                        "gender": "F",
                        "address": null,
                        "formatted_address": null,
                        "place_of_birth": null,
                        "marital_status": "UNKNOWN",
                        "nationality": "ESP",
                        "extra_fields": {
                          "first_surname": "Marin",
                          "second_surname": "Castro"
                        },
                        "mrz": {},
                        "parsed_address": null,
                        "warnings": [
                          {
                            "risk": "DOCUMENT_EXPIRED",
                            "feature": "ID_VERIFICATION",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Document expired",
                            "long_description": "The document's expiration date has passed, rendering it no longer valid for use."
                          }
                        ],
                        "barcodes": []
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T02:25:48.117204+00:00"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "`save_api_request=true`일 때 유지된 세션 ID(`GET /v3/session/{sessionId}/decision/`와 함께 사용 가능), 그렇지 않으면 임시 상관관계 UUID입니다."
                    },
                    "id_verification": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined",
                            "In Review"
                          ],
                          "description": "어떤 경고도 거부로 이어지지 않고 요청된 문서 라이브니스 검사에서 사용 가능한 결과가 도출된 경우 `Approved`, 해당 요청 검사에서 사용 가능한 결과가 도출되지 않은 경우(`DOCUMENT_LIVENESS_NOT_COMPUTED`) `In Review`, 경고가 거부로 이어지는 경우 `Declined`가 됩니다. `warnings` 목록에 이유가 설명되어 있습니다."
                        },
                        "document_type": {
                          "type": "string",
                          "nullable": true,
                          "description": "감지된 문서 유형 표시 이름: `Identity Card`, `Passport`, `Driver's License`, `Residence Permit`, `Health Insurance Card` 또는 `Tax Card`. 문서를 분류할 수 없는 경우 `null`입니다.",
                          "example": "Identity Card"
                        },
                        "document_subtype": {
                          "type": "string",
                          "nullable": true,
                          "description": "사용 가능한 경우 세부 하위 유형(예: `ID_CARD_GENERIC`, `EPASSPORT`)입니다.",
                          "example": "ID_CARD_GENERIC"
                        },
                        "document_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "CBX164224"
                        },
                        "personal_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "일부 문서에 인쇄된 보조 개인/국가 식별 번호.",
                          "example": "20446581H"
                        },
                        "portrait_image": {
                          "type": "string",
                          "nullable": true,
                          "description": "문서에서 잘라낸 인물 사진입니다. `save_api_request=true`(기본값)인 경우 유효 기간이 짧은 미디어 URL(`https://<media-host>/ocr/...`)이며, `save_api_request=false`인 경우 인라인 base64 인코딩 JPEG 문자열입니다. 감지된 인물 사진이 없으면 `null`입니다."
                        },
                        "front_image": {
                          "type": "string",
                          "nullable": true,
                          "description": "정렬되어 잘라낸 문서 앞면 이미지입니다. 저장된 경우 미디어 URL이며, 그렇지 않은 경우 인라인 base64 JPEG입니다."
                        },
                        "back_image": {
                          "type": "string",
                          "nullable": true,
                          "description": "정렬되어 잘라낸 문서 뒷면 이미지입니다. `back_image`가 업로드되지 않은 경우 `null`입니다."
                        },
                        "front_image_camera_front": {
                          "type": "string",
                          "nullable": true,
                          "description": "이 endpoint에서는 항상 `null`입니다(카메라 캡처 인증 세션에서만 채워짐)."
                        },
                        "back_image_camera_front": {
                          "type": "string",
                          "nullable": true,
                          "description": "이 endpoint에서는 항상 `null`입니다."
                        },
                        "front_image_camera_front_face_match_score": {
                          "type": "number",
                          "nullable": true,
                          "description": "이 endpoint에서는 항상 `null`입니다."
                        },
                        "back_image_camera_front_face_match_score": {
                          "type": "number",
                          "nullable": true,
                          "description": "이 endpoint에서는 항상 `null`입니다."
                        },
                        "front_image_quality_score": {
                          "type": "object",
                          "nullable": true,
                          "description": "업로드된 이미지의 촬영 품질 진단 정보(해당 면이 제공되지 않았거나 점수 산정에 실패한 경우 `null`). 모든 점수는 0–100입니다.",
                          "properties": {
                            "focus_score": {
                              "type": "number",
                              "format": "float",
                              "description": "문서 크롭 영역의 선명도입니다(높을수록 더 선명함)."
                            },
                            "brightness_score": {
                              "type": "number",
                              "format": "float",
                              "description": "노출 품질(높을수록 좋음)."
                            },
                            "brightness_issue": {
                              "type": "string",
                              "nullable": true,
                              "description": "노출이 적절한 경우 `ok`이며, 그렇지 않은 경우 감지된 문제(예: 너무 어두움 / 너무 밝음)가 표시됩니다."
                            },
                            "is_document_fully_visible": {
                              "type": "boolean",
                              "nullable": true,
                              "description": "문서의 네 모서리가 모두 프레임 안에 있는지 여부입니다."
                            },
                            "resolution_score": {
                              "type": "number",
                              "format": "float",
                              "description": "문서 영역의 유효 해상도입니다."
                            },
                            "overall_score": {
                              "type": "number",
                              "format": "float",
                              "description": "종합 품질 점수입니다."
                            }
                          }
                        },
                        "back_image_quality_score": {
                          "type": "object",
                          "nullable": true,
                          "description": "업로드된 이미지의 촬영 품질 진단 정보(해당 면이 제공되지 않았거나 점수 산정에 실패한 경우 `null`). 모든 점수는 0–100입니다.",
                          "properties": {
                            "focus_score": {
                              "type": "number",
                              "format": "float",
                              "description": "문서 크롭 영역의 선명도입니다(높을수록 더 선명함)."
                            },
                            "brightness_score": {
                              "type": "number",
                              "format": "float",
                              "description": "노출 품질(높을수록 좋음)."
                            },
                            "brightness_issue": {
                              "type": "string",
                              "nullable": true,
                              "description": "노출이 적절한 경우 `ok`이며, 그렇지 않은 경우 감지된 문제(예: 너무 어두움 / 너무 밝음)가 표시됩니다."
                            },
                            "is_document_fully_visible": {
                              "type": "boolean",
                              "nullable": true,
                              "description": "문서의 네 모서리가 모두 프레임 안에 있는지 여부입니다."
                            },
                            "resolution_score": {
                              "type": "number",
                              "format": "float",
                              "description": "문서 영역의 유효 해상도입니다."
                            },
                            "overall_score": {
                              "type": "number",
                              "format": "float",
                              "description": "종합 품질 점수입니다."
                            }
                          }
                        },
                        "date_of_birth": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "1980-01-13"
                        },
                        "age": {
                          "type": "integer",
                          "nullable": true,
                          "description": "`date_of_birth`를 기준으로 계산된 명의자의 만 나이입니다.",
                          "example": 46
                        },
                        "expiration_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "2032-03-31"
                        },
                        "date_of_issue": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "2022-03-31"
                        },
                        "issuing_state": {
                          "type": "string",
                          "nullable": true,
                          "description": "발급 국가(ISO 3166-1 alpha-3)입니다.",
                          "example": "ESP"
                        },
                        "issuing_state_name": {
                          "type": "string",
                          "nullable": true,
                          "example": "Spain"
                        },
                        "first_name": {
                          "type": "string",
                          "nullable": true,
                          "example": "Julio Francisco"
                        },
                        "last_name": {
                          "type": "string",
                          "nullable": true,
                          "example": "Fores Sena"
                        },
                        "full_name": {
                          "type": "string",
                          "nullable": true,
                          "example": "Julio Francisco Fores Sena"
                        },
                        "gender": {
                          "type": "string",
                          "nullable": true,
                          "description": "인쇄/감지되지 않은 경우 `M`, `F` 또는 `null`.",
                          "example": "M"
                        },
                        "address": {
                          "type": "string",
                          "nullable": true,
                          "description": "문서에 인쇄된 그대로의 주소입니다."
                        },
                        "formatted_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "`address`의 지오코딩되고 정규화된 버전입니다."
                        },
                        "place_of_birth": {
                          "type": "string",
                          "nullable": true,
                          "example": "Valencia, Valencia"
                        },
                        "marital_status": {
                          "type": "string",
                          "nullable": true,
                          "description": "문서에 혼인 여부가 인쇄되어 있지 않은 한 `UNKNOWN`입니다.",
                          "example": "UNKNOWN"
                        },
                        "nationality": {
                          "type": "string",
                          "nullable": true,
                          "description": "명의자 국적(ISO 3166-1 alpha-3)입니다.",
                          "example": "ESP"
                        },
                        "extra_fields": {
                          "type": "object",
                          "nullable": true,
                          "additionalProperties": true,
                          "description": "전용 열이 없는 문서별 추가 항목입니다(예: 스페인 신분증의 `first_surname`/`second_surname`, 운전면허증의 면허 종별)."
                        },
                        "mrz": {
                          "type": "object",
                          "description": "파싱된 기계 판독 영역입니다. 문서에 MRZ가 없거나 읽을 수 없는 경우 **빈 객체**(`{}`)가 반환되며, 이 경우 `warnings` 목록도 확인하십시오. MRZ 내부의 날짜는 원본 `YYMMDD` 형식을 사용합니다.",
                          "properties": {
                            "surname": {
                              "type": "string",
                              "example": "FORES SENA"
                            },
                            "name": {
                              "type": "string",
                              "example": "JULIO FRANCISCO"
                            },
                            "country": {
                              "type": "string",
                              "description": "발급 국가(ISO 3166-1 alpha-3)입니다.",
                              "example": "ESP"
                            },
                            "nationality": {
                              "type": "string",
                              "description": "명의자 국적(ISO 3166-1 alpha-3)입니다.",
                              "example": "ESP"
                            },
                            "birth_date": {
                              "type": "string",
                              "description": "MRZ의 원시 생년월일(`YYMMDD`)입니다.",
                              "example": "800113"
                            },
                            "expiry_date": {
                              "type": "string",
                              "description": "MRZ의 원시 만료일(`YYMMDD`)입니다.",
                              "example": "320331"
                            },
                            "sex": {
                              "type": "string",
                              "example": "M"
                            },
                            "document_type": {
                              "type": "string",
                              "description": "MRZ 문서 유형 코드(예: `ID`, `P`).",
                              "example": "ID"
                            },
                            "document_number": {
                              "type": "string",
                              "example": "CBX164224"
                            },
                            "optional_data": {
                              "type": "string",
                              "nullable": true,
                              "example": "20446581H"
                            },
                            "optional_data_2": {
                              "type": "string",
                              "nullable": true,
                              "example": ""
                            },
                            "birth_date_hash": {
                              "type": "string",
                              "description": "생년월일에 대한 MRZ 체크 디지트.",
                              "example": "9"
                            },
                            "expiry_date_hash": {
                              "type": "string",
                              "description": "만료일에 대한 MRZ 체크 디지트.",
                              "example": "8"
                            },
                            "document_number_hash": {
                              "type": "string",
                              "description": "문서 번호에 대한 MRZ 체크 디지트.",
                              "example": "3"
                            },
                            "final_hash": {
                              "type": "string",
                              "description": "복합 MRZ 체크 디지트입니다.",
                              "example": "3"
                            },
                            "personal_number": {
                              "type": "string",
                              "nullable": true,
                              "example": "20446581H"
                            },
                            "warnings": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "치명적이지 않은 MRZ 파싱 경고."
                            },
                            "errors": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "MRZ 체크 디지트/파싱 오류. 오류가 비어 있지 않으면 `MRZ_VALIDATION_FAILED` 경고로 나타납니다."
                            },
                            "mrz_type": {
                              "type": "string",
                              "description": "MRZ 레이아웃: `TD1`(신분증, 3줄), `TD2` 또는 `TD3`(여권, 2줄).",
                              "example": "TD1"
                            },
                            "mrz_string": {
                              "type": "string",
                              "description": "판독된 원시 MRZ 텍스트이며, 줄은 `\\n`으로 구분됩니다."
                            },
                            "mrz_key": {
                              "type": "string",
                              "description": "교차 확인에 사용되는 복합 키(문서 번호 + 체크 디지트)입니다."
                            }
                          }
                        },
                        "parsed_address": {
                          "type": "object",
                          "nullable": true,
                          "description": "`address`의 구조화된 지오코딩 세부 정보입니다. 문서에 주소가 없거나 파싱할 수 없는 경우 `null`입니다.",
                          "properties": {
                            "street_1": {
                              "type": "string",
                              "nullable": true,
                              "example": "Avenida el Cardonal 52"
                            },
                            "street_2": {
                              "type": "string",
                              "nullable": true,
                              "example": "b"
                            },
                            "city": {
                              "type": "string",
                              "nullable": true,
                              "example": "La Laguna"
                            },
                            "region": {
                              "type": "string",
                              "nullable": true,
                              "example": "Canarias"
                            },
                            "country": {
                              "type": "string",
                              "nullable": true,
                              "description": "ISO 3166-1 alpha-2 국가 코드입니다.",
                              "example": "ES"
                            },
                            "postal_code": {
                              "type": "string",
                              "nullable": true,
                              "example": "38108"
                            },
                            "address_type": {
                              "type": "string",
                              "nullable": true,
                              "example": "Avenida"
                            },
                            "formatted_address": {
                              "type": "string",
                              "nullable": true,
                              "description": "표준 지오코딩 주소 문자열입니다.",
                              "example": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain"
                            },
                            "raw_results": {
                              "type": "object",
                              "additionalProperties": true,
                              "description": "고급 소비자를 위한 원시 지오코딩 payload(`address_components`, `geometry.location`, `place_id`, …)입니다."
                            },
                            "document_location": {
                              "type": "object",
                              "nullable": true,
                              "properties": {
                                "latitude": {
                                  "type": "number"
                                },
                                "longitude": {
                                  "type": "number"
                                }
                              },
                              "description": "문서 주소의 지오코딩된 좌표입니다."
                            },
                            "label": {
                              "type": "string",
                              "nullable": true,
                              "description": "주소를 읽어온 문서 필드입니다.",
                              "example": "Spain Identity Card Address"
                            },
                            "is_verified": {
                              "type": "boolean",
                              "description": "지오코딩을 통해 주소가 존재하는 것으로 확인되었는지 여부입니다."
                            },
                            "category": {
                              "type": "string",
                              "nullable": true,
                              "description": "주소 카테고리(예: `Residential`, `Commercial`).",
                              "example": "Residential"
                            }
                          }
                        },
                        "warnings": {
                          "type": "array",
                          "description": "문제없이 승인된 경우 비어 있습니다. 각 항목은 감지된 하나의 위험을 설명합니다. `log_type: \"error\"`인 항목은 `status`를 `Declined`로 설정하고, `DOCUMENT_LIVENESS_NOT_COMPUTED`(`log_type: \"warning\"`)는 `In Review`로 설정합니다.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "description": "기계 판독 가능한 위험 코드입니다. 항상 거부되는 위험: `DOCUMENT_EXPIRED`, `MINIMUM_AGE_NOT_MET`, `PORTRAIT_IMAGE_NOT_DETECTED`, `SCREEN_CAPTURE_DETECTED`, `PRINTED_COPY_DETECTED`, `PORTRAIT_MANIPULATION_DETECTED`, `PUBLIC_DOCUMENT_IMAGE_DETECTED`, `INVALID_DATE`, `COULD_NOT_RECOGNIZE_DOCUMENT`(400 전용, 경고로 처리되지 않음), `DOCUMENT_NUMBER_NOT_DETECTED`, `COULD_NOT_DETECT_DOCUMENT_TYPE`, `NAME_NOT_DETECTED`, `DATE_OF_BIRTH_NOT_DETECTED`. 요청 옵션에 의해 제어됨: `MRZ_NOT_DETECTED` / `MRZ_VALIDATION_FAILED`(`invalid_mrz_action`), `DATA_INCONSISTENT` / `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` / `DOCUMENT_NAME_DIFFERENT_FROM_OTHER_APPROVED_DOCUMENTS`(`inconsistent_data_action`), `EXPIRATION_DATE_NOT_DETECTED`(`expiration_date_not_detected_action`). 기타 위험(예: `POSSIBLE_DUPLICATED_USER`)은 정보 제공용입니다. `DOCUMENT_LIVENESS_NOT_COMPUTED`는 `perform_document_liveness=true`이지만 위조 확인에서 사용할 수 있는 점수를 반환하지 못했을 때 발생하며, `status`를 `In Review`로 설정합니다. `COULD_NOT_DETECT_DOCUMENT_TYPE`은 문서 앞면이 알려진 공식 문서 디자인과 높은 신뢰도로 일치하지 않을 때도 반환되며, 예를 들어 편집되었거나 컴퓨터로 생성된 문서 또는 아직 지원되지 않는 디자인인 경우가 해당합니다.",
                                "example": "DOCUMENT_EXPIRED"
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "ID_VERIFICATION"
                                ],
                                "description": "경고를 발생시킨 기능입니다. 이 endpoint에서는 항상 `ID_VERIFICATION`입니다."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "일부 위험에 대한 추가 컨텍스트(예: `POSSIBLE_DUPLICATED_USER`에는 `duplicated_session_id` 포함)이며, 대부분의 경우 `null`입니다."
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error",
                                  "warning",
                                  "information"
                                ],
                                "description": "심각도입니다. `error` 경고는 `status`를 `Declined`로 변경합니다. `warning`(요청된 위변조 검사에서 사용 가능한 점수가 나오지 않았을 때 발생하는 `DOCUMENT_LIVENESS_NOT_COMPUTED`만 해당)은 `status`를 `In Review`로 변경합니다. `information` 항목은 참고용이며 상태를 변경하지 않습니다."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "사람이 읽을 수 있는 한 줄의 위험 요약입니다."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "위험에 대한 사람이 읽기 쉬운 설명입니다."
                              }
                            }
                          }
                        },
                        "barcodes": {
                          "type": "array",
                          "description": "문서에서 디코딩된 바코드입니다(PDF417, QR 등). 문서에 바코드가 없거나 읽을 수 없는 경우 비어 있습니다.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "description": "바코드 유형입니다(예: `PDF417`, `QR_CODE`, `UNKNOWN`)."
                              },
                              "position": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "이미지 내 바코드 위치(사용 가능한 경우)."
                              },
                              "data": {
                                "type": "string",
                                "description": "디코딩된 payload입니다."
                              },
                              "data_raw": {
                                "type": "string",
                                "description": "다른 경우, 원시(디코딩되지 않은) payload입니다."
                              },
                              "side": {
                                "type": "string",
                                "nullable": true,
                                "description": "`front` 또는 `back`."
                              }
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "전송한 `vendor_data`의 에코 값 또는 `null`입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "전송한 `metadata` 객체의 에코 값 또는 `null`입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "응답이 생성된 시점의 ISO 8601 타임스탬프(UTC)입니다."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 또는 처리 오류입니다. 필드 수준의 문제는 DRF의 표준 엔벨로프(문제가 발생한 필드당 하나의 메시지 배열)를 반환합니다. 암호화된 PDF 문제는 `{\"detail\": ...}`를 반환합니다. 문서를 전혀 인식할 수 없는 문서 이미지는 `{\"error\": \"COULD_NOT_RECOGNIZE_DOCUMENT\"}`를 반환합니다. PDF 업로드는 추가로 \"The submitted PDF file is corrupted or invalid.\" 또는 페이지 없음 오류로 실패할 수 있습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing front image": {
                    "summary": "폼 데이터에 `front_image`가 포함되지 않음",
                    "value": {
                      "front_image": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Unsupported file extension": {
                    "summary": "tiff/jpg/jpeg/png/webp/pdf 이외의 파일 확장자",
                    "value": {
                      "front_image": [
                        "File extension “txt” is not allowed. Allowed extensions are: tiff, jpg, jpeg, png, webp, pdf."
                      ]
                    }
                  },
                  "File too large": {
                    "summary": "업로드가 10MB 제한을 초과함",
                    "value": {
                      "front_image": [
                        "File size should not exceed 10 MB"
                      ]
                    }
                  },
                  "Invalid option value": {
                    "summary": "옵션은 DECLINE 또는 NO_ACTION만 허용합니다.",
                    "value": {
                      "invalid_mrz_action": [
                        "\"REVIEW\" is not a valid choice."
                      ]
                    }
                  },
                  "Encrypted PDF": {
                    "summary": "필수 비밀번호 없이 업로드된 PDF입니다.",
                    "value": {
                      "detail": "The PDF is encrypted. Please upload a decrypted PDF or a photo instead."
                    }
                  },
                  "Wrong PDF password": {
                    "summary": "`front_image_password` / `back_image_password`로 PDF를 복호화할 수 없음",
                    "value": {
                      "detail": "The PDF password is incorrect. Please provide the correct password."
                    }
                  },
                  "Document not recognized": {
                    "summary": "이미지에서 신분증을 감지할 수 없습니다",
                    "value": {
                      "error": "COULD_NOT_RECOGNIZE_DOCUMENT"
                    }
                  },
                  "PDF conversion failure": {
                    "summary": "업로드된 PDF를 이미지로 변환할 수 없습니다",
                    "value": {
                      "error": "Failed to convert front image PDF."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었거나 호출한 조직의 잔액이 호출 비용을 충당할 수 없을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 키가 누락된 경우 `{\"detail\": ...}`과 함께 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 크레딧이 부족한 경우 어떠한 이미지 처리도 진행되기 전에 `{\"error\": ...}`과 함께 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 호출 비용을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/DocumentProcessingBusy"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/id-verification/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'front_image=@./id_front.jpg' \\\n  -F 'back_image=@./id_back.jpg' \\\n  -F 'perform_document_liveness=true' \\\n  -F 'save_api_request=true' \\\n  -F 'vendor_data=user-123'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_verification.verify(\n    front_image=open(\"front_image.jpg\", \"rb\"),\n    back_image=open(\"back_image.jpg\", \"rb\"),\n    perform_document_liveness=True,\n    save_api_request=True,\n    vendor_data=\"user-123\",\n    metadata={\"flow\": \"onboarding\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idVerification.verify({\n  front_image: await fileFromPath(\"front_image.jpg\"),\n  back_image: await fileFromPath(\"back_image.jpg\"),\n  perform_document_liveness: true,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"onboarding\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDVerification.Verify(ctx, didit.IDVerificationVerifyParams{\n\tFrontImage:              didit.FileFromPath(\"front_image.jpg\"),\n\tBackImage:               didit.Some(didit.FileFromPath(\"back_image.jpg\")),\n\tPerformDocumentLiveness: didit.Bool(true),\n\tSaveAPIRequest:          didit.Bool(true),\n\tVendorData:              didit.String(\"user-123\"),\n\tMetadata:                didit.Some(map[string]any{\"flow\": \"onboarding\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.IdVerificationVerifyParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idVerification().verify(IdVerificationVerifyParams.builder()\n        .frontImage(Path.of(\"front_image.jpg\"))\n        .backImage(Path.of(\"back_image.jpg\"))\n        .performDocumentLiveness(true)\n        .saveApiRequest(true)\n        .vendorData(\"user-123\")\n        .metadata(Map.of(\"flow\", \"onboarding\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idVerification->verify([\n    'front_image' => File::fromPath('front_image.jpg'),\n    'back_image' => File::fromPath('back_image.jpg'),\n    'perform_document_liveness' => true,\n    'save_api_request' => true,\n    'vendor_data' => 'user-123',\n    'metadata' => ['flow' => 'onboarding'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_verification.verify(\n  front_image: Pathname(\"front_image.jpg\"),\n  back_image: Pathname(\"back_image.jpg\"),\n  perform_document_liveness: true,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"onboarding\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdVerification.VerifyAsync(new IdVerificationVerifyParams\n{\n    FrontImage = FileUpload.FromPath(\"front_image.jpg\"),\n    BackImage = FileUpload.FromPath(\"back_image.jpg\"),\n    PerformDocumentLiveness = true,\n    SaveApiRequest = true,\n    VendorData = \"user-123\",\n    Metadata = new Dictionary<string, object> { [\"flow\"] = \"onboarding\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/face-match/": {
      "post": {
        "summary": "얼굴 대조",
        "description": "두 얼굴 이미지를 비교(1:1)하여 유사도 `score`(0–100)와 `Approved`/`Declined` `status`를 반환합니다.\n\n**작동 방식.** 두 이미지는 생체 인식 모델에 의해 디코딩 및 분석되며(캡처가 옆으로 누워 있거나 뒤집혀 있을 수 있는 경우 `rotate_image=true` 설정), 두 얼굴 간의 유사도 점수가 계산됩니다. 점수가 `face_match_score_decline_threshold`(기본값 `30`)를 **초과**하면 `status: \"Approved\"`를 반환하고, 이하이면 `LOW_FACE_MATCH_SIMILARITY` 경고와 함께 `Declined`를 반환합니다. 얼굴 쌍의 점수를 전혀 산출할 수 없는 경우에도 호출은 `200`과 함께 `status: \"Declined\"` 및 `NO_REFERENCE_IMAGE` 경고를 반환합니다. 기본 저장 경로에서는 `score`가 `null`이고, `save_api_request=false`인 경우 `0`입니다. 최상의 결과를 위해 이미지당 선명한 정면 얼굴 하나를 제출하세요.\n\n**결제.** 각 `200` 응답은 얼굴 대조 API 크레딧 1개를 소모합니다(요금제 크레딧 또는 충전 잔액에서 차감). 조직의 잔액으로 호출 비용을 충당할 수 없는 경우, endpoint는 이미지 처리를 시작하기 전에 크레딧 부족 오류와 함께 `403`을 반환합니다.\n\n**세션 지속성(`save_api_request`, 기본값 `true`).** `true`인 경우 호출이 API 유형 세션으로 지속 저장됩니다. Business Console에 표시되고, 반환된 `request_id`는 `GET /v3/session/{sessionId}/decision/`에 전달할 수 있는 실제 세션 id이며, 두 이미지는 세션의 얼굴 대조 소스/타겟 이미지로 저장되고, 설정된 webhook endpoint로 `status.updated` webhook이 전송됩니다. `false`인 경우 아무것도 저장되지 않으며 `request_id`는 나중에 조회할 수 없는 일회성 상관관계 UUID가 됩니다.\n\n**얼굴 검색 인덱스.** 이 endpoint는 얼굴 검색 인덱스에 얼굴을 등록하지 않으며 차단 목록 또는 중복 스크리닝을 실행하지 않습니다. 이러한 작업에는 `POST /v3/passive-liveness/` 또는 `POST /v3/face-search/`를 사용하세요.\n\n**샌드박스.** 샌드박스 API 키는 모든 처리와 결제를 건너뜁니다. 요청 유효성 검사 후(형식이 잘못된 입력은 여전히 `400` 반환), endpoint는 정적 `Approved` 모의 payload를 반환하며 세션이 지속 저장되지 않고 크레딧도 소모되지 않습니다.\n\n**인증.** 애플리케이션의 API 키를 `x-api-key` 헤더에 담아 전송하세요. 자격 증명이 누락되었거나 유효하지 않은 경우 `403`(`{\"detail\": \"You do not have permission to perform this action.\"}`)을 반환합니다. 이 API는 `401`을 반환하지 않습니다.\n\n**속도 제한.** 모든 POST/PATCH/DELETE endpoint에 걸쳐 API 키당 분당 300개의 쓰기 요청 예산이 공유되며, 이를 초과하면 `429`를 반환합니다.",
        "operationId": "post_v3face-match",
        "x-didit-sdk": {
          "resource": "face_match",
          "method": "compare",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "user_image",
                  "ref_image"
                ],
                "properties": {
                  "user_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "인증할 실제 얼굴 또는 후보 얼굴 이미지(예: 셀피). 주체의 얼굴이 선명하게 보이고 조명이 밝은 단일 정면 사진을 제출하십시오. 허용되는 확장자: `tiff`, `jpg`, `jpeg`, `png`, `webp`. 최대 업로드 크기: **5 MB**(더 큰 파일은 `400`으로 거부됨). 이미지는 처리 전에 자동으로 약 0.5 MB로 압축되므로 초고해상도 이미지가 정확도를 향상시키지는 않습니다."
                  },
                  "ref_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "대조할 기준 얼굴 이미지입니다(예: 신분증 문서 사진 또는 이전에 등록된 사진). `user_image`와 동일한 형식 및 크기 제한이 적용됩니다."
                  },
                  "face_match_score_decline_threshold": {
                    "type": "number",
                    "format": "float",
                    "default": 30,
                    "minimum": 0,
                    "maximum": 100,
                    "description": "응답 `status`를 결정하는 유사도 임계값(0–100)입니다. 계산된 점수가 이 값 **이하**이면 `status`가 `Declined`로 설정되고 `LOW_FACE_MATCH_SIMILARITY` 경고가 추가됩니다. 점수가 이 값보다 엄격히 높으면 `Approved`가 반환됩니다. 기본값 `30`은 허용적인 편입니다. 보다 엄격한 인증을 원하시면 이 값을 높이십시오(예: `50`–`60`). 0–100 범위를 벗어나는 값은 `400`을 반환합니다.",
                    "example": 50
                  },
                  "rotate_image": {
                    "type": "boolean",
                    "default": false,
                    "description": "`true`인 경우 서비스가 입력 이미지들을 90도 단위(0, 90, 180, 270)로 시도하고 최적의 얼굴 감지 결과를 내는 방향을 사용합니다. EXIF 방향 정보가 누락된 모바일 촬영에 유용합니다. 지연 시간이 추가되므로 똑바른 이미지를 보장할 수 없는 경우에만 활성화하십시오.",
                    "example": false
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "`true`(기본값)인 경우 호출을 API 유형 세션으로 저장합니다 — Business Console에서 확인할 수 있고 반환된 `request_id`를 사용하여 `GET /v3/session/{sessionId}/decision/`을 통해 조회할 수 있으며 `status.updated` webhook을 통해 알림이 전송됩니다. `false`인 경우 아무것도 저장되지 않으며 `request_id`는 응답 상관관계 식별 전용의 일시적인 UUID입니다.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "저장된 세션에 저장되고 응답에 다시 반환되는 선택적 불투명 문자열(내부 사용자 ID, 이메일, UUID 등)입니다. API 호출을 자체 기록과 연관 짓고 나중에 세션을 필터링하는 데 사용합니다.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "세션과 함께 저장되고(`save_api_request=true`인 경우) 응답에 그대로 반환되는 선택적 JSON 객체입니다. multipart 요청에서는 JSON 인코딩된 문자열 필드(예: `metadata={\"flow\":\"login\"}`)로 전송하십시오. 객체로 파싱됩니다.",
                    "example": {
                      "flow": "login",
                      "device_id": "abc123"
                    }
                  }
                }
              },
              "example": {
                "user_image": "(binary JPEG/PNG of the live selfie)",
                "ref_image": "(binary JPEG/PNG of the reference photo)",
                "face_match_score_decline_threshold": 50,
                "rotate_image": false,
                "save_api_request": true,
                "vendor_data": "user-123",
                "metadata": {
                  "flow": "login"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "얼굴 대조가 계산되었습니다. `face_match.score`는 0–100 범위의 부동 소수점 수이며 소수점 이하 두 자리까지 표시됩니다. 점수가 `face_match_score_decline_threshold`를 엄격히 초과하면 `status`는 `Approved`이고, 그렇지 않으면 설명 경고와 함께 `Declined`입니다. 유사도가 낮거나 점수를 매길 수 없는 쌍이라도 `200`을 반환하므로 HTTP 코드뿐만 아니라 `face_match.status` 및 `face_match.warnings`를 확인하십시오. `save_api_request=true`인 경우, `request_id`는 저장된 세션 ID입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Approved": {
                    "summary": "동일 인물 — 임계값을 초과하는 점수",
                    "value": {
                      "request_id": "f9f5a777-8002-44c6-baaf-128bcfd6e226",
                      "face_match": {
                        "status": "Approved",
                        "score": 99.41,
                        "user_image": {
                          "entities": [
                            {
                              "bbox": [
                                661,
                                728,
                                1688,
                                2188
                              ],
                              "confidence": 0.732973,
                              "age": 26.91,
                              "gender": "male",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "ref_image": {
                          "entities": [
                            {
                              "bbox": [
                                653,
                                745,
                                1691,
                                2185
                              ],
                              "confidence": 0.722082,
                              "age": 27.0,
                              "gender": "male",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "warnings": []
                      },
                      "vendor_data": "user-123",
                      "metadata": {
                        "flow": "login"
                      },
                      "created_at": "2026-06-12T01:04:42.763237+00:00"
                    }
                  },
                  "Declined - low similarity": {
                    "summary": "거부 임계값 이하의 점수",
                    "value": {
                      "request_id": "7cdda24e-311a-46d3-a3bb-e5d9b564ce73",
                      "face_match": {
                        "status": "Declined",
                        "score": 24.87,
                        "user_image": {
                          "entities": [
                            {
                              "bbox": [
                                661,
                                728,
                                1688,
                                2188
                              ],
                              "confidence": 0.732973,
                              "age": 26.91,
                              "gender": "male",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "ref_image": {
                          "entities": [
                            {
                              "bbox": [
                                156,
                                234,
                                679,
                                898
                              ],
                              "confidence": 0.717775,
                              "age": 41.2,
                              "gender": "male",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "warnings": [
                          {
                            "risk": "LOW_FACE_MATCH_SIMILARITY",
                            "feature": "FACEMATCH",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Low face match similarity",
                            "long_description": "The facial features of the provided image don't closely match the reference image, suggesting a potential identity mismatch."
                          }
                        ]
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T01:08:19.859116+00:00"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "`save_api_request=true`일 때 유지된 세션 ID(`GET /v3/session/{sessionId}/decision/`와 함께 사용 가능), 그렇지 않으면 임시 상관관계 UUID입니다."
                    },
                    "face_match": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined"
                          ],
                          "description": "유사도 점수가 `face_match_score_decline_threshold`를 엄격히 초과하고 점수를 계산할 수 있었던 경우 `Approved`, 그렇지 않은 경우 `Declined`(경고에 이유가 설명됨)."
                        },
                        "score": {
                          "type": "number",
                          "format": "float",
                          "nullable": true,
                          "minimum": 0,
                          "maximum": 100,
                          "description": "0부터 100까지의 유사도 점수로, 두 이미지가 동일인을 묘사하는지에 대한 모델의 신뢰도입니다. `save_api_request`가 true인 경우에만 소수점 둘째 자리로 반올림되며, `save_api_request=false`인 경우 원시 float 값이 반환됩니다. 점수를 매길 수 있는 얼굴 쌍이 없는 경우(기본값 `save_api_request=true` 적용 시) `null`입니다. `save_api_request=false`인 경우 동일한 상태가 `score: 0`으로 나타날 수 있습니다. 어느 경우든 `NO_REFERENCE_IMAGE` 경고가 표시되며 `status`는 `Declined`가 됩니다.",
                          "example": 99.41
                        },
                        "user_image": {
                          "type": "object",
                          "description": "분석된 이미지들에 대한 얼굴 감지 결과입니다.",
                          "properties": {
                            "entities": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "bbox": {
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    },
                                    "minItems": 4,
                                    "maxItems": 4,
                                    "description": "처리된 이미지에서 `[x_min, y_min, x_max, y_max]` 픽셀 좌표로 표시된 감지된 얼굴의 경계 상자입니다.",
                                    "example": [
                                      661,
                                      728,
                                      1688,
                                      2188
                                    ]
                                  },
                                  "confidence": {
                                    "type": "number",
                                    "format": "float",
                                    "minimum": 0,
                                    "maximum": 1,
                                    "description": "얼굴 감지 신뢰도(0–1).",
                                    "example": 0.732973
                                  },
                                  "age": {
                                    "type": "number",
                                    "format": "float",
                                    "description": "감지된 얼굴의 모델 추정 연령(세 단위)입니다. 정보 제공용일 뿐이며 얼굴 대조 결정에는 영향을 미치지 않습니다.",
                                    "example": 26.91
                                  },
                                  "gender": {
                                    "type": "string",
                                    "description": "감지된 얼굴의 모델 예측 성별(`male` 또는 `female`)입니다. 정보 제공용입니다.",
                                    "example": "male"
                                  },
                                  "race": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "예약된 필드 — 이 endpoint의 응답에서는 항상 `null`입니다.",
                                    "example": null
                                  }
                                }
                              },
                              "description": "감지된 얼굴당 항목 1개입니다."
                            },
                            "best_angle": {
                              "type": "integer",
                              "description": "가장 우수한 얼굴 감지를 생성한 회전 각도(도: 0, 90, 180 또는 270). `rotate_image=true`로 방향을 수정한 경우에만 0이 아닙니다.",
                              "example": 0
                            }
                          }
                        },
                        "ref_image": {
                          "type": "object",
                          "description": "참조 이미지에 대한 얼굴 감지 결과로, `user_image`와 동일한 형식입니다.",
                          "properties": {
                            "entities": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "bbox": {
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    },
                                    "minItems": 4,
                                    "maxItems": 4,
                                    "description": "처리된 이미지에서 `[x_min, y_min, x_max, y_max]` 픽셀 좌표로 표시된 감지된 얼굴의 경계 상자입니다.",
                                    "example": [
                                      661,
                                      728,
                                      1688,
                                      2188
                                    ]
                                  },
                                  "confidence": {
                                    "type": "number",
                                    "format": "float",
                                    "minimum": 0,
                                    "maximum": 1,
                                    "description": "얼굴 감지 신뢰도(0–1).",
                                    "example": 0.732973
                                  },
                                  "age": {
                                    "type": "number",
                                    "format": "float",
                                    "description": "감지된 얼굴의 모델 추정 연령(세 단위)입니다. 정보 제공용일 뿐이며 얼굴 대조 결정에는 영향을 미치지 않습니다.",
                                    "example": 26.91
                                  },
                                  "gender": {
                                    "type": "string",
                                    "description": "감지된 얼굴의 모델 예측 성별(`male` 또는 `female`)입니다. 정보 제공용입니다.",
                                    "example": "male"
                                  },
                                  "race": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "예약된 필드 — 이 endpoint의 응답에서는 항상 `null`입니다.",
                                    "example": null
                                  }
                                }
                              },
                              "description": "감지된 얼굴당 항목 1개입니다."
                            },
                            "best_angle": {
                              "type": "integer",
                              "example": 0
                            }
                          }
                        },
                        "warnings": {
                          "type": "array",
                          "description": "문제없이 승인된 경우 비어 있습니다. `NO_REFERENCE_IMAGE`(`error`) — 점수를 산정할 수 있는 얼굴 쌍이 없음, `LOW_FACE_MATCH_SIMILARITY`(`error`) — 점수가 거부 임계값 이하임. 이 중 하나라도 해당되면 `status`가 `Declined`로 설정됩니다.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "enum": [
                                  "NO_REFERENCE_IMAGE",
                                  "LOW_FACE_MATCH_SIMILARITY"
                                ],
                                "description": "기계 판독 가능한 위험 코드입니다."
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "FACEMATCH"
                                ],
                                "description": "경고를 발생시킨 기능입니다. 이 endpoint에서는 항상 `FACEMATCH`입니다."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "얼굴 대조 경고의 경우 항상 `null`입니다."
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error",
                                  "warning",
                                  "information"
                                ],
                                "description": "심각도입니다. `error` 경고는 `status`를 `Declined`로 변경합니다. `warning` 및 `information` 항목은 참고용이며 단독으로 거부되지 않습니다."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "사람이 읽을 수 있는 한 줄의 위험 요약입니다."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "위험에 대한 사람이 읽기 쉬운 설명입니다."
                              }
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "전송한 `vendor_data`의 에코 값 또는 `null`입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "전송한 `metadata` 객체의 에코 값 또는 `null`입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "응답이 생성된 시점의 ISO 8601 타임스탬프(UTC)(예: `2026-06-12T01:04:42.763237+00:00`)입니다."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 필수 이미지가 누락되었거나, 5 MB를 초과하거나, 지원되지 않는 확장자이거나, 옵션이 범위를 벗어난 경우 반환됩니다. 본문은 DRF의 표준 필드 오류 봉투(문제가 있는 필드당 메시지 배열 1개)입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing required image": {
                    "summary": "form data에 `ref_image`(또는 `user_image`)가 포함되지 않음",
                    "value": {
                      "ref_image": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Unsupported file extension": {
                    "summary": "tiff/jpg/jpeg/png/webp 이외의 파일 확장자",
                    "value": {
                      "user_image": [
                        "File extension “txt” is not allowed. Allowed extensions are: tiff, jpg, jpeg, png, webp."
                      ]
                    }
                  },
                  "File too large": {
                    "summary": "업로드가 5MB 제한을 초과함",
                    "value": {
                      "user_image": [
                        "File size should not exceed 5 MB"
                      ]
                    }
                  },
                  "Threshold out of range": {
                    "summary": "`face_match_score_decline_threshold`가 0–100 범위를 벗어남",
                    "value": {
                      "face_match_score_decline_threshold": [
                        "Ensure this value is less than or equal to 100."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었거나 호출한 조직의 잔액이 호출 비용을 충당할 수 없을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 키가 누락된 경우 `{\"detail\": ...}`과 함께 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 크레딧이 부족한 경우 어떠한 이미지 처리도 진행되기 전에 `{\"error\": ...}`과 함께 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 호출 비용을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/face-match/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'user_image=@./selfie.jpg' \\\n  -F 'ref_image=@./id_portrait.jpg' \\\n  -F 'face_match_score_decline_threshold=50' \\\n  -F 'save_api_request=true' \\\n  -F 'vendor_data=user-123'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.face_match.compare(\n    user_image=open(\"user_image.jpg\", \"rb\"),\n    ref_image=open(\"ref_image.jpg\", \"rb\"),\n    face_match_score_decline_threshold=50.0,\n    rotate_image=False,\n    save_api_request=True,\n    vendor_data=\"user-123\",\n    metadata={\"flow\": \"login\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.faceMatch.compare({\n  user_image: await fileFromPath(\"user_image.jpg\"),\n  ref_image: await fileFromPath(\"ref_image.jpg\"),\n  face_match_score_decline_threshold: 50.0,\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"login\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FaceMatch.Compare(ctx, didit.FaceMatchCompareParams{\n\tUserImage:                      didit.FileFromPath(\"user_image.jpg\"),\n\tRefImage:                       didit.FileFromPath(\"ref_image.jpg\"),\n\tFaceMatchScoreDeclineThreshold: didit.Float(50.0),\n\tRotateImage:                    didit.Bool(false),\n\tSaveAPIRequest:                 didit.Bool(true),\n\tVendorData:                     didit.String(\"user-123\"),\n\tMetadata:                       didit.Some(map[string]any{\"flow\": \"login\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.FaceMatchCompareParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.faceMatch().compare(FaceMatchCompareParams.builder()\n        .userImage(Path.of(\"user_image.jpg\"))\n        .refImage(Path.of(\"ref_image.jpg\"))\n        .faceMatchScoreDeclineThreshold(50.0)\n        .rotateImage(false)\n        .saveApiRequest(true)\n        .vendorData(\"user-123\")\n        .metadata(Map.of(\"flow\", \"login\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->faceMatch->compare([\n    'user_image' => File::fromPath('user_image.jpg'),\n    'ref_image' => File::fromPath('ref_image.jpg'),\n    'face_match_score_decline_threshold' => 50.0,\n    'rotate_image' => false,\n    'save_api_request' => true,\n    'vendor_data' => 'user-123',\n    'metadata' => ['flow' => 'login'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.face_match.compare(\n  user_image: Pathname(\"user_image.jpg\"),\n  ref_image: Pathname(\"ref_image.jpg\"),\n  face_match_score_decline_threshold: 50.0,\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"login\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FaceMatch.CompareAsync(new FaceMatchCompareParams\n{\n    UserImage = FileUpload.FromPath(\"user_image.jpg\"),\n    RefImage = FileUpload.FromPath(\"ref_image.jpg\"),\n    FaceMatchScoreDeclineThreshold = 50.0,\n    RotateImage = false,\n    SaveApiRequest = true,\n    VendorData = \"user-123\",\n    Metadata = new Dictionary<string, object> { [\"flow\"] = \"login\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/age-estimation/": {
      "post": {
        "summary": "연령 추정(얼굴 연령 + 패시브 라이브니스)",
        "description": "단일 얼굴 사진에서 인물의 연령을 추정하고 동일한 호출 내에서 수동적 라이브니스 검사를 실행합니다. 모델이 예측한 `age_estimation`(연 단위), 라이브니스 `score`(0–100), 그리고 `Approved`/`Declined` `status`를 반환합니다. 연령은 **문서를 통해 검증된 것이 아니라 얼굴로부터 모델이 예측한 값**입니다. 법적 연령 증명이 아닌 연령 제한 게이트 및 마찰이 적은 검사용으로 사용하십시오.\n\n**작동 방식.** 이미지에서 얼굴을 분석합니다(촬영 방향이 옆으로 눕혀져 있거나 거꾸로인 경우 `rotate_image=true` 설정). 감지된 각 얼굴의 연령이 추정되며, 프레임에서 가장 큰 얼굴을 기준으로 `age_estimation`이 결정됩니다. 동시에 수동적 라이브니스 모델이 사진 속 인물이 실제 인물인지 점수를 매기며(사용자 챌린지 불필요), 프레젠테이션 공격(사진의 사진, 화면, 마스크)을 감지합니다. 최상의 결과를 위해 이미지당 조명이 밝은 환경에서 촬영한 선명하고 정면을 바라보는 얼굴 하나를 전송하십시오.\n\n**결정 로직.** 경고가 하나라도 있으면 거부됩니다. `warnings` 배열이 비어 있을 때만 `status`가 `Approved`가 됩니다. 라이브니스 `score`가 `face_liveness_score_decline_threshold`(기본값 `30`) 이하이면 `LOW_LIVENESS_SCORE`가 추가됩니다. 공격이 감지되면 `LIVENESS_FACE_ATTACK`이 추가되고, 라이브니스 모델에서 얼굴을 찾지 못하면 `NO_FACE_DETECTED`가 추가되며, 추정 가능한 얼굴 연령이 없으면 `AGE_NOT_DETECTED`가 추가됩니다(`age_estimation`은 `null`). 추정 연령이 `age_estimation_decline_threshold`(기본값 `18`) 미만이면 `AGE_BELOW_MINIMUM`이 추가됩니다. 설정한 임계값에 가까운 경계선 연령은 문서 기반 인증으로 대체하는 것이 좋습니다. 한계치에 가까운 얼굴일수록 모델의 오차가 커지기 때문입니다.\n\n**결제.** `200` 응답마다 연령 추정 API 크레딧 1개가 차감됩니다(요금제 크레딧 또는 충전 잔액에서 차감). 조직의 잔액이 호출 비용을 충당할 수 없는 경우, endpoint는 이미지 처리가 시작되기 전에 크레딧 부족 오류와 함께 `403`을 반환합니다.\n\n**세션 영속성 (`save_api_request`, 기본값 `true`).** `true`인 경우 호출이 API 유형 세션으로 저장됩니다. Business Console에 표시되며, 반환된 `request_id`는 `GET /v3/session/{sessionId}/decision/`에 전달할 수 있는 실제 세션 id가 됩니다(결과는 해당 위치의 `liveness_checks[]` 내에 `features: [\"AGE_ESTIMATION\"]`과 함께 표시됨). 얼굴 크롭 및 참조 이미지가 저장되고, 얼굴 임베딩이 애플리케이션의 얼굴 색인에 추가되며(얼굴 검색 및 중복 감지에 사용), `status.updated` webhook이 발송됩니다. `false`인 경우 아무것도 저장되지 않으며 `request_id`는 나중에 조회할 수 없는 일회성 상관관계 UUID가 됩니다.\n\n**샌드박스.** 샌드박스 API 키는 모든 처리 및 결제를 건너뜁니다. 요청 유효성 검사 후(잘못된 형식의 입력은 여전히 `400`을 반환함) endpoint는 정적 `Approved` 모의 payload(`age_estimation: 30`, 경고 없음)를 반환하며, 세션이 저장되지 않고 크레딧도 소모되지 않습니다.\n\n**인증.** 애플리케이션의 API 키를 `x-api-key` 헤더에 담아 전송하십시오. 자격 증명이 누락되었거나 유효하지 않으면 `403`(`{\"detail\": \"You do not have permission to perform this action.\"}`)을 반환합니다. 이 API는 `401`을 절대 반환하지 않습니다.\n\n**속도 제한.** 모든 POST/PATCH/DELETE endpoint에 걸쳐 API 키당 분당 300회의 공유 쓰기 예산이 적용되며, 이를 초과하면 `429`가 반환됩니다.",
        "operationId": "post_v3age-estimation",
        "x-didit-sdk": {
          "resource": "age_estimation",
          "method": "estimate",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "user_image"
                ],
                "properties": {
                  "user_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "분석할 얼굴 사진(예: 셀피). 대상의 얼굴이 선명하게 보이고 조명이 밝은 정면 사진 한 장을 제출하십시오. 허용되는 확장자: `tiff`, `jpg`, `jpeg`, `png`, `webp`(PDF 불가). 최대 업로드 크기: **5 MB**(더 큰 파일은 `400`과 함께 거부됨). 이미지는 처리 전에 약 0.3 MB로 자동 압축되므로 매우 높은 해상도가 정확도를 향상시키지는 않습니다."
                  },
                  "face_liveness_score_decline_threshold": {
                    "type": "number",
                    "format": "float",
                    "default": 30,
                    "minimum": 0,
                    "maximum": 100,
                    "description": "라이브니스 임계값(0–100). 라이브니스 `score`가 이 값 **이하**인 경우 `LOW_LIVENESS_SCORE` 경고를 추가하고 거부합니다. 더 엄격한 안티 스푸핑을 위해 값을 올리십시오. 0–100 범위를 벗어난 값은 `400`을 반환합니다.",
                    "example": 30
                  },
                  "age_estimation_decline_threshold": {
                    "type": "integer",
                    "default": 18,
                    "minimum": 0,
                    "maximum": 100,
                    "description": "허용 가능한 최소 추정 연령(세 단위)입니다. 추정 연령이 이 값 **미만**인 경우 `AGE_BELOW_MINIMUM` 경고가 추가되고 거부됩니다. 연령 확인을 비활성화하려면 `0`으로 설정하십시오(이 경우 연령 기반 결정 없이 라이브니스 + 연령 추정만 실행됩니다).",
                    "example": 18
                  },
                  "rotate_image": {
                    "type": "boolean",
                    "default": false,
                    "description": "`true`인 경우 서비스가 입력 이미지를 90도 단위(0, 90, 180, 270)로 시도하고 최적의 얼굴 감지 결과를 내는 방향을 사용합니다. EXIF 방향 정보가 누락된 모바일 촬영에 유용합니다. 지연 시간이 추가되므로 똑바른 이미지를 보장할 수 없는 경우에만 활성화하십시오.",
                    "example": false
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "`true`(기본값)인 경우 호출을 API 유형 세션으로 저장합니다. Business Console에서 확인할 수 있고 반환된 `request_id`를 사용하여 `GET /v3/session/{sessionId}/decision/`을 통해 조회할 수 있으며 `status.updated` webhook을 통해 알림이 전송되고 감지된 얼굴이 애플리케이션의 얼굴 색인에 추가됩니다. `false`인 경우 아무것도 저장되지 않으며 `request_id`는 응답 상관관계 식별 전용의 일시적인 UUID입니다.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "저장된 세션에 저장되고 응답에 다시 반환되는 선택적 불투명 문자열(내부 사용자 ID, 이메일, UUID 등)입니다. API 호출을 자체 기록과 연관 짓고 나중에 세션을 필터링하는 데 사용합니다.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "세션과 함께 저장되고(`save_api_request=true`인 경우) 응답에 그대로 반환되는 선택적 JSON 객체입니다. multipart 요청에서는 JSON 인코딩된 문자열 필드(예: `metadata={\"flow\":\"age-gate\"}`)로 전송하십시오. 객체로 파싱됩니다.",
                    "example": {
                      "flow": "age-gate"
                    }
                  }
                }
              },
              "example": {
                "user_image": "(binary JPEG/PNG of the selfie)",
                "face_liveness_score_decline_threshold": 30,
                "age_estimation_decline_threshold": 18,
                "rotate_image": false,
                "save_api_request": true,
                "vendor_data": "user-123",
                "metadata": {
                  "flow": "age-gate"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "연령 추정 및 패시브 라이브니스가 완료되었습니다. `age_estimation.age_estimation`은 감지된 가장 큰 얼굴에 대해 모델이 예측한 연령(연 단위, 감지된 얼굴이 없으면 `null`)이며, `age_estimation.score`는 패시브 라이브니스 점수(0–100)입니다. `status`는 `warnings`가 비어 있는 경우에만 `Approved`입니다. 미성년자이거나 스푸핑된 캡처인 경우에도 `status: \"Declined\"`와 함께 `200`을 반환하므로, HTTP 코드뿐만 아니라 body도 확인하십시오. `save_api_request=true`인 경우 `request_id`는 저장된 세션 ID입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Approved": {
                    "summary": "실제 성인 얼굴 — 두 검사 모두 통과함",
                    "value": {
                      "request_id": "0c40ba43-64ab-4e2e-b4b8-7d1f12f81bc1",
                      "age_estimation": {
                        "status": "Approved",
                        "method": "PASSIVE",
                        "score": 97.5,
                        "user_image": {
                          "entities": [
                            {
                              "age": 27.33,
                              "bbox": [
                                40,
                                40,
                                100,
                                100
                              ],
                              "confidence": 0.7177750468254089,
                              "gender": "male"
                            }
                          ],
                          "best_angle": 0
                        },
                        "age_estimation": 27.33,
                        "warnings": []
                      },
                      "vendor_data": "user-123",
                      "metadata": {
                        "flow": "age-gate"
                      },
                      "created_at": "2026-06-12T02:24:11.512941+00:00"
                    }
                  },
                  "Declined - age below threshold": {
                    "summary": "추정 연령이 `age_estimation_decline_threshold` 미만임",
                    "value": {
                      "request_id": "9be41a6f-2f4e-4f57-92f4-b3a4f6f0a1c2",
                      "age_estimation": {
                        "status": "Declined",
                        "method": "PASSIVE",
                        "score": 95.0,
                        "user_image": {
                          "entities": [
                            {
                              "age": 16.5,
                              "bbox": [
                                40,
                                40,
                                100,
                                100
                              ],
                              "confidence": 0.7177750468254089,
                              "gender": "female"
                            }
                          ],
                          "best_angle": 0
                        },
                        "age_estimation": 16.5,
                        "warnings": [
                          {
                            "risk": "AGE_BELOW_MINIMUM",
                            "feature": "LIVENESS",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Age below minimum",
                            "long_description": "The age of the face is below the minimum age threshold for the application."
                          }
                        ]
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T02:26:40.118332+00:00"
                    }
                  },
                  "Declined - liveness too low": {
                    "summary": "라이브니스 점수가 거부 임계값 이하임(스푸핑 가능성 있음)",
                    "value": {
                      "request_id": "5f6f2f1f-7c4f-43b9-8d62-0a8f4c2d9e77",
                      "age_estimation": {
                        "status": "Declined",
                        "method": "PASSIVE",
                        "score": 5.0,
                        "user_image": {
                          "entities": [
                            {
                              "age": 25.0,
                              "bbox": [
                                40,
                                40,
                                100,
                                100
                              ],
                              "confidence": 0.7177750468254089,
                              "gender": "male"
                            }
                          ],
                          "best_angle": 0
                        },
                        "age_estimation": 25.0,
                        "warnings": [
                          {
                            "risk": "LOW_LIVENESS_SCORE",
                            "feature": "LIVENESS",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Low liveness score",
                            "long_description": "The liveness check resulted in a low score, indicating potential use of non-live facial representations or poor-quality biometric data."
                          }
                        ]
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T02:27:02.901547+00:00"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "`save_api_request=true`일 때 유지된 세션 ID(`GET /v3/session/{sessionId}/decision/`와 함께 사용 가능), 그렇지 않으면 임시 상관관계 UUID입니다."
                    },
                    "age_estimation": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined"
                          ],
                          "description": "발생한 경고가 없는 경우 `Approved`, 그렇지 않은 경우 `Declined`가 됩니다(이 endpoint에서 발생하는 모든 경고는 거부로 처리됩니다)."
                        },
                        "method": {
                          "type": "string",
                          "enum": [
                            "PASSIVE"
                          ],
                          "description": "라이브니스 방식. 이 endpoint에서는 항상 `PASSIVE`입니다(단일 이미지, 사용자 챌린지 없음)."
                        },
                        "score": {
                          "type": "number",
                          "format": "float",
                          "nullable": true,
                          "minimum": 0,
                          "maximum": 100,
                          "description": "0부터 100까지의 패시브 라이브니스 점수입니다. 사진에 실제 사람이 나타나 있는지에 대한 모델의 신뢰도 점수를 나타냅니다. `face_liveness_score_decline_threshold`와 비교되며, 해당 값 이하이면 호출이 `LOW_LIVENESS_SCORE`로 거부됩니다. 라이브니스 모델이 신뢰도를 반환하지 않는 경우 `null`이며, 임계값 비교 시 null은 0으로 처리되므로 호출은 여전히 `LOW_LIVENESS_SCORE`로 거부됩니다.",
                          "example": 97.5
                        },
                        "user_image": {
                          "type": "object",
                          "description": "분석된 이미지에 대한 얼굴 감지 결과입니다.",
                          "properties": {
                            "entities": {
                              "type": "array",
                              "description": "감지된 얼굴당 항목 1개입니다. 얼굴이 발견되지 않으면 비어 있습니다(이 경우 `age_estimation`은 `null`이 되며 `AGE_NOT_DETECTED` 경고가 추가됩니다).",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "age": {
                                    "type": "number",
                                    "format": "float",
                                    "description": "이 얼굴의 모델 추정 연령(세 단위)입니다.",
                                    "example": 27.33
                                  },
                                  "bbox": {
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    },
                                    "minItems": 4,
                                    "maxItems": 4,
                                    "description": "처리된 이미지에서 `[x_min, y_min, x_max, y_max]` 픽셀 좌표로 표시된 감지된 얼굴의 경계 상자입니다.",
                                    "example": [
                                      40,
                                      40,
                                      100,
                                      100
                                    ]
                                  },
                                  "confidence": {
                                    "type": "number",
                                    "format": "float",
                                    "minimum": 0,
                                    "maximum": 1,
                                    "description": "얼굴 감지 신뢰도(0–1).",
                                    "example": 0.7177750468254089
                                  },
                                  "gender": {
                                    "type": "string",
                                    "description": "감지된 얼굴의 모델 예측 성별(`male` 또는 `female`)입니다. 정보 제공용입니다.",
                                    "example": "male"
                                  }
                                }
                              }
                            },
                            "best_angle": {
                              "type": "integer",
                              "nullable": true,
                              "description": "가장 우수한 얼굴 감지를 생성한 회전 각도(도: 0, 90, 180 또는 270). `rotate_image=true`로 방향을 수정한 경우에만 0이 아닙니다.",
                              "example": 0
                            }
                          }
                        },
                        "age_estimation": {
                          "type": "number",
                          "format": "float",
                          "nullable": true,
                          "description": "감지된 얼굴 중 **가장 큰** 얼굴의 모델 예측 연령(세 단위)입니다. 얼굴 연령을 추정할 수 없는 경우 `null`입니다(`AGE_NOT_DETECTED` 경고가 추가되고 호출이 거부됨).",
                          "example": 27.33
                        },
                        "warnings": {
                          "type": "array",
                          "description": "문제없이 승인된 경우 비어 있습니다. 항목이 하나라도 있으면 `status`가 `Declined`로 설정됩니다.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "enum": [
                                  "NO_FACE_DETECTED",
                                  "LOW_LIVENESS_SCORE",
                                  "LIVENESS_FACE_ATTACK",
                                  "AGE_NOT_DETECTED",
                                  "AGE_BELOW_MINIMUM"
                                ],
                                "description": "기계 판독 가능한 위험 코드입니다. `NO_FACE_DETECTED` — 라이브니스 모델이 얼굴을 찾지 못함; `LOW_LIVENESS_SCORE` — 라이브니스 `score`가 `face_liveness_score_decline_threshold` 이하임; `LIVENESS_FACE_ATTACK` — 프레젠테이션 공격(사진/화면/가면)이 감지됨; `AGE_NOT_DETECTED` — 얼굴 연령을 추정할 수 없음; `AGE_BELOW_MINIMUM` — 추정 연령이 `age_estimation_decline_threshold` 미만임. `NO_FACE_DETECTED`와 `LOW_LIVENESS_SCORE`는 상호 배타적입니다 — 얼굴을 찾지 못한 경우 `NO_FACE_DETECTED`만 출력됩니다."
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "LIVENESS"
                                ],
                                "description": "경고를 발생시킨 기능입니다. 이 endpoint에서는 항상 `LIVENESS`입니다."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "연령 추정 경고의 경우 항상 `null`입니다."
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ],
                                "description": "심각도입니다. 이 endpoint에서 생성되는 모든 경고는 `error`이며 `status`를 `Declined`로 설정합니다."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "사람이 읽을 수 있는 한 줄의 위험 요약입니다."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "위험에 대한 사람이 읽기 쉬운 설명입니다."
                              }
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "전송한 `vendor_data`의 에코 값 또는 `null`입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "전송한 `metadata` 객체의 에코 값 또는 `null`입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "응답이 생성된 시점의 ISO 8601 타임스탬프(UTC)입니다."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. `user_image`가 누락되었거나, 5 MB를 초과하거나, 지원되지 않는 확장자이거나, 임계값이 범위를 벗어난 경우 반환됩니다. 본문은 DRF의 표준 필드 오류 봉투(문제가 있는 필드당 메시지 배열 1개)입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing user image": {
                    "summary": "폼 데이터에 `user_image`가 포함되지 않음",
                    "value": {
                      "user_image": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Unsupported file extension": {
                    "summary": "tiff/jpg/jpeg/png/webp 이외의 파일 확장자",
                    "value": {
                      "user_image": [
                        "File extension “txt” is not allowed. Allowed extensions are: tiff, jpg, jpeg, png, webp."
                      ]
                    }
                  },
                  "File too large": {
                    "summary": "업로드가 5MB 제한을 초과함",
                    "value": {
                      "user_image": [
                        "File size should not exceed 5 MB"
                      ]
                    }
                  },
                  "Threshold out of range": {
                    "summary": "`face_liveness_score_decline_threshold`가 0–100 범위를 벗어남",
                    "value": {
                      "face_liveness_score_decline_threshold": [
                        "Ensure this value is less than or equal to 100."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었거나 호출한 조직의 잔액이 호출 비용을 충당할 수 없을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 키가 누락된 경우 `{\"detail\": ...}`과 함께 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 크레딧이 부족한 경우 어떠한 이미지 처리도 진행되기 전에 `{\"error\": ...}`과 함께 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 호출 비용을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/age-estimation/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'user_image=@./selfie.jpg' \\\n  -F 'age_estimation_decline_threshold=18' \\\n  -F 'face_liveness_score_decline_threshold=30' \\\n  -F 'save_api_request=true' \\\n  -F 'vendor_data=user-123'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.age_estimation.estimate(\n    user_image=open(\"user_image.jpg\", \"rb\"),\n    face_liveness_score_decline_threshold=30.0,\n    age_estimation_decline_threshold=18,\n    rotate_image=False,\n    save_api_request=True,\n    vendor_data=\"user-123\",\n    metadata={\"flow\": \"age-gate\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.ageEstimation.estimate({\n  user_image: await fileFromPath(\"user_image.jpg\"),\n  face_liveness_score_decline_threshold: 30.0,\n  age_estimation_decline_threshold: 18,\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"age-gate\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.AgeEstimation.Estimate(ctx, didit.AgeEstimationEstimateParams{\n\tUserImage:                         didit.FileFromPath(\"user_image.jpg\"),\n\tFaceLivenessScoreDeclineThreshold: didit.Float(30.0),\n\tAgeEstimationDeclineThreshold:     didit.Int(18),\n\tRotateImage:                       didit.Bool(false),\n\tSaveAPIRequest:                    didit.Bool(true),\n\tVendorData:                        didit.String(\"user-123\"),\n\tMetadata:                          didit.Some(map[string]any{\"flow\": \"age-gate\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.AgeEstimationEstimateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.ageEstimation().estimate(AgeEstimationEstimateParams.builder()\n        .userImage(Path.of(\"user_image.jpg\"))\n        .faceLivenessScoreDeclineThreshold(30.0)\n        .ageEstimationDeclineThreshold(18L)\n        .rotateImage(false)\n        .saveApiRequest(true)\n        .vendorData(\"user-123\")\n        .metadata(Map.of(\"flow\", \"age-gate\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->ageEstimation->estimate([\n    'user_image' => File::fromPath('user_image.jpg'),\n    'face_liveness_score_decline_threshold' => 30.0,\n    'age_estimation_decline_threshold' => 18,\n    'rotate_image' => false,\n    'save_api_request' => true,\n    'vendor_data' => 'user-123',\n    'metadata' => ['flow' => 'age-gate'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.age_estimation.estimate(\n  user_image: Pathname(\"user_image.jpg\"),\n  face_liveness_score_decline_threshold: 30.0,\n  age_estimation_decline_threshold: 18,\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"age-gate\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.AgeEstimation.EstimateAsync(new AgeEstimationEstimateParams\n{\n    UserImage = FileUpload.FromPath(\"user_image.jpg\"),\n    FaceLivenessScoreDeclineThreshold = 30.0,\n    AgeEstimationDeclineThreshold = 18,\n    RotateImage = false,\n    SaveApiRequest = true,\n    VendorData = \"user-123\",\n    Metadata = new Dictionary<string, object> { [\"flow\"] = \"age-gate\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/poa/": {
      "post": {
        "summary": "주소 증명(문서 OCR + 주소 확인)",
        "description": "단 한 번의 호출로 공과금 고지서, 은행 거래 내역서, 정부 발급 문서 등 주소 증명 문서를 추출하고 검증합니다. 발급 기관, 발급일/만료일, 소유자 성명, 원본 및 파싱/지오코딩된 주소, `Approved`/`Declined` `status`, 발견된 모든 문제를 설명하는 `warnings` 목록을 반환합니다.\n\n**지연 시간.** 추출은 LLM을 기반으로 작동합니다. 일반적인 호출은 **5–15초**, 여러 페이지로 구성된 PDF는 최대 **약 30초**가 소요됩니다. 클라이언트 타임아웃을 **최소 45초**로 구성하고 호출이 완료되기 전에 재시도하지 마세요.\n\n**작동 방식.** 문서(이미지 또는 PDF, 최대 15 MB, 암호화된 PDF는 `document_password` 필요)는 문서 유형 및 하위 유형(예: `UTILITY_BILL` / `WATER_BILL`)으로 분류되며, LLM 기반 추출을 통해 발급 기관, 날짜, 소유자 성명, 주소가 추출됩니다. 주소는 파싱 및 지오코딩되어 `poa_parsed_address`에 반영됩니다. PDF/EXIF 포렌식을 통해 디지털 서명 후 수정, 알려진 PDF 편집기 사용, 오버레이 텍스트 조작, 의심스러운 재내보내기 등의 변조 여부를 스크리닝하여 `SUSPECTED_DOCUMENT_MANIPULATION` 또는 `DOCUMENT_METADATA_MISMATCH`를 표시합니다. 텍스트 필드가 공백 처리된 후 다른 글꼴로 다시 입력되었으나 파일 자체에는 내용 변경 여부에 대한 증거가 없는 경우 `POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT`가 표시됩니다. 문서 발행 기간은 `poa_document_age_months`를 기준으로 검증되며, 언어는 `poa_languages_allowed`를 기준으로 검증됩니다. `expected_address`, `expected_country` 또는 `expected_first_name`/`expected_last_name`을 전달하면 추출된 값과 교차 확인하여 불일치를 표시합니다.\n\n**결정 로직.** 최소 하나의 경고라도 거부로 처리되지 않는 한 `status`는 `Approved`가 됩니다. 치명적 오류(Hard failure)는 항상 거부됩니다: `MISSING_ADDRESS_INFORMATION`, `POA_DOCUMENT_EXPIRED`, `INVALID_DOCUMENT_TYPE`, `UNABLE_TO_VALIDATE_DOCUMENT_AGE`, 그리고 `UNABLE_TO_EXTRACT_ISSUE_DATE` 및 `POA_NAME_NOT_DETECTED`(이 endpoint에서는 구성할 수 없음). 5가지 위험 그룹은 `poa_*_action` 옵션(`DECLINE` 또는 `NO_ACTION`, 모두 기본값은 `DECLINE`)을 통해 요청별로 구성할 수 있습니다. `POA_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION` 및 `UNPARSABLE_OR_INVALID_ADDRESS`는 이 endpoint에서 정보 제공용이며 절대 거부되지 않습니다. 전혀 처리할 수 없는 문서는 `400`을 반환하고, 읽을 수는 있지만 문제가 있는 문서는 `200`과 함께 `status: \"Declined\"`를 반환합니다. 따라서 HTTP 코드뿐만 아니라 항상 `poa.status`와 `poa.warnings`를 확인하세요.\n\n**결제.** `200` 응답마다 주소 증명 API 크레딧이 1개씩 차감됩니다(요금제 크레딧 또는 충전 잔액에서 차감). 조직의 잔액이 호출 비용을 충당할 수 없는 경우, endpoint는 문서 처리를 시작하기 전에 크레딧 부족 오류와 함께 `403`을 반환합니다.\n\n**세션 유지(`save_api_request`, 기본값 `true`).** `true`인 경우 호출은 API 유형 세션으로 영구 보관됩니다. Business Console에 표시되고, 업로드된 문서가 저장되며, 반환된 `request_id`는 `GET /v3/session/{sessionId}/decision/`에 전달할 수 있는 실제 세션 id가 되고(결정에는 이 응답에서 생략된 `document_file` 및 `document_metadata` 포렌식이 추가로 표시됨), `status.updated` webhook이 발송됩니다. `false`인 경우 아무것도 저장되지 않으며 `request_id`는 나중에 조회할 수 없는 일회성 상관관계 UUID가 됩니다.\n\n**샌드박스.** 샌드박스 API 키는 모든 처리 및 결제를 건너뜁니다. 요청 유효성 검사 후(잘못된 형식의 입력은 여전히 `400`을 반환함), endpoint는 정적 `Approved` 모의 payload(가상의 \"Sandbox Power Co.\" 전기 요금 고지서)를 반환하며, 세션이 저장되지 않고 크레딧도 차감되지 않습니다.\n\n**인증.** 애플리케이션의 API 키를 `x-api-key` 헤더에 담아 전송하세요. 자격 증명이 누락되었거나 유효하지 않으면 `403`(`{\"detail\": \"You do not have permission to perform this action.\"}`)을 반환합니다. 이 API는 절대 `401`을 반환하지 않습니다.\n\n**속도 제한.** 모든 POST/PATCH/DELETE endpoint에 걸쳐 API 키당 분당 300건의 공유 쓰기 요청 한도가 적용되며, 초과 시 `429`가 반환됩니다.\n\n참고: `FUTURE_ISSUE_DATE` 및 `POOR_DOCUMENT_QUALITY`는 워크플로 세션에 존재하지만 이 독립 실행형 endpoint에서는 생성되지 않습니다. 미래 날짜가 지정된 문서는 여기에서 자동으로 거부되지 않습니다.",
        "operationId": "post_v3poa",
        "x-didit-sdk": {
          "resource": "proof_of_address",
          "method": "verify",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "document"
                ],
                "properties": {
                  "document": {
                    "type": "string",
                    "format": "binary",
                    "description": "주소 증명 문서입니다. 허용되는 확장자: `tiff`, `jpg`, `jpeg`, `png`, `pdf`, `webp`. 최대 업로드 크기: **15 MB**(더 큰 파일은 `400`으로 거부됨). 다중 페이지 PDF가 지원됩니다(대기 시간이 늘어날 수 있음). 암호화된 PDF는 `document_password`가 필요합니다. 이미지는 처리 전에 자동으로 압축됩니다."
                  },
                  "document_password": {
                    "type": "string",
                    "description": "`document`가 암호화된 PDF인 경우 복호화하기 위한 비밀번호입니다. 비밀번호 없이(또는 잘못된 비밀번호로) 암호화된 PDF를 전송하면 `400`이 반환됩니다.",
                    "writeOnly": true
                  },
                  "expected_address": {
                    "type": "string",
                    "description": "문서와 대조하여 확인할 주소입니다. 지오코딩되어 추출된 주소와 비교됩니다. 불일치하는 경우(또는 제공된 주소를 지오코딩/검증할 수 없는 경우) `poa_address_mismatch_action`에 따라 `ADDRESS_MISMATCH_WITH_PROVIDED`가 추가됩니다. 지오코딩된 형태는 `expected_details_formatted_address` / `expected_details_parsed_address`로 다시 반환됩니다.",
                    "example": "Av. Monseñor Tavella 1291, Salta, Argentina"
                  },
                  "expected_country": {
                    "type": "string",
                    "description": "문서와 대조하여 검증할 국가(ISO 3166-1 코드, 예: `ARG` 또는 `AR`). 문서의 국가와 일치하지 않으면 `POA_COUNTRY_MISMATCH_WITH_PROVIDED`가 추가되며, `poa_address_mismatch_action`의 적용을 받습니다.",
                    "example": "ARG"
                  },
                  "expected_first_name": {
                    "type": "string",
                    "description": "`name_on_document`와 대조하여 검증할 이름입니다(퍼지 일치, 음차 인식). 일치 임계값보다 낮은 점수는 `NAME_MISMATCH_WITH_PROVIDED`를 추가하며, 이는 `poa_address_mismatch_action`의 제어를 받습니다.",
                    "example": "Sophia"
                  },
                  "expected_last_name": {
                    "type": "string",
                    "description": "`name_on_document`와 대조하여 확인할 성으로, 일치 점수 산정을 위해 `expected_first_name`과 결합됩니다.",
                    "example": "Martinez"
                  },
                  "poa_languages_allowed": {
                    "type": "string",
                    "description": "ISO 639-1 코드로 지정된 수락 가능한 문서 언어의 쉼표로 구분된 목록(예: `en,es,fr`). 생략하거나 비워 두면 **지원되는 51개 언어 모두**가 수락됩니다. 목록 외의 언어로 작성된 문서는 `UNSUPPORTED_DOCUMENT_LANGUAGE`를 추가하며(`poa_unsupported_language_action`에 의해 관리됨), 목록에 알 수 없는 코드가 포함되어 있으면 지원되는 전체 코드 세트와 함께 `400`을 반환합니다.",
                    "example": "en,es"
                  },
                  "poa_document_age_months": {
                    "type": "string",
                    "description": "문서 유형별 최대 문서 사용 기간(개월)을 설정하는 쉼표로 구분된 `key:value` 쌍 — 키: `utility_bill`, `bank_statement`, `government_issued_document`, `other_poa_document`, 값: `1`–`120` 또는 무제한(문서 연령 확인 안 함)을 나타내는 `-1`. 생략 시 기본값: `utility_bill:3,bank_statement:3,government_issued_document:12,other_poa_document:12`. 제한보다 오래된 문서는 `POA_DOCUMENT_EXPIRED`로 거부됩니다. **주의:** 이 필드를 제공할 때는 수락할 *모든* 유형을 나열해야 합니다. 생략된 유형은 수락되지 않은 것으로 처리되며(정보성 `POA_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION`), 문서 연령 확인을 건너뜁니다.",
                    "example": "utility_bill:3,bank_statement:6"
                  },
                  "poa_name_mismatch_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "허용되지만 **현재 적용되지 않음** — 이름 불일치 경고(`NAME_MISMATCH_WITH_PROVIDED`)는 대신 `poa_address_mismatch_action`을 따릅니다. 이름과 주소 불일치 동작을 모두 제어하려면 `poa_address_mismatch_action`을 설정하십시오."
                  },
                  "poa_document_issues_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "파일 무결성 문제 발생 시 수행할 작업입니다. 실제로는 이 endpoint에서 `DOCUMENT_METADATA_MISMATCH`만 생성됩니다."
                  },
                  "poa_document_authenticity_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "문서 위변조가 의심될 때(`SUSPECTED_DOCUMENT_MANIPULATION`) 수행할 작업입니다(예: 전자 서명 후 PDF 수정, 알려진 PDF 편집기로 처리됨, 오버레이 텍스트 조작 확인, 일치하지 않는 EXIF 날짜 등). `POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT`(파일상에서 변경 여부를 입증할 수 없는 다시 입력된 텍스트 필드)에도 적용되며, `DECLINE`은 이 또한 거부하고 `NO_ACTION`은 경고로 유지합니다."
                  },
                  "poa_unsupported_language_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "문서 언어가 `poa_languages_allowed`에 속하지 않을 때 수행할 작업입니다 (`UNSUPPORTED_DOCUMENT_LANGUAGE`)."
                  },
                  "poa_address_mismatch_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "추출된 세부 정보가 `expected_*` 필드와 일치하지 않을 때 수행할 작업입니다. `ADDRESS_MISMATCH_WITH_PROVIDED`, `NAME_MISMATCH_WITH_PROVIDED`, `POA_COUNTRY_MISMATCH_WITH_PROVIDED` 모두 이 작업을 따릅니다."
                  },
                  "poa_issuer_not_identified_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "문서에서 발급 회사/조직을 식별할 수 없을 때(`ISSUER_NOT_IDENTIFIED`) 수행할 작업입니다."
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "`true`(기본값)인 경우 호출을 API 유형 세션으로 저장합니다. Business Console에서 확인할 수 있고 반환된 `request_id`를 사용하여 `GET /v3/session/{sessionId}/decision/`을 통해 조회할 수 있으며 `status.updated` webhook을 통해 알림이 전송되고 업로드된 문서가 저장됩니다. `false`인 경우 아무것도 저장되지 않으며 `request_id`는 응답 상관관계 식별 전용의 일시적인 UUID입니다.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "저장된 세션에 저장되고 응답에 다시 반환되는 선택적 불투명 문자열(내부 사용자 ID, 이메일, UUID 등)입니다. API 호출을 자체 기록과 연관 짓고 나중에 세션을 필터링하는 데 사용합니다.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "세션과 함께 저장되고(`save_api_request=true`인 경우) 응답에 그대로 반환되는 선택적 JSON 객체입니다. multipart 요청에서는 JSON 인코딩된 문자열 필드(예: `metadata={\"flow\":\"onboarding\"}`)로 전송하십시오. 객체로 파싱됩니다.",
                    "example": {
                      "flow": "onboarding"
                    }
                  }
                }
              },
              "example": {
                "document": "(binary JPEG/PNG/PDF of the utility bill or bank statement)",
                "expected_address": "Av. Monseñor Tavella 1291, Salta, Argentina",
                "expected_country": "ARG",
                "expected_first_name": "Sophia",
                "expected_last_name": "Martinez",
                "poa_languages_allowed": "en,es",
                "save_api_request": true,
                "vendor_data": "user-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "문서가 처리되었습니다. `poa.status`는 `Approved` 또는 `Declined`입니다. 감지된 모든 문제는 `poa.warnings`에 항목별로 나열됩니다. 만료되었거나 불일치하거나 의심스러운 문서라도 `status: \"Declined\"`와 함께 `200`을 반환하므로 HTTP 코드뿐만 아니라 본문도 확인해야 합니다. `save_api_request=true`인 경우 `request_id`는 저장된 세션 ID입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Approved": {
                    "summary": "공과금 청구서가 명확하게 판독되었으며, 예상 세부 정보 확인이 수행되지 않았습니다",
                    "value": {
                      "request_id": "4b523a8d-ed32-45e4-8aa8-a89eda459d88",
                      "poa": {
                        "issuing_state": "ARG",
                        "document_type": "UTILITY_BILL",
                        "document_subtype": "WATER_BILL",
                        "document_language": "es",
                        "issuer": "Aguas del Norte",
                        "issue_date": "2026-04-10",
                        "expiration_date": null,
                        "poa_address": "AVDA. MONSEÑOR TAVELLA N° 1291, B° VILLA LAVALLE CP: 4400, CAPITAL - SALTA",
                        "poa_formatted_address": "Av. Monseñor Tavella 1291 b, A4400 Salta, Argentina",
                        "poa_parsed_address": {
                          "street_1": "Avenida Monseñor Tavella 1291",
                          "street_2": "b",
                          "city": "Salta",
                          "region": "Salta",
                          "country": "AR",
                          "postal_code": "A4400",
                          "document_location": {
                            "latitude": -24.8208682,
                            "longitude": -65.4130954
                          }
                        },
                        "expected_details_address": null,
                        "expected_details_formatted_address": null,
                        "expected_details_parsed_address": null,
                        "name_on_document": "OESTE EMBOTELLADORA S.A.",
                        "extra_fields": {
                          "bank_account_number": null,
                          "bank_iban": null,
                          "bank_sort_code": null,
                          "bank_routing_number": null,
                          "bank_swift_bic": null,
                          "bank_branch_name": null,
                          "bank_branch_address": null,
                          "document_phone_number": null,
                          "additional_names": [
                            "LA EMBOTELLADORA DEL NORTE SA"
                          ]
                        },
                        "detected_codes": [
                          {
                            "type": "QR_CODE",
                            "page_number": 1,
                            "position": [
                              [
                                820,
                                1120
                              ],
                              [
                                1002,
                                1120
                              ],
                              [
                                1002,
                                1302
                              ],
                              [
                                820,
                                1302
                              ]
                            ],
                            "x": 820,
                            "y": 1120,
                            "width": 182,
                            "height": 182,
                            "page_width": 1190,
                            "page_height": 1684,
                            "raw_payload": "aHR0cHM6Ly9hZ3Vhc2RlbG5vcnRlLmNvbS9mYWN0dXJhLzk5ODgxMQ==",
                            "parsed_payload": "https://aguasdelnorte.com/factura/998811"
                          },
                          {
                            "type": "CODE_128",
                            "page_number": 1,
                            "position": [
                              [
                                112,
                                1480
                              ],
                              [
                                560,
                                1480
                              ],
                              [
                                560,
                                1540
                              ],
                              [
                                112,
                                1540
                              ]
                            ],
                            "x": 112,
                            "y": 1480,
                            "width": 448,
                            "height": 60,
                            "page_width": 1190,
                            "page_height": 1684,
                            "raw_payload": "MDA5OTg4MTEwMDA0Mg==",
                            "parsed_payload": "0099881100042"
                          }
                        ],
                        "status": "Approved",
                        "warnings": []
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T02:29:02.439655+00:00"
                    }
                  },
                  "Declined - document too old": {
                    "summary": "허용된 `poa_document_age_months`보다 오래된 발급일",
                    "value": {
                      "request_id": "f61681b8-9422-4378-ac3e-04c6a247fb45",
                      "poa": {
                        "issuing_state": "ARG",
                        "document_type": "UTILITY_BILL",
                        "document_subtype": "WATER_BILL",
                        "document_language": "es",
                        "issuer": "Aguas del Norte",
                        "issue_date": "2021-02-10",
                        "expiration_date": null,
                        "poa_address": "AVDA. MONSEÑOR TAVELLA N° 1291, B° VILLA LAVALLE CP: 4400, CAPITAL - SALTA",
                        "poa_formatted_address": "Av. Monseñor Tavella 1291 b, A4400 Salta, Argentina",
                        "poa_parsed_address": {
                          "street_1": "Avenida Monseñor Tavella 1291",
                          "street_2": "b",
                          "city": "Salta",
                          "region": "Salta",
                          "country": "AR",
                          "postal_code": "A4400",
                          "document_location": {
                            "latitude": -24.8208682,
                            "longitude": -65.4130954
                          }
                        },
                        "expected_details_address": null,
                        "expected_details_formatted_address": null,
                        "expected_details_parsed_address": null,
                        "name_on_document": "OESTE EMBOTELLADORA S.A.",
                        "extra_fields": {
                          "bank_account_number": null,
                          "bank_iban": null,
                          "bank_sort_code": null,
                          "bank_routing_number": null,
                          "bank_swift_bic": null,
                          "bank_branch_name": null,
                          "bank_branch_address": null,
                          "document_phone_number": null,
                          "additional_names": [
                            "LA EMBOTELLADORA DEL NORTE SA"
                          ]
                        },
                        "status": "Declined",
                        "warnings": [
                          {
                            "risk": "POA_DOCUMENT_EXPIRED",
                            "feature": "PROOF_OF_ADDRESS",
                            "additional_data": {
                              "expiration_reason": "age_window",
                              "max_age_months": 3,
                              "document_subtype": "WATER_BILL",
                              "document_type": "UTILITY_BILL",
                              "issue_date": "2021-02-10"
                            },
                            "log_type": "error",
                            "short_description": "Document expired",
                            "long_description": "The submitted document is older than the maximum accepted age of 3 months from its issue date, which exceeds the acceptable time period for validity."
                          }
                        ]
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T02:23:02.165493+00:00"
                    }
                  },
                  "Declined - name mismatch": {
                    "summary": "`expected_first_name`/`expected_last_name`이 `name_on_document`와 일치하지 않음",
                    "value": {
                      "request_id": "0a7f2f9c-58f1-4b8e-b1e3-2f6f9d4f7a21",
                      "poa": {
                        "issuing_state": "ARG",
                        "document_type": "UTILITY_BILL",
                        "document_subtype": "WATER_BILL",
                        "document_language": "es",
                        "issuer": "Aguas del Norte",
                        "issue_date": "2021-02-10",
                        "expiration_date": null,
                        "poa_address": "AVDA. MONSEÑOR TAVELLA N° 1291, B° VILLA LAVALLE CP: 4400, CAPITAL - SALTA",
                        "poa_formatted_address": "Av. Monseñor Tavella 1291 b, A4400 Salta, Argentina",
                        "poa_parsed_address": {
                          "street_1": "Avenida Monseñor Tavella 1291",
                          "street_2": "b",
                          "city": "Salta",
                          "region": "Salta",
                          "country": "AR",
                          "postal_code": "A4400",
                          "document_location": {
                            "latitude": -24.8208682,
                            "longitude": -65.4130954
                          }
                        },
                        "expected_details_address": null,
                        "expected_details_formatted_address": null,
                        "expected_details_parsed_address": null,
                        "name_on_document": "OESTE EMBOTELLADORA S.A.",
                        "extra_fields": {
                          "bank_account_number": null,
                          "bank_iban": null,
                          "bank_sort_code": null,
                          "bank_routing_number": null,
                          "bank_swift_bic": null,
                          "bank_branch_name": null,
                          "bank_branch_address": null,
                          "document_phone_number": null,
                          "additional_names": [
                            "LA EMBOTELLADORA DEL NORTE SA"
                          ]
                        },
                        "status": "Declined",
                        "warnings": [
                          {
                            "risk": "NAME_MISMATCH_WITH_PROVIDED",
                            "feature": "PROOF_OF_ADDRESS",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Name mismatch with provided information",
                            "long_description": "The full name on the document does not match the name from the user's verified identity documents, or the full name sent by API."
                          }
                        ]
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T02:27:21.330172+00:00"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "`save_api_request=true`일 때 유지된 세션 ID(`GET /v3/session/{sessionId}/decision/`와 함께 사용 가능), 그렇지 않으면 임시 상관관계 UUID입니다."
                    },
                    "poa": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined"
                          ],
                          "description": "어떤 경고도 거부로 이어지지 않는 경우 `Approved`, 그렇지 않은 경우 `Declined`가 됩니다. `warnings` 목록에 이유가 설명되어 있습니다."
                        },
                        "issuing_state": {
                          "type": "string",
                          "nullable": true,
                          "description": "문서에서 추출된 문서 발급 국가 — 일반적으로 ISO 3166-1 alpha-3(예: `ARG`).",
                          "example": "ARG"
                        },
                        "document_type": {
                          "type": "string",
                          "enum": [
                            "UTILITY_BILL",
                            "BANK_STATEMENT",
                            "GOVERNMENT_ISSUED_DOCUMENT",
                            "OTHER_POA_DOCUMENT",
                            "UNKNOWN"
                          ],
                          "description": "감지된 문서 카테고리입니다. `UNKNOWN`은 문서를 유효한 주소 증명으로 분류할 수 없음을 의미하며 `INVALID_DOCUMENT_TYPE`과 함께 자동으로 거부됩니다. 절대 null이 될 수 없으며, 분류 실패 시 `UNKNOWN`으로 대체됩니다."
                        },
                        "document_subtype": {
                          "type": "string",
                          "description": "`document_type` 내의 세부 분류입니다(예: 공과금 청구서의 경우 `ELECTRICITY_BILL`, `WATER_BILL`, `GAS_BILL`, `INTERNET_BILL`, `PHONE_BILL`, 은행 명세서의 경우 `ACCOUNT_STATEMENT`, `CREDIT_CARD_STATEMENT`, 정부 문서의 경우 `TAX_ASSESSMENT`, `RESIDENCY_CERTIFICATE`). 하위 유형을 확인할 수 없는 경우 `UNKNOWN`입니다. 절대 null이 아니며, 분류 실패 시 `UNKNOWN`으로 대체됩니다.",
                          "example": "WATER_BILL"
                        },
                        "document_language": {
                          "type": "string",
                          "nullable": true,
                          "description": "감지된 문서 언어(ISO 639-1)입니다.",
                          "example": "es"
                        },
                        "issuer": {
                          "type": "string",
                          "nullable": true,
                          "description": "문서를 발급한 기업 또는 조직입니다. `null`인 경우 `ISSUER_NOT_IDENTIFIED`가 추가됩니다.",
                          "example": "Aguas del Norte"
                        },
                        "issue_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "description": "문서 발급일(`YYYY-MM-DD`)입니다. 추출할 수 없는 경우 `null`이며, 이 endpoint에서는 `UNABLE_TO_EXTRACT_ISSUE_DATE`로 거부됩니다.",
                          "example": "2021-02-10"
                        },
                        "expiration_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "description": "문서에 인쇄된 명시적 만료일/유효일(있는 경우)입니다. `poa_document_age_months` 기간 확인과는 별개입니다."
                        },
                        "poa_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "문서에 인쇄된 그대로의 주소입니다. `null`이면 `MISSING_ADDRESS_INFORMATION`으로 자동 거부됩니다."
                        },
                        "poa_formatted_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "`poa_address`의 지오코딩되고 정규화된 버전입니다.",
                          "example": "Av. Monseñor Tavella 1291 b, A4400 Salta, Argentina"
                        },
                        "poa_parsed_address": {
                          "type": "object",
                          "nullable": true,
                          "description": "문서 주소의 구조화된 지오코딩 세부 정보입니다. 주소를 파싱할 수 없는 경우 `null`입니다.",
                          "properties": {
                            "street_1": {
                              "type": "string",
                              "nullable": true,
                              "example": "Avenida Monseñor Tavella 1291"
                            },
                            "street_2": {
                              "type": "string",
                              "nullable": true
                            },
                            "city": {
                              "type": "string",
                              "nullable": true,
                              "example": "Salta"
                            },
                            "region": {
                              "type": "string",
                              "nullable": true,
                              "example": "Salta"
                            },
                            "country": {
                              "type": "string",
                              "nullable": true,
                              "description": "ISO 3166-1 alpha-2 국가 코드입니다.",
                              "example": "AR"
                            },
                            "postal_code": {
                              "type": "string",
                              "nullable": true,
                              "example": "A4400"
                            },
                            "document_location": {
                              "type": "object",
                              "nullable": true,
                              "properties": {
                                "latitude": {
                                  "type": "number"
                                },
                                "longitude": {
                                  "type": "number"
                                }
                              },
                              "description": "문서 주소의 지오코딩된 좌표입니다."
                            }
                          }
                        },
                        "expected_details_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "전송한 `expected_address`의 에코 값 또는 `null`입니다."
                        },
                        "expected_details_formatted_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "`expected_address`의 지오코딩되고 정규화된 버전입니다. 제공되지 않았거나 지오코딩할 수 없는 경우 `null`입니다."
                        },
                        "expected_details_parsed_address": {
                          "type": "object",
                          "nullable": true,
                          "additionalProperties": true,
                          "description": "`expected_address`에 대한 전체 지오코딩 결과(도로명/시/지역/국가/우편번호 및 원시 지오코더 출력과 `is_verified` 플래그). `expected_address`가 제공되지 않은 경우 `null`입니다."
                        },
                        "name_on_document": {
                          "type": "string",
                          "nullable": true,
                          "description": "문서에서 추출된 주 소지자 성명입니다. 제공된 경우 `expected_first_name`/`expected_last_name`과 비교됩니다. `null`인 경우 이 endpoint에서 `POA_NAME_NOT_DETECTED`와 함께 거부됩니다.",
                          "example": "OESTE EMBOTELLADORA S.A."
                        },
                        "extra_fields": {
                          "type": "object",
                          "description": "문서별 추가 항목입니다. 은행 관련 필드는 문서에 인쇄된 경우 은행 거래 내역서에 대해 채워지며, 그렇지 않은 경우 `null`입니다.",
                          "properties": {
                            "bank_account_number": {
                              "type": "string",
                              "nullable": true
                            },
                            "bank_iban": {
                              "type": "string",
                              "nullable": true
                            },
                            "bank_sort_code": {
                              "type": "string",
                              "nullable": true
                            },
                            "bank_routing_number": {
                              "type": "string",
                              "nullable": true
                            },
                            "bank_swift_bic": {
                              "type": "string",
                              "nullable": true
                            },
                            "bank_branch_name": {
                              "type": "string",
                              "nullable": true
                            },
                            "bank_branch_address": {
                              "type": "string",
                              "nullable": true
                            },
                            "document_phone_number": {
                              "type": "string",
                              "nullable": true,
                              "description": "문서에 인쇄된 연락처 전화번호입니다."
                            },
                            "additional_names": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "문서에서 발견된 다른 명의자 이름(예: 공동 계좌 명의자, 이전 계좌 이름)입니다."
                            }
                          }
                        },
                        "warnings": {
                          "type": "array",
                          "description": "문제없이 승인된 경우 비어 있습니다. 각 항목은 감지된 하나의 위험을 설명합니다. `log_type: \"error\"`인 항목은 `status`를 `Declined`로 설정합니다.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "description": "기계 판독 가능한 위험 코드입니다. 항상 거부: `MISSING_ADDRESS_INFORMATION`, `POA_DOCUMENT_EXPIRED`, `INVALID_DOCUMENT_TYPE`, `UNABLE_TO_VALIDATE_DOCUMENT_AGE` 및 `UNABLE_TO_EXTRACT_ISSUE_DATE`, `POA_NAME_NOT_DETECTED`(이 endpoint에서는 거부로 고정됨). 요청 옵션에 의해 제어됨: `NAME_MISMATCH_WITH_PROVIDED` / `ADDRESS_MISMATCH_WITH_PROVIDED` / `POA_COUNTRY_MISMATCH_WITH_PROVIDED`(`poa_address_mismatch_action`), `POOR_DOCUMENT_QUALITY`(이 endpoint에서는 생성되지 않음) / `DOCUMENT_METADATA_MISMATCH`(`poa_document_issues_action`), `SUSPECTED_DOCUMENT_MANIPULATION` 및 `POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT`(`poa_document_authenticity_action`), `UNSUPPORTED_DOCUMENT_LANGUAGE`(`poa_unsupported_language_action`), `ISSUER_NOT_IDENTIFIED`(`poa_issuer_not_identified_action`). 이 endpoint에서 정보 제공용: `POA_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION`, `UNPARSABLE_OR_INVALID_ADDRESS`.",
                                "example": "POA_DOCUMENT_EXPIRED"
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "PROOF_OF_ADDRESS"
                                ],
                                "description": "경고를 발생시킨 기능입니다. 이 엔드포인트에서는 항상 `PROOF_OF_ADDRESS`입니다."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "일부 위험에 대한 추가 컨텍스트 — 예: `POA_DOCUMENT_EXPIRED`에는 `expiration_reason`(`printed_expiration` 또는 `age_window`), `document_type`, `document_subtype`, `issue_date`가 포함되며, `printed_expiration` 경로에서는 `expiration_date`, `age_window` 경로에서는 `max_age_months`가 추가로 포함됩니다. `SUSPECTED_DOCUMENT_MANIPULATION`에는 `reason` 및 `detection_method`가 포함됩니다. `POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT`에는 `reason`, `detection_method`(`unproven_text_replacement`), `replaced_text`, `manipulated_regions`, `manipulated_blocks`가 포함됩니다. 대부분의 위험에 대해 `null`입니다."
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error",
                                  "information"
                                ],
                                "description": "심각도입니다. `error` 경고는 `status`를 `Declined`로 변경합니다. `information` 항목은 참고용이며 단독으로 거부되지 않습니다. (`warning`은 이 endpoint에서 생성되지 않습니다. 해당 옵션은 `DECLINE` 또는 `NO_ACTION`만 허용합니다.)"
                              },
                              "short_description": {
                                "type": "string",
                                "description": "사람이 읽을 수 있는 한 줄의 위험 요약입니다."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "위험에 대한 사람이 읽기 쉬운 설명입니다."
                              }
                            }
                          }
                        },
                        "detected_codes": {
                          "type": "array",
                          "description": "문서의 처리된 모든 페이지에서 감지된 QR 코드 및 바코드입니다. 발견되지 않으면 비어 있습니다. 위치는 식별되었으나 디코딩할 수 없는 QR 코드는 `parsed_payload: null`을 가집니다.",
                          "items": {
                            "$ref": "#/components/schemas/DocumentAIDetectedCode"
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "전송한 `vendor_data`의 에코 값 또는 `null`입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "전송한 `metadata` 객체의 에코 값 또는 `null`입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "응답이 생성된 시점의 ISO 8601 타임스탬프(UTC)입니다."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 또는 처리 오류입니다. 필드 수준의 문제는 DRF의 표준 엔벨로프(문제가 발생한 필드당 하나의 메시지 배열)를 반환합니다. 암호화된 PDF 문제는 `{\"detail\": ...}`를 반환합니다. 추출 파이프라인에서 처리할 수 없는 문서는 `{\"error\": [\"Error extracting POA information\"]}`를 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing document": {
                    "summary": "폼 데이터에 `document`가 포함되지 않음",
                    "value": {
                      "document": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Unsupported file extension": {
                    "summary": "tiff/jpg/jpeg/png/pdf/webp 이외의 파일 확장자",
                    "value": {
                      "document": [
                        "File extension “txt” is not allowed. Allowed extensions are: tiff, jpg, jpeg, png, pdf, webp."
                      ]
                    }
                  },
                  "File too large": {
                    "summary": "업로드가 15MB 제한을 초과함",
                    "value": {
                      "document": [
                        "File size should not exceed 15 MB"
                      ]
                    }
                  },
                  "Encrypted PDF": {
                    "summary": "필수 비밀번호 없이 업로드된 PDF입니다.",
                    "value": {
                      "detail": "The PDF is encrypted. Please upload a decrypted PDF or a photo instead."
                    }
                  },
                  "Wrong PDF password": {
                    "summary": "`document_password`로 PDF를 복호화할 수 없음",
                    "value": {
                      "detail": "The PDF password is incorrect. Please provide the correct password."
                    }
                  },
                  "Invalid language code": {
                    "summary": "`poa_languages_allowed`에 지원되지 않는 코드가 포함됨",
                    "value": {
                      "poa_languages_allowed": [
                        "Invalid language code: 'xx'. Must be one of the supported languages: ['ar', 'bn', 'hy', 'bg', 'bs', 'ca', 'cnr', 'sq', 'zh', 'hr', 'cs', 'da', 'nl', 'en', 'et', 'fi', 'fr', 'ka', 'kk', 'de', 'el', 'he', 'hi', 'hu', 'id', 'it', 'ja', 'ko', 'ky', 'lv', 'lt', 'mk', 'mn', 'ms', 'no', 'fa', 'pl', 'pt', 'ro', 'ru', 'sr', 'sk', 'sl', 'so', 'es', 'sv', 'th', 'tr', 'uk', 'uz', 'vi']."
                      ]
                    }
                  },
                  "Invalid document age value": {
                    "summary": "`poa_document_age_months` 값이 1–120 / -1 범위를 벗어남",
                    "value": {
                      "poa_document_age_months": [
                        "Invalid integer value for 'utility_bill': '999'. Must be -1 (unlimited) or a positive integer between 1 and 120."
                      ]
                    }
                  },
                  "Extraction failure": {
                    "summary": "추출 파이프라인에서 문서를 처리할 수 없습니다.",
                    "value": {
                      "error": [
                        "Error extracting POA information"
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었거나 호출한 조직의 잔액이 호출 비용을 충당할 수 없을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 키가 누락된 경우 `{\"detail\": ...}`과 함께 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 크레딧이 부족한 경우 어떠한 문서 처리도 진행되기 전에 `{\"error\": ...}`과 함께 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 호출 비용을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/DocumentProcessingBusy"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/poa/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'document=@./utility-bill.pdf' \\\n  -F 'expected_address=Av. Monseñor Tavella 1291, Salta, Argentina' \\\n  -F 'expected_country=ARG' \\\n  -F 'expected_first_name=Sophia' \\\n  -F 'expected_last_name=Martinez' \\\n  -F 'poa_languages_allowed=en,es' \\\n  -F 'vendor_data=user-123' \\\n  --max-time 45"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.proof_of_address.verify(\n    document=open(\"document.pdf\", \"rb\"),\n    expected_address=\"Av. Monseñor Tavella 1291, Salta, Argentina\",\n    expected_country=\"ARG\",\n    expected_first_name=\"Sophia\",\n    expected_last_name=\"Martinez\",\n    poa_languages_allowed=\"en,es\",\n    save_api_request=True,\n    vendor_data=\"user-123\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.proofOfAddress.verify({\n  document: await fileFromPath(\"document.pdf\"),\n  expected_address: \"Av. Monseñor Tavella 1291, Salta, Argentina\",\n  expected_country: \"ARG\",\n  expected_first_name: \"Sophia\",\n  expected_last_name: \"Martinez\",\n  poa_languages_allowed: \"en,es\",\n  save_api_request: true,\n  vendor_data: \"user-123\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.ProofOfAddress.Verify(ctx, didit.ProofOfAddressVerifyParams{\n\tDocument:            didit.FileFromPath(\"document.pdf\"),\n\tExpectedAddress:     didit.String(\"Av. Monseñor Tavella 1291, Salta, Argentina\"),\n\tExpectedCountry:     didit.String(\"ARG\"),\n\tExpectedFirstName:   didit.String(\"Sophia\"),\n\tExpectedLastName:    didit.String(\"Martinez\"),\n\tPOALanguagesAllowed: didit.String(\"en,es\"),\n\tSaveAPIRequest:      didit.Bool(true),\n\tVendorData:          didit.String(\"user-123\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.ProofOfAddressVerifyParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.proofOfAddress().verify(ProofOfAddressVerifyParams.builder()\n        .document(Path.of(\"document.pdf\"))\n        .expectedAddress(\"Av. Monseñor Tavella 1291, Salta, Argentina\")\n        .expectedCountry(\"ARG\")\n        .expectedFirstName(\"Sophia\")\n        .expectedLastName(\"Martinez\")\n        .poaLanguagesAllowed(\"en,es\")\n        .saveApiRequest(true)\n        .vendorData(\"user-123\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->proofOfAddress->verify([\n    'document' => File::fromPath('document.pdf'),\n    'expected_address' => 'Av. Monseñor Tavella 1291, Salta, Argentina',\n    'expected_country' => 'ARG',\n    'expected_first_name' => 'Sophia',\n    'expected_last_name' => 'Martinez',\n    'poa_languages_allowed' => 'en,es',\n    'save_api_request' => true,\n    'vendor_data' => 'user-123',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.proof_of_address.verify(\n  document: Pathname(\"document.pdf\"),\n  expected_address: \"Av. Monseñor Tavella 1291, Salta, Argentina\",\n  expected_country: \"ARG\",\n  expected_first_name: \"Sophia\",\n  expected_last_name: \"Martinez\",\n  poa_languages_allowed: \"en,es\",\n  save_api_request: true,\n  vendor_data: \"user-123\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.ProofOfAddress.VerifyAsync(new ProofOfAddressVerifyParams\n{\n    Document = FileUpload.FromPath(\"document.pdf\"),\n    ExpectedAddress = \"Av. Monseñor Tavella 1291, Salta, Argentina\",\n    ExpectedCountry = \"ARG\",\n    ExpectedFirstName = \"Sophia\",\n    ExpectedLastName = \"Martinez\",\n    PoaLanguagesAllowed = \"en,es\",\n    SaveApiRequest = true,\n    VendorData = \"user-123\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/document-ai/": {
      "post": {
        "summary": "Document AI(사용자 정의 필드 추출 + 위변조 검사)",
        "description": "한 번의 호출로 급여 명세서, 자금 증명, 자산 출처 확인서, 세금 명세서, 계약서, 청구서 등 모든 증빙 문서에서 **직접** 정의한 필드를 추출합니다. 파일과 함께 `fields` 정의(키, 이름, 추출 지침, 유형)를 전송하면 유형이 지정된 값(`text`, `number`, `YYYY-MM-DD` 형식의 `date`), 대상 개인 또는 기업에 대한 선택적 성명 일치 점수, PDF/EXIF 변조 신호, `Approved`/`Declined`/`In Review` `status`, 발견된 모든 문제를 설명하는 `warnings` 목록을 반환받습니다. 이는 호스팅 Document AI 워크플로 단계(`/core-technology/document-ai/overview` 참조)의 서버 간 대응 기능으로, Didit의 기본 추출 모델을 사용하며 제공업체 선택 기능은 제공하지 않습니다.\n\n**지연 시간.** 추출은 LLM 기반으로 수행됩니다. 일반적인 호출은 **5–15초**, 여러 페이지로 구성된 PDF는 **최대 약 30초**가 소요됩니다. 클라이언트 타임아웃을 **최소 45초**로 구성하고 호출이 완료되기 전에는 재시도하지 마십시오.\n\n**요청 형식.** `multipart/form-data`만 지원됩니다. `fields`는 **하나의 JSON 인코딩된 배열 문자열**(1–30개 항목, 최대 16 KB)이어야 하며 대괄호 스타일의 폼 배열은 `400`으로 거부됩니다. 각 항목은 `{key, name, instruction, type, required, is_full_name}` 형식입니다. `key`는 반환받을 JSON 키(`^[a-z0-9_]{1,64}$`, 고유값), `instruction`은 모델이 읽어야 할 내용을 안내하는 지침, `type`은 `text`(기본값) | `number` | `date`, `required`는 값을 읽을 수 없을 때 `DOCUMENT_AI_MISSING_REQUIRED_FIELDS`를 발생시키는 플래그이며, 최대 하나의 필드만 `is_full_name: true`로 설정하여 예상 성명과 비교할 값을 지정할 수 있습니다.\n\n**성명 일치.** `expected_first_name` + `expected_last_name`(개인) **또는** `expected_company_name`(+ 선택적 `expected_company_country`)을 전달해야 하며 둘 다 전달할 수는 없습니다. `is_full_name` 필드의 값(또는 지정된 필드가 없는 경우 성명처럼 보이는 키를 가진 첫 번째 텍스트 필드)을 퍼지 방식으로 비교합니다. 양쪽 값이 모두 존재하면 `name_match_score`(0–100)와 `name_on_document`가 항상 반환되며, 점수가 `document_ai_name_match_score_threshold`(기본값 80) 미만인 경우 `document_ai_name_mismatch_action`의 설정을 따르는 `DOCUMENT_AI_NAME_MISMATCH`가 추가됩니다.\n\n**결정 로직.** 각 위험은 구성 가능한 작업에 매핑됩니다. `DECLINE` → `status: \"Declined\"`, `REVIEW` → `status: \"In Review\"`, `NO_ACTION` → 정보 제공 전용. 기본값은 워크플로 단계를 그대로 반영합니다. 읽을 수 없는 문서 `REVIEW`, 필수 필드 누락 `REVIEW`, 조작 의심 `DECLINE`, 성명 불일치 `NO_ACTION`, 지원되지 않는 파일 `REVIEW`. 전혀 처리할 수 없는 문서는 `400`을 반환합니다. 읽을 수 있지만 문제가 있는 문서는 `Declined`/`In Review`와 함께 `200`을 반환하므로 HTTP 코드뿐만 아니라 항상 `document_ai.status`와 `document_ai.warnings`를 확인하십시오.\n\n**결제.** 각 `200` 응답은 하나의 Document AI API 크레딧을 소비합니다(정가 기준 **문서당 $0.20**). 요금제 크레딧 또는 충전 잔액에서 차감됩니다. 조직의 잔액으로 호출 비용을 충당할 수 없는 경우 endpoint는 처리를 시작하기 전에 `403`을 반환합니다. 샌드박스 API 키는 결정론적 모의 응답을 반환하며 비용이 청구되지 않습니다.\n\n**영속성.** `save_api_request=true`(기본값)를 사용하면 호출이 API 유형 세션으로 저장됩니다. 문서, 추출된 값, 필드 정의 및 성명 일치 스냅샷이 보존되고 세션이 Business Console에 표시되며 `request_id`를 `GET /v3/session/{sessionId}/decision/`과 함께 사용할 수 있습니다.",
        "operationId": "post_v3document-ai",
        "x-didit-sdk": {
          "resource": "document_ai",
          "method": "analyze",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "document",
                  "fields"
                ],
                "properties": {
                  "document": {
                    "type": "string",
                    "format": "binary",
                    "description": "판독할 문서입니다. 허용되는 확장자: `tiff`, `jpg`, `jpeg`, `png`, `pdf`, `webp`, `zip`. 최대 업로드 크기: **30 MB**(더 큰 파일은 `400`으로 거부됨). 다중 페이지 PDF가 지원됩니다(지연 시간이 길어질 수 있음). 암호화된 PDF는 `400`으로 거부됩니다. 이미지는 처리 전에 자동으로 압축됩니다."
                  },
                  "fields": {
                    "type": "string",
                    "description": "**1–30**개의 필드 정의가 포함된 JSON 인코딩 배열 문자열(최대 16KB)입니다. 각 항목: `key`(필수, `^[a-z0-9_]{1,64}$`, 고유값 — `extracted_data`에서 반환되는 키), `name`(100자 이하, 메시지에 표시됨), `instruction`(500자 이하, 모델이 읽어야 하는 내용), `type`(기본값 `text` | `number` | `date`), `required`(부울, 기본값 `false`), `is_full_name`(부울, 기본값 `false`, 요청당 최대 1개). 대괄호 스타일 폼 배열, 잘못된 JSON, 중복된 키 또는 둘 이상의 `is_full_name`은 처리나 결제가 진행되기 전에 `400`을 반환합니다.",
                    "example": "[{\"key\": \"employer_name\", \"name\": \"Employer name\", \"instruction\": \"The employer or company issuing the payslip.\", \"type\": \"text\", \"required\": true, \"is_full_name\": false}, {\"key\": \"employee_name\", \"name\": \"Employee name\", \"instruction\": \"The full name of the employee as printed on the payslip.\", \"type\": \"text\", \"required\": true, \"is_full_name\": true}, {\"key\": \"net_pay\", \"name\": \"Net pay\", \"instruction\": \"The net amount paid to the employee for the period.\", \"type\": \"number\", \"required\": true, \"is_full_name\": false}, {\"key\": \"pay_date\", \"name\": \"Pay date\", \"instruction\": \"The payment date shown on the payslip.\", \"type\": \"date\", \"required\": false, \"is_full_name\": false}]"
                  },
                  "expected_first_name": {
                    "type": "string",
                    "description": "문서의 이름 필드와 대조하여 검증할 이름입니다(퍼지 일치, 음차 인식). `expected_last_name`과 함께 사용해야 하며, `expected_company_name`과 결합할 수 없습니다.",
                    "example": "Sophia"
                  },
                  "expected_last_name": {
                    "type": "string",
                    "description": "문서의 이름 필드와 대조하여 검증할 성으로, `name_match_score`를 위해 `expected_first_name`과 결합됩니다.",
                    "example": "Martinez"
                  },
                  "expected_company_name": {
                    "type": "string",
                    "description": "문서의 이름 필드와 대조하여 확인할 기업명입니다(기업 문서용). `expected_first_name` / `expected_last_name`과 함께 사용할 수 없습니다(예시 값은 의도적으로 제공되지 않음 — 생성된 요청 샘플에는 개인 필드가 사용되므로, 기업 문서를 확인할 때는 이 필드로 교체하십시오)."
                  },
                  "expected_company_country": {
                    "type": "string",
                    "description": "`expected_company_name`에 대한 기업명 정규화를 조정하는 선택적 ISO 3166-1 alpha-2 국가 코드(ASCII 2글자, 예: `FR`)입니다. `expected_company_name`과 함께만 사용됩니다."
                  },
                  "document_ai_name_match_score_threshold": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 80,
                    "description": "이름이 일치하는 것으로 간주하기 위한 최소 `name_match_score`(0–100)입니다. 점수가 이보다 낮으면 `DOCUMENT_AI_NAME_MISMATCH`가 추가되며, `document_ai_name_mismatch_action`의 제어를 받습니다.",
                    "example": 80
                  },
                  "document_ai_unreadable_document_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "REVIEW",
                      "NO_ACTION"
                    ],
                    "default": "REVIEW",
                    "description": "문서에서 어떤 필드도 읽을 수 없을 때(`DOCUMENT_AI_UNREADABLE_DOCUMENT`) 수행할 작업입니다."
                  },
                  "document_ai_missing_required_fields_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "REVIEW",
                      "NO_ACTION"
                    ],
                    "default": "REVIEW",
                    "description": "`required` 필드 중 하나 이상을 읽을 수 없을 때(`DOCUMENT_AI_MISSING_REQUIRED_FIELDS`, 해당 필드는 `additional_data.missing_fields`에 나열됨) 수행할 작업입니다."
                  },
                  "document_ai_document_tampering_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "REVIEW",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "PDF/EXIF 포렌식에서 전자 서명 후 수정, 알려진 PDF 편집기 사용, 오버레이 텍스트 조작, 의심스러운 재내보내기, 이미지 이상 현상 등 위변조가 의심될 때(`DOCUMENT_AI_SUSPECTED_MANIPULATION`) 수행할 작업입니다."
                  },
                  "document_ai_name_mismatch_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "REVIEW",
                      "NO_ACTION"
                    ],
                    "default": "NO_ACTION",
                    "description": "`name_match_score`가 임계값 미만일 때(`DOCUMENT_AI_NAME_MISMATCH`) 수행할 작업입니다."
                  },
                  "document_ai_unsupported_file_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "REVIEW",
                      "NO_ACTION"
                    ],
                    "default": "REVIEW",
                    "description": "업로드된 항목이 비어 있거나 처리할 수 없는 파일일 때 수행할 작업입니다 (`DOCUMENT_AI_UNSUPPORTED_FILE`)."
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "`true`(기본값)인 경우 호출을 API 유형 세션으로 저장합니다. Business Console에서 확인할 수 있고 반환된 `request_id`를 사용하여 `GET /v3/session/{sessionId}/decision/`을 통해 조회할 수 있으며 업로드된 문서, 추출된 값, 필드 정의 및 이름 일치 스냅샷이 저장됩니다. `false`인 경우 아무것도 저장되지 않고 `request_id`는 응답 상관관계 식별 전용의 일시적인 UUID이지만 호출에 대한 요금은 여전히 청구됩니다.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "저장된 세션에 저장되고 응답에 다시 반환되는 선택적 불투명 문자열(내부 사용자 ID, 이메일, UUID 등)입니다. API 호출을 자체 기록과 연관 짓고 나중에 세션을 필터링하는 데 사용합니다.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "세션과 함께 저장되고(`save_api_request=true`인 경우) 응답에 그대로 반환되는 선택적 JSON 객체입니다. multipart 요청에서는 JSON 인코딩된 문자열 필드(예: `metadata={\"flow\":\"onboarding\"}`)로 전송하십시오. 객체로 파싱됩니다.",
                    "example": {
                      "flow": "onboarding"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "문서가 처리되었습니다. `document_ai.status`는 `Approved`, `Declined` 또는 `In Review`입니다. 감지된 모든 문제는 `document_ai.warnings`에 항목별로 나열됩니다. 문제가 있는 문서라도 `200`을 반환하므로 HTTP 코드뿐만 아니라 본문도 검사해야 합니다. `save_api_request=true`인 경우 `request_id`는 저장된 세션 ID입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Approved": {
                    "summary": "급여 명세서가 정상적으로 판독되었으며 성명이 일치함",
                    "value": {
                      "request_id": "9d6a3b1e-2f0c-4a8e-9b7d-1c2e3f4a5b6c",
                      "document_ai": {
                        "status": "Approved",
                        "extracted_data": {
                          "employer_name": "Acme Payments Ltd",
                          "employee_name": "Sophia Martinez",
                          "net_pay": 3120.5,
                          "pay_date": "2026-07-31"
                        },
                        "detected_codes": [
                          {
                            "type": "CODE_128",
                            "page_number": 1,
                            "position": [
                              [
                                96,
                                456
                              ],
                              [
                                96,
                                616
                              ],
                              [
                                1012,
                                611
                              ],
                              [
                                1015,
                                456
                              ]
                            ],
                            "x": 96,
                            "y": 456,
                            "width": 919,
                            "height": 160,
                            "page_width": 1200,
                            "page_height": 1700,
                            "raw_payload": "SU5WLTIwMjYtMDA0Mg==",
                            "parsed_payload": "INV-2026-0042"
                          }
                        ],
                        "fields": [
                          {
                            "key": "employer_name",
                            "name": "Employer name",
                            "instruction": "The employer or company issuing the payslip.",
                            "type": "text",
                            "required": true,
                            "is_full_name": false
                          },
                          {
                            "key": "employee_name",
                            "name": "Employee name",
                            "instruction": "The full name of the employee as printed on the payslip.",
                            "type": "text",
                            "required": true,
                            "is_full_name": true
                          },
                          {
                            "key": "net_pay",
                            "name": "Net pay",
                            "instruction": "The net amount paid to the employee for the period.",
                            "type": "number",
                            "required": true,
                            "is_full_name": false
                          },
                          {
                            "key": "pay_date",
                            "name": "Pay date",
                            "instruction": "The payment date shown on the payslip.",
                            "type": "date",
                            "required": false,
                            "is_full_name": false
                          }
                        ],
                        "name_match_score": 100.0,
                        "name_on_document": "Sophia Martinez",
                        "warnings": []
                      },
                      "vendor_data": "user-123",
                      "metadata": {
                        "flow": "onboarding"
                      },
                      "created_at": "2026-08-19T16:40:12.318Z"
                    }
                  },
                  "In Review — missing required field": {
                    "summary": "`net_pay`를 읽을 수 없습니다. 기본 작업 REVIEW",
                    "value": {
                      "request_id": "3f2a9c7b-5d4e-4b1a-8c6f-0e9d8c7b6a5f",
                      "document_ai": {
                        "status": "In Review",
                        "extracted_data": {
                          "employer_name": "Acme Payments Ltd",
                          "employee_name": "Sophia Martinez",
                          "net_pay": null,
                          "pay_date": "2026-07-31"
                        },
                        "detected_codes": [],
                        "fields": [
                          {
                            "key": "employer_name",
                            "name": "Employer name",
                            "instruction": "The employer or company issuing the payslip.",
                            "type": "text",
                            "required": true,
                            "is_full_name": false
                          },
                          {
                            "key": "employee_name",
                            "name": "Employee name",
                            "instruction": "The full name of the employee as printed on the payslip.",
                            "type": "text",
                            "required": true,
                            "is_full_name": true
                          },
                          {
                            "key": "net_pay",
                            "name": "Net pay",
                            "instruction": "The net amount paid to the employee for the period.",
                            "type": "number",
                            "required": true,
                            "is_full_name": false
                          },
                          {
                            "key": "pay_date",
                            "name": "Pay date",
                            "instruction": "The payment date shown on the payslip.",
                            "type": "date",
                            "required": false,
                            "is_full_name": false
                          }
                        ],
                        "name_match_score": 100.0,
                        "name_on_document": "Sophia Martinez",
                        "warnings": [
                          {
                            "risk": "DOCUMENT_AI_MISSING_REQUIRED_FIELDS",
                            "feature": "DOCUMENT_AI",
                            "additional_data": {
                              "missing_fields": [
                                "Net pay"
                              ]
                            },
                            "log_type": "warning",
                            "short_description": "Required fields could not be extracted",
                            "long_description": "One or more fields configured as required could not be extracted from the uploaded document."
                          }
                        ]
                      },
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-08-19T16:41:05.002Z"
                    }
                  },
                  "Declined — suspected manipulation": {
                    "summary": "PDF 포렌식에서 알려진 편집기를 감지했습니다. 기본 작업은 거부(DECLINE)입니다.",
                    "value": {
                      "request_id": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                      "document_ai": {
                        "status": "Declined",
                        "extracted_data": {
                          "employer_name": "Acme Payments Ltd",
                          "employee_name": "Sophia Martinez",
                          "net_pay": 3120.5,
                          "pay_date": "2026-07-31"
                        },
                        "detected_codes": [],
                        "fields": [
                          {
                            "key": "employer_name",
                            "name": "Employer name",
                            "instruction": "The employer or company issuing the payslip.",
                            "type": "text",
                            "required": true,
                            "is_full_name": false
                          },
                          {
                            "key": "employee_name",
                            "name": "Employee name",
                            "instruction": "The full name of the employee as printed on the payslip.",
                            "type": "text",
                            "required": true,
                            "is_full_name": true
                          },
                          {
                            "key": "net_pay",
                            "name": "Net pay",
                            "instruction": "The net amount paid to the employee for the period.",
                            "type": "number",
                            "required": true,
                            "is_full_name": false
                          },
                          {
                            "key": "pay_date",
                            "name": "Pay date",
                            "instruction": "The payment date shown on the payslip.",
                            "type": "date",
                            "required": false,
                            "is_full_name": false
                          }
                        ],
                        "name_match_score": null,
                        "name_on_document": "Sophia Martinez",
                        "warnings": [
                          {
                            "risk": "DOCUMENT_AI_SUSPECTED_MANIPULATION",
                            "feature": "DOCUMENT_AI",
                            "additional_data": {
                              "detection_method": "known_editor",
                              "processed_by_known_editor": "ilovepdf"
                            },
                            "log_type": "error",
                            "short_description": "Suspected document manipulation",
                            "long_description": "The system detected signs of potential manipulation or editing in the uploaded document."
                          }
                        ]
                      },
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-08-19T16:42:40.771Z"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "`save_api_request=true`일 때 유지된 세션 ID(`GET /v3/session/{sessionId}/decision/`와 함께 사용 가능), 그렇지 않으면 임시 상관관계 UUID입니다."
                    },
                    "document_ai": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined",
                            "In Review"
                          ],
                          "description": "어떤 경고도 거부나 검토로 이어지지 않는 경우 `Approved`, 하나 이상의 위험 요소가 `DECLINE`에 매핑되는 경우 `Declined`, 그 외에 하나 이상의 위험 요소가 `REVIEW`에 매핑되는 경우 `In Review`가 됩니다. `warnings` 목록에 이유가 설명되어 있습니다."
                        },
                        "extracted_data": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "요청된 필드 키당 항목 1개입니다. 값은 필드 `type`에 따라 유형이 지정되며(`text`의 경우 문자열, `number`의 경우 숫자, `date`의 경우 `YYYY-MM-DD` 문자열), 값을 읽을 수 없는 경우 `null`입니다.",
                          "example": {
                            "employer_name": "Acme Payments Ltd",
                            "employee_name": "Sophia Martinez",
                            "net_pay": 3120.5,
                            "pay_date": "2026-07-31"
                          }
                        },
                        "detected_codes": {
                          "type": "array",
                          "description": "처리된 모든 페이지에서 감지된 QR 코드 및 바코드입니다. 발견되지 않으면 비어 있습니다. 위치는 식별되었으나 디코딩할 수 없는 QR 코드는 `parsed_payload: null`을 가집니다.",
                          "items": {
                            "$ref": "#/components/schemas/DocumentAIDetectedCode"
                          }
                        },
                        "fields": {
                          "type": "array",
                          "description": "이 추출에 사용된 정규화된 필드 정의이며, 그대로 반환됩니다(`save_api_request=true`인 경우 세션과 함께 저장되기도 함).",
                          "items": {
                            "type": "object",
                            "properties": {
                              "key": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "instruction": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string",
                                "enum": [
                                  "text",
                                  "number",
                                  "date"
                                ]
                              },
                              "required": {
                                "type": "boolean"
                              },
                              "is_full_name": {
                                "type": "boolean"
                              }
                            }
                          }
                        },
                        "name_match_score": {
                          "type": "number",
                          "nullable": true,
                          "minimum": 0,
                          "maximum": 100,
                          "description": "`name_on_document`와 예상되는 개인/기업 이름 간의 퍼지 유사도(0–100)입니다. 이름 값과 예상 이름이 모두 존재할 때 일치 **및** 불일치 시 항상 반환되며, 그렇지 않은 경우 `null`입니다.",
                          "example": 96.0
                        },
                        "name_on_document": {
                          "type": "string",
                          "nullable": true,
                          "description": "예상 이름과 비교된 문서에서 가져온 이름 값(`is_full_name` 필드 또는 이름과 유사한 첫 번째 텍스트 필드)입니다. 사용할 수 있는 이름 값이 없는 경우 `null`입니다.",
                          "example": "Sophia Martinez"
                        },
                        "warnings": {
                          "type": "array",
                          "description": "문제없이 승인된 경우 비어 있습니다. 각 항목은 감지된 하나의 위험을 설명합니다. `log_type: \"error\"`인 항목은 `status`를 `Declined`로 설정하고, `log_type: \"warning\"`인 항목은 `In Review`로 설정합니다.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "enum": [
                                  "DOCUMENT_AI_UNREADABLE_DOCUMENT",
                                  "DOCUMENT_AI_MISSING_REQUIRED_FIELDS",
                                  "DOCUMENT_AI_SUSPECTED_MANIPULATION",
                                  "DOCUMENT_AI_NAME_MISMATCH",
                                  "DOCUMENT_AI_UNSUPPORTED_FILE"
                                ],
                                "description": "기계 판독 가능한 위험 코드입니다. 각각은 일치하는 `document_ai_*_action` 요청 옵션에 의해 제어됩니다.",
                                "example": "DOCUMENT_AI_MISSING_REQUIRED_FIELDS"
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "DOCUMENT_AI"
                                ],
                                "description": "경고를 발생시킨 기능입니다. 이 endpoint에서는 항상 `DOCUMENT_AI`입니다."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "위험에 대한 추가 컨텍스트입니다. 필수 필드가 누락된 경우 `{\"missing_fields\": [\"Net pay\"]}`, 이름 불일치의 경우 `{\"name_on_document\", \"score\", \"threshold\"}`, 위조 의심의 경우 포렌식 결과(`detection_method`, 생성자/편집자 세부 정보)가 포함됩니다. 추가할 내용이 없는 경우 `null`입니다.",
                                "example": {
                                  "missing_fields": [
                                    "Net pay"
                                  ]
                                }
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error",
                                  "warning",
                                  "information"
                                ],
                                "description": "구성된 작업에서 파생된 심각도: `error`(DECLINE), `warning`(REVIEW), `information`(NO_ACTION)."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "사람이 읽을 수 있는 한 줄의 위험 요약입니다.",
                                "example": "Required fields could not be extracted"
                              },
                              "long_description": {
                                "type": "string",
                                "description": "해당하는 경우 `additional_data`가 삽입된 사람이 읽기 쉬운 설명입니다."
                              }
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "전송한 `vendor_data`의 에코 값 또는 `null`입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "전송한 `metadata` 객체의 에코 값 또는 `null`입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "요청이 처리된 시점(UTC, ISO 8601)."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 또는 처리 오류입니다. 필드 수준의 문제는 DRF의 표준 엔벨로프(문제가 발생한 필드당 하나의 메시지 배열)를 반환합니다. 암호화되었거나 읽을 수 없는 문서 및 추출 실패는 `{\"error\": ...}`를 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing document": {
                    "summary": "폼 데이터에 `document`가 포함되지 않음",
                    "value": {
                      "document": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Invalid fields payload": {
                    "summary": "`fields`가 JSON 인코딩된 단일 배열 문자열이 아님",
                    "value": {
                      "fields": [
                        "fields must be a valid JSON array string."
                      ]
                    }
                  },
                  "Duplicate field keys": {
                    "summary": "두 항목이 동일한 `key`를 공유합니다",
                    "value": {
                      "fields": [
                        "Every fields item must have a unique key."
                      ]
                    }
                  },
                  "Conflicting expectations": {
                    "summary": "개인 및 기업 기대치가 함께 전송됨",
                    "value": {
                      "non_field_errors": [
                        "Provide either person expected-name fields or expected_company_name, not both."
                      ]
                    }
                  },
                  "Invalid metadata": {
                    "summary": "`metadata`가 JSON 객체가 아니거나 NUL 문자를 포함합니다.",
                    "value": {
                      "metadata": [
                        "Metadata must be a JSON object."
                      ]
                    }
                  },
                  "Oversized vendor_data": {
                    "summary": "`vendor_data`가 2,000바이트 한도를 초과했습니다.",
                    "value": {
                      "vendor_data": [
                        "vendor_data is too long (maximum 2000 bytes)."
                      ]
                    }
                  },
                  "Encrypted PDF": {
                    "summary": "비밀번호로 보호된 PDF",
                    "value": {
                      "error": "The PDF is encrypted. Please upload a decrypted PDF or a photo instead."
                    }
                  },
                  "Extraction failed": {
                    "summary": "추출 파이프라인에서 문서를 처리할 수 없습니다",
                    "value": {
                      "error": [
                        "Error extracting Document AI information"
                      ]
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었거나 호출한 조직의 잔액이 호출 비용을 충당할 수 없을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 키가 누락된 경우 `{\"detail\": ...}`과 함께 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 크레딧이 부족한 경우, 그리고 요금표에 Document AI API 항목이 없는 계약 청구 조직의 경우 어떠한 문서 처리도 진행되기 전에 `{\"error\": ...}`과 함께 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 호출 비용을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  },
                  "Contract rate missing": {
                    "summary": "요금표에 Document AI API 항목이 없는 계약 결제 방식의 조직",
                    "value": {
                      "error": "Document AI API is not included in your contract rate card. Contact support@didit.me to enable it."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/DocumentProcessingBusy"
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.document_ai.analyze(\n    document=open(\"document.pdf\", \"rb\"),\n    fields=\"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.documentAi.analyze({\n  document: await fileFromPath(\"document.pdf\"),\n  fields: \"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.DocumentAi.Analyze(ctx, didit.DocumentAiAnalyzeParams{\n\tDocument: didit.FileFromPath(\"document.pdf\"),\n\tFields:   \"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.DocumentAiAnalyzeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.documentAi().analyze(DocumentAiAnalyzeParams.builder()\n        .document(Path.of(\"document.pdf\"))\n        .fields(\"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->documentAi->analyze([\n    'document' => File::fromPath('document.pdf'),\n    'fields' => '[{\"key\": \"employer_name\", \"name\": \"Employer name\", \"instruction\": \"The employer or company issuing the payslip.\", \"type\": \"text\", \"required\": true, \"is_full_name\": false}, {\"key\": \"employee_name\", \"name\": \"Employee name\", \"instruction\": \"The full name of the employee as printed on the payslip.\", \"type\": \"text\", \"required\": true, \"is_full_name\": true}, {\"key\": \"net_pay\", \"name\": \"Net pay\", \"instruction\": \"The net amount paid to the employee for the period.\", \"type\": \"number\", \"required\": true, \"is_full_name\": false}, {\"key\": \"pay_date\", \"name\": \"Pay date\", \"instruction\": \"The payment date shown on the payslip.\", \"type\": \"date\", \"required\": false, \"is_full_name\": false}]',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.document_ai.analyze(\n  document: Pathname(\"document.pdf\"),\n  fields: \"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.DocumentAi.AnalyzeAsync(new DocumentAiAnalyzeParams\n{\n    Document = FileUpload.FromPath(\"document.pdf\"),\n    Fields = \"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/aml/": {
      "post": {
        "summary": "AML 스크리닝(독립형)",
        "operationId": "post_v3aml",
        "x-didit-sdk": {
          "resource": "aml",
          "method": "screen",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "선택 사항인 재시도 안전 키로, 최대 255자입니다. 동일한 요청 본문으로 동일한 키를 재사용하면 두 번째 스크리닝을 실행하거나 결제하지 않고 원래 응답을 반환합니다. 다른 본문으로 키를 재사용하면 `409`를 반환합니다.",
            "schema": {
              "type": "string",
              "maxLength": 255
            }
          }
        ],
        "description": "단 한 번의 호출로 개인 또는 기업을 PEP, 제재, 경고/감시 목록 및 부정적 언론 보도 데이터셋에 대해 스크리닝합니다.\n\n**이중 점수 모델.** 각 적중 항목에는 `match_score`(0–100, 신원 신뢰도) 및 `risk_score`(0–100, 엔티티 위험도)가 부여됩니다. `match_score`가 `aml_match_score_threshold`(기본값 **93**) 미만인 적중 항목은 `review_status: \"False Positive\"`로 태그 지정되며 위험도 산정에서 제외됩니다. 남은 적중 항목 중 가장 높은 `risk_score`가 `aml.score`가 됩니다. 최종 `aml.status`는 설정된 임계값을 따릅니다. `score` > `aml_score_review_threshold`(기본값 **100**) → `Declined`, `score` > `aml_score_approve_threshold`(기본값 **80**) → `In Review`, 그 외에는 `Approved`입니다. `score`가 0이 아니고 승인 임계값 이상일 때마다 `POSSIBLE_MATCH_FOUND` 경고가 추가됩니다(점수가 정확히 0이면 경고가 발생하지 않음).\n\n**일치 점수 가중치.** `aml_name_weight` + `aml_dob_weight` + `aml_country_weight`의 합은 정확히 100이어야 합니다(기본값 60/25/15). 요청에서 누락된 구성 요소는 재정규화되어 제외되며, 일치하는 `document_number`는 `match_score`를 100으로 덮어쓰는 골든 키 역할을 합니다.\n\n**지연 시간.** 일반 스크리닝은 일반적으로 수 초 내에 완료됩니다. `include_adverse_media=true`인 경우 API는 부정적 언론 보도 데이터 보강을 대기하므로(초기 약 5초 일시 중지 후 최대 약 25초 동안 폴링), 클라이언트 타임아웃을 **최소 60초**로 구성하십시오.\n\n**영속성.** `save_api_request`의 기본값은 **true**입니다. 스크리닝은 세션으로 저장되며(`request_id`는 `GET /v3/session/{sessionId}/decision/`에서 사용 가능), 콘솔에 표시되고, `status.updated` webhook이 발생하며, 적중 항목의 검토 상태를 나중에 업데이트할 수 있습니다. `save_api_request=false`인 경우 아무것도 저장되지 않으며 `request_id`는 일시적인 상관 관계 ID로 사용됩니다. `include_ongoing_monitoring=true`는 프로필을 지속적으로 재스크리닝하며 `save_api_request=true`가 필요합니다(`400`으로 강제됨).\n\n**멱등성.** 타임아웃 또는 일시적 오류 발생 후 재시도할 때 `Idempotency-Key` 헤더를 전송하십시오. 키의 범위는 애플케이션 및 정확한 요청 본문으로 제한됩니다. 처음에 완료된 요청은 응답을 저장하며, 이후 동일한 재시도는 해당 응답을 그대로 반환하고 다른 AML 스크리닝을 실행하거나 요금을 청구하지 않습니다. 원래 요청이 아직 실행 중인 경우 동일한 키로 나중에 다시 시도하십시오. 다른 본문에 동일한 키가 재사용되면 API는 `409`를 반환합니다.\n\n**결제.** 첫 번째 성공적인 스크리닝 후 AML API 크레딧 1개가 청구됩니다. 멱등성 재요청으로 반환된 응답에는 다시 청구되지 않으며, 잔액이 부족하면 새로운 스크리닝이 수행되기 전에 `403`이 반환됩니다.\n\n**샌드박스.** 샌드박스 애플케이션의 키는 스크리닝 및 결제를 완전히 건너뛰고 모의 결과(`sandbox_scenario`를 전달하지 않는 한 적중 항목이 없는 `Approved`)를 반환합니다. `save_api_request`는 프로덕션 키와 동일하게 작동하므로 저장된 샌드박스 스크리닝은 `GET /v3/session/{sessionId}/decision/` 및 `GET /v3/session/{sessionId}/generate-pdf/`를 통해 조회할 수 있습니다.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "full_name"
                ],
                "properties": {
                  "full_name": {
                    "type": "string",
                    "minLength": 2,
                    "description": "스크리닝할 개인 또는 기업의 성명입니다. 최소 **2자**여야 합니다(스크리닝 제공업체 자체 기준 하한선). 이름이 이보다 짧거나 비어 있으면 스크리닝이 실행되기 전에 이 필드에서 `400`을 반환하므로 비용이 청구되지 않습니다.",
                    "example": "Antonio Ejemplo Modelo"
                  },
                  "entity_type": {
                    "type": "string",
                    "enum": [
                      "person",
                      "company"
                    ],
                    "default": "person",
                    "description": "스크리닝할 엔티티 유형입니다. 기본값은 `person`입니다."
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "description": "생년월일(개인) 또는 법인 설립일(기업), `YYYY-MM-DD`입니다. 생년월일 가중치를 통해 일치 정밀도를 향상시킵니다.",
                    "example": "1972-02-29"
                  },
                  "nationality": {
                    "type": "string",
                    "description": "ISO 3166-1 **alpha-2** 국가 코드(예: `ES`)입니다. 유효하지 않은 코드는 `400`을 반환합니다. 국가 가중치를 통해 일치 정확도를 향상시킵니다.",
                    "example": "ES"
                  },
                  "document_number": {
                    "type": "string",
                    "description": "신분증 번호입니다. 가중치가 부여되지 않으며 골든 키 역할을 합니다. 정확히 일치하면 히트의 `match_score`를 100으로 재정의하고, 명백히 불일치하면 패널티를 부여합니다. **2~50자**인 경우에만 스크리닝 제공업체에 검색 필터로 전송됩니다. 이 범위를 벗어나는 값도 허용 및 저장되며 스크리닝은 계속 실행되고 요금이 청구되지만 신분증 번호로 좁혀지지는 않습니다."
                  },
                  "aml_score_approve_threshold": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 80,
                    "description": "이 값 이하일 때 결과가 `Approved`가 되는 위험 점수 임계값입니다. `aml_score_review_threshold` 이하이어야 합니다(그렇지 않으면 `400`)."
                  },
                  "aml_score_review_threshold": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 100,
                    "description": "결과가 `Declined`로 처리되는 기준 위험 점수 임계값입니다. 두 임계값 사이의 점수는 결과를 `In Review`로 만듭니다."
                  },
                  "aml_name_weight": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 60,
                    "description": "적중 결과별 일치 점수에서 이름 유사도의 가중치입니다. 세 가중치의 합은 정확히 100이어야 합니다(그렇지 않으면 `400`)."
                  },
                  "aml_dob_weight": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 25,
                    "description": "적중 결과별 일치 점수에서 생년월일의 가중치입니다."
                  },
                  "aml_country_weight": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 15,
                    "description": "적중 결과별 일치 점수에서 국가/국적의 가중치입니다."
                  },
                  "aml_match_score_threshold": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 93,
                    "description": "적중 항목별 컷오프: `match_score`가 이 값 미만인 적중 항목은 `False Positive`(위험 평가에서 제외됨)가 되며, 이 값 이상인 항목은 `Unreviewed` 상태의 잠재적 일치 항목이 됩니다."
                  },
                  "include_adverse_media": {
                    "type": "boolean",
                    "default": false,
                    "description": "부정적 보도에 대한 뉴스 미디어도 검색합니다. 결과를 수집하는 동안 대기 시간이 최대 약 30초 추가되므로, 60초 이상의 클라이언트 타임아웃을 사용하십시오."
                  },
                  "include_ongoing_monitoring": {
                    "type": "boolean",
                    "default": false,
                    "description": "이 프로필을 계속 재스크리닝하고 webhook을 통해 변경 사항을 푸시합니다. `save_api_request=true`가 필요합니다(그렇지 않으면 `400`)."
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "스크리닝을 세션으로 유지합니다(콘솔 표시, 결정 endpoint, webhook, 적발 검토). 상태를 저장하지 않는 무상태 검사의 경우 `false`로 설정합니다."
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "스크리닝 대상 사용자에 대한 귀하의 식별자입니다. 세션에 저장되며 그대로 다시 반환됩니다."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "요청과 함께 저장되고 그대로 반환되는 자유 형식 JSON입니다."
                  },
                  "sandbox_scenario": {
                    "type": "string",
                    "description": "샌드박스 전용 시나리오 슬러그입니다. API 키가 샌드박스 모드 애플리케이션에 속한 경우에만 허용되며, 프로덕션 환경 애플리케이션에서는 거부됩니다. 독립형 스크리닝에는 설정할 세션이 없으므로 슬러그가 스크리닝 요청 자체에 포함됩니다: `decline_aml_hit`는 프로덕션 형태의 일치 항목 하나를 반환하고 스크리닝을 `Declined`로 처리하며, `review_aml_possible_match`는 `In Review`로 처리하고, AML 결과를 설정하지 않는 시나리오는 스크리닝을 문제없는 상태로 둡니다. 시나리오 카탈로그는 GET /v1/sandbox/scenarios/ 또는 [Sandbox & Test Data](/ko/integration/sandbox-testing)에서 확인하십시오.",
                    "example": "decline_aml_hit"
                  }
                }
              },
              "example": {
                "full_name": "Antonio Ejemplo Modelo",
                "entity_type": "person",
                "date_of_birth": "1972-02-29",
                "nationality": "ES",
                "include_adverse_media": false,
                "vendor_data": "user-1234"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/aml/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -H 'Idempotency-Key: aml-user-1234-2026-08-20' \\\n  -d '{\n    \"full_name\": \"Antonio Ejemplo Modelo\",\n    \"entity_type\": \"person\",\n    \"date_of_birth\": \"1972-02-29\",\n    \"nationality\": \"ES\",\n    \"include_adverse_media\": false,\n    \"vendor_data\": \"user-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.aml.screen(\n    full_name=\"Antonio Ejemplo Modelo\",\n    entity_type=\"person\",\n    date_of_birth=\"1972-02-29\",\n    nationality=\"ES\",\n    include_adverse_media=False,\n    vendor_data=\"user-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.aml.screen({\n  full_name: \"Antonio Ejemplo Modelo\",\n  entity_type: \"person\",\n  date_of_birth: \"1972-02-29\",\n  nationality: \"ES\",\n  include_adverse_media: false,\n  vendor_data: \"user-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.AML.Screen(ctx, didit.AMLScreenParams{\n\tFullName:            \"Antonio Ejemplo Modelo\",\n\tEntityType:          didit.Some(didit.AMLScreenParamsEntityType(\"person\")),\n\tDateOfBirth:         didit.String(\"1972-02-29\"),\n\tNationality:         didit.String(\"ES\"),\n\tIncludeAdverseMedia: didit.Bool(false),\n\tVendorData:          didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport me.didit.Didit;\nimport me.didit.types.AmlScreenParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.aml().screen(AmlScreenParams.builder()\n        .fullName(\"Antonio Ejemplo Modelo\")\n        .entityType(AmlScreenParams.EntityType.of(\"person\"))\n        .dateOfBirth(LocalDate.parse(\"1972-02-29\"))\n        .nationality(\"ES\")\n        .includeAdverseMedia(false)\n        .vendorData(\"user-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->aml->screen([\n    'full_name' => 'Antonio Ejemplo Modelo',\n    'entity_type' => 'person',\n    'date_of_birth' => '1972-02-29',\n    'nationality' => 'ES',\n    'include_adverse_media' => false,\n    'vendor_data' => 'user-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.aml.screen(\n  full_name: \"Antonio Ejemplo Modelo\",\n  entity_type: \"person\",\n  date_of_birth: \"1972-02-29\",\n  nationality: \"ES\",\n  include_adverse_media: false,\n  vendor_data: \"user-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Aml.ScreenAsync(new AmlScreenParams\n{\n    FullName = \"Antonio Ejemplo Modelo\",\n    EntityType = new AmlScreenParamsEntityType(\"person\"),\n    DateOfBirth = \"1972-02-29\",\n    Nationality = \"ES\",\n    IncludeAdverseMedia = false,\n    VendorData = \"user-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "스크리닝이 완료되었습니다. `aml.status`는 설정한 임계값을 반영하며, 내부 포함 기준선 이상의 모든 적중 항목은 신원 `match_score`, 엔티티 `risk_score`, 일치 세부 정보를 설명하는 `score_breakdown`과 함께 `aml.hits`에 나열됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "`save_api_request=true`일 때 유지된 세션 ID(`GET /v3/session/{sessionId}/decision/`와 함께 사용 가능), 그렇지 않으면 임시 상관관계 UUID입니다."
                    },
                    "aml": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "In Review",
                            "Declined"
                          ],
                          "description": "`score` > `aml_score_review_threshold`인 경우 `Declined`, `score` > `aml_score_approve_threshold`인 경우 `In Review`, 그 외의 경우(사용 가능한 점수가 없는 경우 포함) `Approved`."
                        },
                        "total_hits": {
                          "type": "integer",
                          "description": "`hits`의 항목 수입니다."
                        },
                        "entity_type": {
                          "type": "string",
                          "enum": [
                            "person",
                            "company"
                          ],
                          "description": "스크리닝된 엔터티 유형의 에코 값입니다."
                        },
                        "hits": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "description": "스크리닝 일치 항목 1건입니다. `match_score`(0–100)는 신원 신뢰도를 측정합니다. `aml_match_score_threshold` 미만의 일치 항목은 `review_status: \"False Positive\"` 태그가 지정되어 위험 평가에서 제외되며, 임계값 이상의 일치 항목은 `\"Unreviewed\"` 잠재적 일치 항목이 됩니다. `risk_score`(0–100)는 일치된 엔터티의 위험도를 측정하며 최상위 `aml.score`를 결정합니다.",
                            "properties": {
                              "id": {
                                "type": "string",
                                "nullable": true,
                                "description": "해당 적발 항목에 대한 Didit의 고유 식별자: `hit_` 뒤에 24자리의 16진수 문자가 붙습니다. 대상을 다시 스크리닝할 때 동일하게 일치된 엔터티는 동일한 `id`를 유지합니다. AML 적발 항목 검토 endpoint에 `hit_id`로 전달합니다."
                              },
                              "url": {
                                "type": "string",
                                "nullable": true,
                                "description": "일치하는 엔티티의 출처 URL(제공되는 경우)입니다."
                              },
                              "match": {
                                "type": "boolean",
                                "nullable": true,
                                "description": "레거시 정확 일치 플래그입니다. `match_score` + `review_status`를 권장합니다."
                              },
                              "score": {
                                "type": "number",
                                "nullable": true,
                                "description": "[지원 중단됨] 0–1 범위의 가중 일치 점수입니다. 대신 `match_score`를 사용하세요."
                              },
                              "match_score": {
                                "type": "number",
                                "nullable": true,
                                "description": "신원 신뢰도(0~100)입니다. `aml_match_score_threshold`와 비교하여 오탐과 일치 가능성을 구분합니다."
                              },
                              "risk_score": {
                                "type": "number",
                                "nullable": true,
                                "description": "엔티티 위험 점수(0–100). 오탐이 아닌 적중 건 중 가장 높은 `risk_score`가 최상위 `aml.score`가 됩니다."
                              },
                              "target": {
                                "type": "boolean",
                                "nullable": true
                              },
                              "caption": {
                                "type": "string",
                                "nullable": true,
                                "description": "일치된 엔터티의 표시 이름입니다."
                              },
                              "datasets": {
                                "type": "array",
                                "nullable": true,
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "PEP",
                                    "PEP Level 1",
                                    "PEP Level 2",
                                    "PEP Level 3",
                                    "PEP Level 4",
                                    "Sanctions",
                                    "Adverse Media",
                                    "Warnings and Regulatory Enforcement",
                                    "Fitness and Probity",
                                    "SIP",
                                    "SIE",
                                    "Insolvency",
                                    "Other Lists"
                                  ]
                                },
                                "description": "해당 주체가 등재된 위험 범주: `PEP`(해당 등급 포함, `PEP Level 1`~`PEP Level 4`), `Sanctions`, `Adverse Media`, `Warnings and Regulatory Enforcement`, `Fitness and Probity`, `SIP`, `SIE` 또는 `Insolvency`. 주체의 출처에 이러한 범주가 전혀 명시되지 않은 경우 `Other Lists`로 표시됩니다."
                              },
                              "features": {
                                "type": "object",
                                "nullable": true
                              },
                              "properties": {
                                "type": "object",
                                "nullable": true,
                                "description": "엔티티 프로필: `name`, `alias`, `notes`, `gender`, `birthDate`, `birthPlace`, `nationality`, `position` 및 기타 전기 정보 배열(각각 nullable)."
                              },
                              "rca_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "일치 결과가 RCA인 경우 엔티티가 매칭된 관련 밀접 관계자의 이름입니다."
                              },
                              "pep_matches": {
                                "type": "array",
                                "description": "이 일치 항목을 뒷받침하는 정치적 주요 인물(PEP) 목록 항목입니다.",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "list_name": {
                                      "type": "string"
                                    },
                                    "publisher": {
                                      "type": "string"
                                    },
                                    "source_url": {
                                      "type": "string"
                                    },
                                    "description": {
                                      "type": "string"
                                    },
                                    "matched_name": {
                                      "type": "string"
                                    },
                                    "pep_position": {
                                      "type": "string"
                                    },
                                    "date_of_birth": {
                                      "type": "string"
                                    },
                                    "place_of_birth": {
                                      "type": "string"
                                    },
                                    "aliases": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "education": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "other_sources": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              },
                              "sanction_matches": {
                                "type": "array",
                                "items": {
                                  "type": "object"
                                },
                                "description": "이 일치 항목을 뒷받침하는 제재 목록 항목입니다(`pep_matches`와 동일한 근거 목록 형식에 제재 관련 필드가 추가됨)."
                              },
                              "warning_matches": {
                                "type": "array",
                                "items": {
                                  "type": "object"
                                },
                                "description": "이 적중 결과를 뒷받침하는 경고/감시 목록 항목입니다."
                              },
                              "adverse_media_matches": {
                                "type": "array",
                                "description": "부정적 언론 보도 기사입니다. `include_adverse_media=true`인 경우에만 채워집니다.",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "headline": {
                                      "type": "string"
                                    },
                                    "summary": {
                                      "type": "string"
                                    },
                                    "sentiment": {
                                      "type": "string"
                                    },
                                    "sentiment_score": {
                                      "type": "number"
                                    },
                                    "source_url": {
                                      "type": "string"
                                    },
                                    "thumbnail": {
                                      "type": "string",
                                      "nullable": true
                                    },
                                    "country": {
                                      "type": "string",
                                      "nullable": true
                                    },
                                    "author_name": {
                                      "type": "string",
                                      "nullable": true
                                    },
                                    "publication_date": {
                                      "type": "string",
                                      "nullable": true
                                    },
                                    "adverse_keywords": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "other_sources": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              },
                              "adverse_media_details": {
                                "type": "object",
                                "nullable": true,
                                "description": "엔터티에 대해 집계된 부정적 언론 보도 감성 분석입니다(`sentiment`, `sentiment_score`, `adverse_keywords` 빈도 맵). `include_adverse_media=true`인 경우에만 채워집니다."
                              },
                              "first_seen": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true,
                                "description": "엔터티가 데이터 세트에 처음 등장한 시점입니다."
                              },
                              "last_seen": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true,
                                "description": "해당 엔티티가 포함된 가장 최근의 데이터셋 새로고침."
                              },
                              "linked_entities": {
                                "type": "array",
                                "description": "일치하는 엔터티의 알려진 관계(가족, 관계자, 회사)입니다.",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "name": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "relation": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "status": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "details": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "active": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              },
                              "risk_view": {
                                "type": "object",
                                "nullable": true,
                                "description": "차원별 위험 세부 내역(`crimes`, `countries`, `categories`, `custom_list`)이며, 각각 `score`, `weightage`, `risk_level` 및 `risk_scores` 맵을 포함합니다."
                              },
                              "additional_information": {
                                "type": "object",
                                "nullable": true,
                                "description": "엔터티에 플래그가 지정된 이유를 설명하는 `flag_summary` 배열 등과 같은 자유 형식의 추가 컨텍스트입니다."
                              },
                              "review_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "False Positive",
                                  "Unreviewed",
                                  "Confirmed Match",
                                  "Inconclusive"
                                ],
                                "description": "`False Positive` — `match_score`가 `aml_match_score_threshold` 미만이며 위험 평가에서 제외됨. `Unreviewed` — 검토 대기 중인 가능한 일치 항목. `Confirmed Match` / `Inconclusive` — 저장된 세션에 대해 검토자가 (Business Console을 통해) 수동으로 설정함. 해당 검토 기능은 본 사양의 일부가 아닙니다."
                              },
                              "score_breakdown": {
                                "type": "object",
                                "nullable": true,
                                "description": "`match_score`가 계산된 방식입니다. 성명, 생년월일, 국가는 각각 `<component>_score` × `<component>_weight_normalized` 점수를 반영합니다. 스크리닝 데이터에서 구성 요소가 누락된 경우 가중치가 다시 정규화됩니다. 문서 번호는 가중치가 부여되지 않으며 일종의 '골든 키' 역할을 합니다. `MATCH`는 점수를 100으로 덮어쓰고, `NEUTRAL`은 변경하지 않고 유지하며, `HARD_MISMATCH`는 페널티를 적용합니다.",
                                "properties": {
                                  "name_score": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "원시 성명 유사도(0–100)입니다."
                                  },
                                  "name_weight": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "설정된 이름 가중치(`aml_name_weight`)입니다."
                                  },
                                  "name_weight_normalized": {
                                    "type": "number",
                                    "nullable": true,
                                    "description": "재정규화 후의 이름 가중치(0–100)."
                                  },
                                  "name_contribution": {
                                    "type": "number",
                                    "nullable": true,
                                    "description": "`total_score`에 기여한 이름 점수입니다."
                                  },
                                  "dob_score": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "가중치 대비 백분율로 환산된 생년월일 점수(-100~100)."
                                  },
                                  "dob_weight": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "설정된 생년월일 가중치(`aml_dob_weight`)입니다."
                                  },
                                  "dob_weight_normalized": {
                                    "type": "number",
                                    "nullable": true,
                                    "description": "재정규화 후 생년월일 가중치(0~100)."
                                  },
                                  "dob_contribution": {
                                    "type": "number",
                                    "nullable": true,
                                    "description": "`total_score`에 기여한 생년월일 점수입니다."
                                  },
                                  "country_score": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "가중치 대비 백분율로 표시된 국가 점수(−100~100)."
                                  },
                                  "country_weight": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "설정된 국가 가중치(`aml_country_weight`)입니다."
                                  },
                                  "country_weight_normalized": {
                                    "type": "number",
                                    "nullable": true,
                                    "description": "재정규화 후 국가 가중치(0~100)."
                                  },
                                  "country_contribution": {
                                    "type": "number",
                                    "nullable": true,
                                    "description": "`total_score`에 기여한 국가 점수입니다."
                                  },
                                  "document_number_match_type": {
                                    "type": "string",
                                    "nullable": true,
                                    "enum": [
                                      "MATCH",
                                      "NEUTRAL",
                                      "HARD_MISMATCH"
                                    ],
                                    "description": "문서 번호 비교를 위한 골든 키 결과입니다."
                                  },
                                  "document_number_effect": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "문서 번호 영향에 대한 사람이 읽기 쉬운 설명입니다."
                                  },
                                  "total_score": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "최종 가중 일치 점수(0–100) — `match_score`를 반영합니다."
                                  }
                                }
                              }
                            }
                          }
                        },
                        "score": {
                          "type": "number",
                          "nullable": true,
                          "description": "전체 AML 위험 점수(0–100): 오탐이 아닌 일치 항목 중 가장 높은 `risk_score`입니다. 두 임계값을 통해 `status`를 결정합니다."
                        },
                        "screened_data": {
                          "type": "object",
                          "description": "스크리닝된 대상의 에코 값: `full_name`, `date_of_birth`, `nationality`, `document_number`(없는 필드는 `null`).",
                          "properties": {
                            "full_name": {
                              "type": "string"
                            },
                            "date_of_birth": {
                              "type": "string",
                              "nullable": true
                            },
                            "nationality": {
                              "type": "string",
                              "nullable": true
                            },
                            "document_number": {
                              "type": "string",
                              "nullable": true
                            }
                          }
                        },
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "feature": {
                                "type": "string",
                                "description": "경고를 발생시킨 기능입니다."
                              },
                              "risk": {
                                "type": "string",
                                "description": "기계 판독 가능한 위험 식별자입니다."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "description": "가능한 경우 제공되는 경고의 추가 컨텍스트입니다."
                              },
                              "log_type": {
                                "type": "string",
                                "description": "`warning`, `information` 또는 `error` — 위험이 결과에 미친 영향입니다."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "사람이 읽을 수 있는 한 줄 요약입니다."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "사람이 읽을 수 있는 전체 설명입니다."
                              }
                            }
                          },
                          "description": "`score`가 0이 아니고 `aml_score_approve_threshold` 이상일 때마다 `POSSIBLE_MATCH_FOUND` 경고가 포함됩니다(점수가 정확히 0이면 경고가 발생하지 않음). 그렇지 않으면 비어 있습니다."
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "전송한 `vendor_data`의 에코 값입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "description": "전송한 `metadata`의 에코 값입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "No hits (Approved)": {
                    "summary": "이상 없는 스크리닝 — 일치 항목 0건",
                    "value": {
                      "request_id": "d27c5509-7a66-45a9-b05e-d69d9f4c336a",
                      "aml": {
                        "status": "Approved",
                        "total_hits": 0,
                        "entity_type": "person",
                        "hits": [],
                        "score": 0,
                        "screened_data": {
                          "full_name": "Maximilian Mustermann-Doe",
                          "date_of_birth": "1992-03-14",
                          "nationality": "DE",
                          "document_number": null
                        },
                        "warnings": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": {
                        "internal_ref": "abc-123"
                      },
                      "created_at": "2026-06-11T10:21:07.013938+00:00"
                    }
                  },
                  "PEP hit (Approved — risk below approve threshold)": {
                    "summary": "정치적 주요 인물(PEP) 일치 가능성 1건입니다. 위험 점수 73점은 기본 승인 임계값인 80점 미만으로 유지됩니다.",
                    "value": {
                      "request_id": "0b7e7a3e-65a1-4f3d-9c7a-1de2f9a40111",
                      "aml": {
                        "status": "Approved",
                        "total_hits": 1,
                        "entity_type": "person",
                        "hits": [
                          {
                            "id": "hit_7c1e9a40b2d35f86e0a4c912",
                            "url": "https://news.example.org/articles/sample",
                            "match": false,
                            "score": 0.93,
                            "match_score": 93.0,
                            "risk_score": 73.0,
                            "target": null,
                            "caption": "Antonio Ejemplo Modelo",
                            "datasets": [
                              "PEP Level 1",
                              "PEP"
                            ],
                            "features": null,
                            "rca_name": "",
                            "first_seen": "2026-01-07T00:00:00",
                            "last_seen": "2026-01-07T00:00:00",
                            "review_status": "Unreviewed",
                            "properties": {
                              "name": [
                                "Antonio Ejemplo Modelo",
                                "Antonio Ejemplo"
                              ],
                              "alias": [
                                "Antonio Ejemplo Modelo",
                                "Ejemplo Modelo, Pedro"
                              ],
                              "notes": [
                                "Prime Minister of Spain"
                              ],
                              "gender": [
                                "male"
                              ],
                              "birthDate": [
                                "1972-02-29"
                              ],
                              "birthPlace": [
                                "Madrid, Spain"
                              ],
                              "nationality": null,
                              "position": null
                            },
                            "risk_view": {
                              "crimes": {
                                "score": 0.0,
                                "weightage": 20,
                                "risk_level": "Low",
                                "risk_scores": {}
                              },
                              "countries": {
                                "score": 9.64,
                                "weightage": 30,
                                "risk_level": "Low",
                                "risk_scores": {
                                  "Spain": 25.71
                                }
                              },
                              "categories": {
                                "score": 62.5,
                                "weightage": 50,
                                "risk_level": "High",
                                "risk_scores": {
                                  "PEP": 100.0,
                                  "PEP Level 1": 100.0
                                }
                              },
                              "custom_list": {}
                            },
                            "score_breakdown": {
                              "name_score": 89,
                              "name_weight": 60,
                              "name_weight_normalized": 60.0,
                              "name_contribution": 53.4,
                              "dob_score": 100,
                              "dob_weight": 25,
                              "dob_weight_normalized": 25.0,
                              "dob_contribution": 25.0,
                              "country_score": 100,
                              "country_weight": 15,
                              "country_weight_normalized": 15.0,
                              "country_contribution": 15.0,
                              "document_number_match_type": "NEUTRAL",
                              "document_number_effect": "No document number provided for screening",
                              "total_score": 93
                            },
                            "pep_matches": [
                              {
                                "aliases": [],
                                "education": [],
                                "list_name": "Presidency of the Government of Spain",
                                "publisher": "Presidency of the Government of Spain",
                                "source_url": "https://news.example.org/articles/sample",
                                "description": "The Presidency of the Government is the central institutional body in Spain that supports the Prime Minister and coordinates the general action of the central government.",
                                "matched_name": "Antonio Ejemplo Modelo",
                                "pep_position": "",
                                "date_of_birth": "1972-02-29",
                                "other_sources": [],
                                "place_of_birth": "Madrid, Spain"
                              }
                            ],
                            "sanction_matches": [],
                            "warning_matches": [],
                            "adverse_media_matches": [],
                            "adverse_media_details": null,
                            "linked_entities": [
                              {
                                "name": [
                                  "Maria Begona Gomez Fernandez"
                                ],
                                "active": [],
                                "status": [],
                                "details": [],
                                "relation": [
                                  "spouse"
                                ]
                              }
                            ],
                            "additional_information": {
                              "flag_summary": [
                                "Antonio Ejemplo Modelo has been flagged as a Level 1 Politically Exposed Person (PEP) from Spain, serving as the President of the Government of Spain."
                              ]
                            }
                          }
                        ],
                        "score": 73.0,
                        "screened_data": {
                          "full_name": "Pedro Sanchez Perez-Castejon",
                          "date_of_birth": "1972-02-29",
                          "nationality": "ES",
                          "document_number": null
                        },
                        "warnings": []
                      },
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-06-11T10:23:44.812000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 필드 수준 문제는 DRF의 표준 엔벨로프(문제가 있는 필드당 하나의 메시지 배열)를 반환하고, 필드 간 규칙(가중치 합계, 임계값 순서, 저장 없는 모니터링)은 `{\"error\": [...]}`를 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing full_name": {
                    "summary": "`full_name`만 필수 필드임",
                    "value": {
                      "full_name": [
                        "This field is required."
                      ]
                    }
                  },
                  "Short full_name": {
                    "summary": "`full_name`은 2자 이상이어야 함",
                    "value": {
                      "full_name": [
                        "Ensure this field has at least 2 characters."
                      ]
                    }
                  },
                  "Invalid nationality": {
                    "summary": "`nationality`는 ISO 3166-1 alpha-2 형식이어야 합니다.",
                    "value": {
                      "nationality": [
                        "Invalid ISO 3166-1 alpha-2 country code."
                      ]
                    }
                  },
                  "Weights do not sum to 100": {
                    "summary": "`aml_name_weight` + `aml_dob_weight` + `aml_country_weight` ≠ 100",
                    "value": {
                      "error": [
                        "AML weights must sum to 100. Current sum: 90 (name: 50, dob: 25, country: 15)"
                      ]
                    }
                  },
                  "Thresholds out of order": {
                    "summary": "검토 임계값을 초과하는 승인 임계값",
                    "value": {
                      "error": [
                        "Approve threshold (90.0) cannot be greater than review threshold (80.0)"
                      ]
                    }
                  },
                  "Monitoring without saving": {
                    "summary": "`save_api_request=false` 상태에서 `include_ongoing_monitoring=true`를 설정했습니다.",
                    "value": {
                      "error": [
                        "Ongoing monitoring can only be enabled when the API request is saved."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었거나 호출한 조직의 잔액이 호출 비용을 충당할 수 없을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 키가 누락된 경우 `{\"detail\": ...}`과 함께 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 크레딧이 부족한 경우 어떠한 스크리닝이나 제공업체 호출도 진행되기 전에 `{\"error\": ...}`과 함께 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 호출 비용을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/face-search/": {
      "post": {
        "summary": "얼굴 검색",
        "description": "얼굴 이미지를 애플리케이션의 얼굴 검색 색인(인증 세션에서 등록된 얼굴, 저장된 독립 실행형 API 호출, 직접 업로드한 사용자 프로필 얼굴, 차단/허용 목록)과 1:N으로 검색하여 유사도 순으로 정렬된 일치 항목과 차단 목록 및 중복 경고를 반환받습니다.\n\n**작동 방식.** `user_image`에서 감지된 가장 큰 얼굴이 임베딩되어 애플리케이션 범위 내의 색인과 대조 검색됩니다. 유사도 하한선 이상의 **일치 항목이 최대 5개**까지 `matches`로 반환되며, 각 항목에는 `similarity_percentage`, 원래 세션(`session_id`, `session_number`, `status`, `vendor_data`), 해당 세션의 문서 인증 중 추출된 `user_details`, `is_blocklisted` / `is_allowlisted` 플래그, `source` 구분값(`session`, `imported` 또는 `list_entry`)이 포함됩니다.\n\n- `search_type=most_similar`(기본값)는 등록된 모든 얼굴을 유사도 순으로 정렬합니다. 중복 제거 및 사기 조직 조사에 사용하세요.\n- `search_type=blocklisted_or_approved`는 후보를 차단 목록에 등록된 얼굴, 허용 목록에 등록된 얼굴, 승인된 세션의 얼굴, 가져온 사용자 프로필 얼굴로 제한하고 차단 목록 항목을 먼저 정렬합니다. 주요 목적이 차단 목록 스크리닝일 때 사용하세요.\n\n`status`는 `FACE_IN_BLOCKLIST` 또는 `POSSIBLE_FACE_IN_BLOCKLIST` 경고가 발생할 때만 `Declined`가 됩니다. `DUPLICATED_FACE` / `POSSIBLE_DUPLICATED_FACE`(`information`) 및 `MULTIPLE_FACES_DETECTED`(`warning`)는 절대 거부되지 않습니다. 수동 라이브니스와 달리 이 endpoint는 동일한 `vendor_data`를 가진 이전 세션을 일치 항목에서 제외하지 **않습니다**. 수동 라이브니스 분석도 내부적으로 실행되어 영구 저장된 세션과 함께 저장되지만, 해당 결과는 이 응답에 포함되지 않습니다.\n\n**결제.** 각 `200` 응답은 얼굴 검색 API 크레딧 1개를 소모합니다(요금제 크레딧 또는 충전 잔액에서 차감). 잔액이 부족하면 이미지 처리가 시작되기 전에 `403`을 반환합니다.\n\n**세션 영구 저장 및 얼굴 등록(`save_api_request`, 기본값 `true`).** `true`인 경우 호출은 API 유형 세션(Business Console, 반환된 `request_id`를 통한 `GET /v3/session/{sessionId}/decision/`, `status.updated` webhook)으로 영구 저장되며 검색된 얼굴은 얼굴 검색 색인에 등록됩니다. 얼굴 검색 호출로 등록된 얼굴은 향후 얼굴 검색 결과에서 제외되므로 반복된 검색이 서로 일치하지 않습니다. `false`인 경우 호출은 1회성입니다. 아무것도 저장되지 않고, 얼굴이 등록되지 않으며, `match_image_url` 값은 다운로드 가능한 URL이 아닌 내부 저장소 경로가 됩니다.\n\n**샌드박스.** 샌드박스 API 키는 모든 처리 및 결제를 건너뜁니다. 요청 검증 후(형식이 잘못된 입력은 여전히 `400` 반환) endpoint는 정적 `Approved` 모의 payload를 반환하며, 세션이 영구 저장되지 않고 크레딧도 소모되지 않습니다.\n\n**인증.** 애플리케이션의 API 키를 `x-api-key` 헤더에 담아 전송하세요. 자격 증명이 없거나 유효하지 않으면 `403`(`{\"detail\": \"You do not have permission to perform this action.\"}`)을 반환합니다. 이 API는 `401`을 절대 반환하지 않습니다.\n\n**속도 제한.** 모든 POST/PATCH/DELETE endpoint에서 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다. 이를 초과하면 `429`를 반환합니다.",
        "operationId": "post_v3face-search",
        "x-didit-sdk": {
          "resource": "face_search",
          "method": "search",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "user_image"
                ],
                "properties": {
                  "user_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "검색할 정면 얼굴 이미지입니다. 허용되는 확장자: `tiff`, `jpg`, `jpeg`, `png`, `webp`. 최대 업로드 크기: **5 MB**(더 큰 파일은 `400` 오류로 거부됨). 이미지는 처리 전에 자동으로 ~0.5 MB로 압축되므로 매우 높은 해상도라고 해서 정확도가 향상되지는 않습니다. 이미지에는 감지 가능한 얼굴이 하나 이상 포함되어야 하며, 그렇지 않으면 endpoint에서 `400`을 반환합니다. 여러 얼굴이 있는 경우 가장 큰 얼굴이 검색되며 `MULTIPLE_FACES_DETECTED` 경고가 추가됩니다."
                  },
                  "search_type": {
                    "type": "string",
                    "default": "most_similar",
                    "enum": [
                      "most_similar",
                      "blocklisted_or_approved"
                    ],
                    "description": "검색 정책. `most_similar`(기본값)는 애플리케이션에 등록된 모든 얼굴의 유사도 순위를 매깁니다. `blocklisted_or_approved`는 차단 목록에 등록된 얼굴, 허용 목록에 등록된 얼굴, 승인된 세션의 얼굴, 가져온 사용자 프로필 얼굴로 후보를 제한하며, 차단 목록 항목이 먼저 정렬됩니다.",
                    "example": "most_similar"
                  },
                  "rotate_image": {
                    "type": "boolean",
                    "default": false,
                    "description": "`true`인 경우 서비스가 입력을 90도씩 회전해 보고 최적의 얼굴 감지 결과를 제공하는 방향을 사용합니다. EXIF 방향 정보가 누락되었을 때 유용합니다. 지연 시간이 증가합니다.",
                    "example": false
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "`true`(기본값)인 경우 호출을 API 유형의 세션으로 저장하고, `status.updated` webhook을 발행하며, `match_image_url` 값을 사전 서명하고, 검색된 얼굴을 얼굴 검색 인덱스에 등록합니다(얼굴 검색 등록 건은 향후 검색 대상에서 제외됨). `false`인 경우 검색은 단발성으로 처리되어 세션이 저장되지 않고 얼굴도 등록되지 않습니다.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "저장된 세션에 저장되고 다시 반환되는 선택적 불투명 식별자(사용자 ID, 이메일, UUID 등)입니다. 검색 결과에서 동일 사용자의 얼굴을 제외하지는 않습니다.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "세션과 함께 저장되고(`save_api_request=true`인 경우) 그대로 반환되는 선택적 JSON 객체입니다. multipart 요청에서는 JSON 인코딩된 문자열 필드로 전송하십시오. 객체로 파싱됩니다.",
                    "example": {
                      "flow": "dedup_check"
                    }
                  }
                }
              },
              "example": {
                "user_image": "(binary JPEG/PNG selfie)",
                "search_type": "most_similar",
                "rotate_image": false,
                "save_api_request": true,
                "vendor_data": "user-123",
                "metadata": {
                  "flow": "dedup_check"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "얼굴 검색이 완료되었습니다. `face_search.matches`는 유사도 순으로 정렬된 유사한 얼굴을 최대 5개까지 포함합니다. 빈 배열은 등록된 얼굴 중 유사도 하한을 초과한 얼굴이 없음을 의미합니다. `status`는 차단 목록에 일치하는 경우에만 `Declined`입니다. 중복 일치만으로는 `Approved`를 반환하므로 `status`뿐만 아니라 `matches` 및 `warnings`를 확인하십시오. `save_api_request=true`인 경우, `request_id`는 저장된 세션 ID입니다. 각 일치 항목에는 `source`(`session`, `imported`, `list_entry` 또는 `retained_template`), `vendor_user_id`, `biometric_template_id`가 포함됩니다. `retained_template` 일치는 소스 세션이 삭제된 후 보관된 이미지가 없는 생체 인식 템플릿에서 비롯되며, 이 일치 항목의 세션 필드, `match_image_url`, `user_details`는 `null`입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Blocklist hit (Declined)": {
                    "summary": "얼굴이 차단 목록에 등록된 얼굴과 일치합니다",
                    "value": {
                      "request_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
                      "face_search": {
                        "status": "Declined",
                        "total_matches": 1,
                        "matches": [
                          {
                            "session_id": "882c42d5-8a4d-4d20-8080-a22f57822c86",
                            "session_number": 323442,
                            "similarity_percentage": 99.99,
                            "source": "session",
                            "vendor_data": "user-1",
                            "verification_date": "2025-01-01T00:00:00Z",
                            "user_details": {
                              "full_name": "Jane Marie Doe",
                              "document_type": "ID",
                              "document_number": "X1234567"
                            },
                            "match_image_url": "https://<media-host>/face/3f6a1c2e/reference.jpg",
                            "status": "Approved",
                            "is_blocklisted": true,
                            "is_allowlisted": false,
                            "api_service": null,
                            "vendor_user_id": "2f7c1a9e-8b4d-4c6a-9e1f-3d5b7a9c1e2f",
                            "biometric_template_id": null
                          }
                        ],
                        "user_image": {
                          "entities": [
                            {
                              "bbox": [
                                40,
                                40,
                                120,
                                120
                              ],
                              "confidence": 0.732973
                            }
                          ],
                          "best_angle": 0
                        },
                        "warnings": [
                          {
                            "risk": "FACE_IN_BLOCKLIST",
                            "feature": "LIVENESS",
                            "additional_data": {
                              "blocklisted_session_id": "882c42d5-8a4d-4d20-8080-a22f57822c86",
                              "blocklisted_session_number": 323442,
                              "api_service": null
                            },
                            "log_type": "error",
                            "short_description": "Face in blocklist",
                            "long_description": "The system identified a face in the blocklist, which means the face is not allowed to be verified."
                          }
                        ]
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T01:04:42.763237+00:00"
                    }
                  },
                  "Duplicate found (Approved)": {
                    "summary": "얼굴이 이미 다른 승인된 세션에 나타났습니다 — 정보 제공용이며, 거부되지 않습니다",
                    "value": {
                      "request_id": "5e0c3a1f-7b2d-4c8e-9f10-2a3b4c5d6e7f",
                      "face_search": {
                        "status": "Approved",
                        "total_matches": 1,
                        "matches": [
                          {
                            "session_id": "1f2e3d4c-5b6a-7980-1122-334455667788",
                            "session_number": 1024,
                            "similarity_percentage": 87.42,
                            "source": "session",
                            "vendor_data": "user-9",
                            "verification_date": "2025-11-20T09:15:00Z",
                            "user_details": null,
                            "match_image_url": "https://<media-host>/face/9c8b7a6d/reference.jpg",
                            "status": "Approved",
                            "is_blocklisted": false,
                            "is_allowlisted": false,
                            "api_service": "PASSIVE_LIVENESS",
                            "vendor_user_id": "2f7c1a9e-8b4d-4c6a-9e1f-3d5b7a9c1e2f",
                            "biometric_template_id": null
                          }
                        ],
                        "user_image": {
                          "entities": [
                            {
                              "bbox": [
                                40,
                                40,
                                120,
                                120
                              ],
                              "confidence": 0.732973
                            }
                          ],
                          "best_angle": 0
                        },
                        "warnings": [
                          {
                            "risk": "DUPLICATED_FACE",
                            "feature": "LIVENESS",
                            "additional_data": {
                              "duplicated_session_id": "1f2e3d4c-5b6a-7980-1122-334455667788",
                              "duplicated_session_number": 1024,
                              "api_service": "PASSIVE_LIVENESS"
                            },
                            "log_type": "information",
                            "short_description": "Duplicated face from other approved session",
                            "long_description": "The system identified a duplicated face from another approved session, requiring further investigation."
                          }
                        ]
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T01:04:42.763237+00:00"
                    }
                  },
                  "No matches (Approved)": {
                    "summary": "등록된 얼굴 중 유사도 하한을 초과한 얼굴이 없습니다",
                    "value": {
                      "request_id": "9d8c7b6a-5f4e-3d2c-1b0a-998877665544",
                      "face_search": {
                        "status": "Approved",
                        "total_matches": 0,
                        "matches": [],
                        "user_image": {
                          "entities": [
                            {
                              "bbox": [
                                40,
                                40,
                                120,
                                120
                              ],
                              "confidence": 0.732973
                            }
                          ],
                          "best_angle": 0
                        },
                        "warnings": []
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T01:04:42.763237+00:00"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "`save_api_request=true`일 때 유지된 세션 ID(`GET /v3/session/{sessionId}/decision/`와 함께 사용 가능), 그렇지 않으면 임시 상관관계 UUID입니다."
                    },
                    "face_search": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined"
                          ],
                          "description": "`FACE_IN_BLOCKLIST` 또는 `POSSIBLE_FACE_IN_BLOCKLIST` 경고가 발생한 경우에만 `Declined`. 중복 일치 및 다중 얼굴 경고는 단독으로 거부되지 않습니다."
                        },
                        "total_matches": {
                          "type": "integer",
                          "description": "`matches`의 항목 수(0–5)입니다.",
                          "example": 1
                        },
                        "matches": {
                          "type": "array",
                          "maxItems": 5,
                          "description": "얼굴 검색 인덱스에서 유사도 최저 기준을 초과한 얼굴 목록으로 최대 5개까지 유사도순으로 정렬됩니다(`search_type=blocklisted_or_approved`인 경우 차단 목록 항목이 우선 순위로 정렬됨). 등록된 얼굴 중 충분히 유사한 얼굴이 없는 경우 비어 있습니다.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "session_id": {
                                "type": "string",
                                "format": "uuid",
                                "nullable": true,
                                "description": "일치하는 얼굴이 속한 인증 세션의 ID입니다. `source`가 `imported`, `list_entry` 또는 `retained_template`인 경우 `null`입니다.",
                                "example": "882c42d5-8a4d-4d20-8080-a22f57822c86"
                              },
                              "session_number": {
                                "type": "integer",
                                "nullable": true,
                                "description": "Business Console에 표시되는 사람이 읽기 쉬운 세션 번호입니다. 비세션 일치 항목의 경우 `null`입니다.",
                                "example": 323442
                              },
                              "similarity_percentage": {
                                "type": "number",
                                "format": "float",
                                "minimum": 0,
                                "maximum": 100,
                                "description": "제출된 얼굴과 일치한 얼굴 간의 유사도(0–100)입니다.",
                                "example": 99.99
                              },
                              "source": {
                                "type": "string",
                                "enum": [
                                  "session",
                                  "imported",
                                  "list_entry",
                                  "retained_template"
                                ],
                                "description": "일치하는 얼굴이 등록된 위치: `session` — 인증 세션 또는 저장된 독립형 API 호출, `imported` — 사용자 프로필에 직접 업로드된 얼굴, `list_entry` — 내 목록 중 하나에 첨부된 얼굴, `retained_template` — `/v3/biometric-templates/` 아래에 나열된 사용자에게 저장된 이미지가 없는 생체 인식 템플릿."
                              },
                              "vendor_data": {
                                "type": "string",
                                "nullable": true,
                                "description": "가져온 얼굴 및 보존된 템플릿 얼굴의 경우 일치하는 세션 또는 연결된 사용자의 `vendor_data`입니다.",
                                "example": "user-1"
                              },
                              "vendor_user_id": {
                                "type": "string",
                                "format": "uuid",
                                "nullable": true,
                                "description": "연결된 User id입니다. 목록 항목 및 사용자가 없는 세션 일치 항목의 경우 `null`입니다.",
                                "example": "2f7c1a9e-4b28-4a6d-97f1-83576f80e1b4"
                              },
                              "biometric_template_id": {
                                "type": "string",
                                "format": "uuid",
                                "nullable": true,
                                "description": "보존된 생체 인식 템플릿의 ID입니다. `source`가 `retained_template`일 때만 설정되며, 그 외의 경우 `null`입니다.",
                                "example": null
                              },
                              "verification_date": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true,
                                "description": "일치한 얼굴이 원래 캡처된 시점 또는 보존된 템플릿이 생성된 시점(`YYYY-MM-DDThh:mm:ssZ`)입니다. `list_entry` 일치의 경우 `null`입니다.",
                                "example": "2025-01-01T00:00:00Z"
                              },
                              "user_details": {
                                "type": "object",
                                "nullable": true,
                                "description": "일치하는 세션의 문서 검증 중 추출된 신원 데이터입니다. 일치하는 세션에 문서 데이터가 없는 경우(예: 라이브니스 전용 세션) `null`이며, `retained_template` 일치의 경우 항상 `null`입니다. `source: imported` 일치의 경우 사용자 프로필에서 채워집니다(`full_name` 설정됨, `document_type`/`document_number`는 null).",
                                "properties": {
                                  "full_name": {
                                    "type": "string",
                                    "nullable": true,
                                    "example": "Jane Marie Doe"
                                  },
                                  "document_type": {
                                    "type": "string",
                                    "nullable": true,
                                    "example": "ID"
                                  },
                                  "document_number": {
                                    "type": "string",
                                    "nullable": true,
                                    "example": "X1234567"
                                  }
                                }
                              },
                              "match_image_url": {
                                "type": "string",
                                "nullable": true,
                                "description": "`save_api_request=true`일 때 일치하는 얼굴의 참조 이미지에 대한 시간 제한 URL(`https://<media-host>/...`)입니다. `save_api_request=false`인 경우 직접 다운로드할 수 없는 내부 스토리지 경로입니다. 보존된 템플릿에는 이미지가 포함되어 있지 않으므로 `retained_template` 일치의 경우 항상 `null`입니다.",
                                "example": "https://<media-host>/face/3f6a1c2e/reference.jpg"
                              },
                              "status": {
                                "type": "string",
                                "nullable": true,
                                "description": "일치하는 세션의 상태(`Approved`, `Declined`, `In Review` 등)입니다. `imported`/`list_entry` 일치의 경우 `null`입니다.",
                                "example": "Approved"
                              },
                              "is_blocklisted": {
                                "type": "boolean",
                                "description": "일치하는 얼굴이 얼굴 차단 목록에 있을 때 `true`입니다. 충분히 유사한 차단 목록 일치 항목이 있으면 검색이 거절됩니다."
                              },
                              "is_allowlisted": {
                                "type": "boolean",
                                "description": "일치하는 얼굴이 허용 목록 중 하나에 있을 때 `true`입니다. 허용 목록에 등록된 일치 항목은 중복 경고를 억제합니다."
                              },
                              "api_service": {
                                "type": "string",
                                "nullable": true,
                                "description": "일치한 얼굴이 독립 실행형 API 호출(예: `PASSIVE_LIVENESS`)을 통해 등록된 경우 설정됩니다. 일반 인증 세션 및 가져온 얼굴의 경우 `null`입니다.",
                                "example": null
                              }
                            }
                          }
                        },
                        "user_image": {
                          "type": "object",
                          "description": "제출된 이미지에 대한 얼굴 감지 결과입니다. 여기의 항목에는 `bbox` 및 `confidence`만 포함됩니다.",
                          "properties": {
                            "entities": {
                              "type": "array",
                              "description": "감지된 얼굴당 항목 1개입니다. 가장 큰 얼굴이 검색 대상이 됩니다.",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "bbox": {
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    },
                                    "minItems": 4,
                                    "maxItems": 4,
                                    "description": "픽셀 단위의 경계 상자 `[x_min, y_min, x_max, y_max]`입니다.",
                                    "example": [
                                      40,
                                      40,
                                      120,
                                      120
                                    ]
                                  },
                                  "confidence": {
                                    "type": "number",
                                    "format": "float",
                                    "minimum": 0,
                                    "maximum": 1,
                                    "description": "얼굴 감지 신뢰도(0–1).",
                                    "example": 0.732973
                                  }
                                }
                              }
                            },
                            "best_angle": {
                              "type": "integer",
                              "description": "가장 우수한 얼굴 감지를 생성한 회전 각도(도). `rotate_image=true`로 방향을 수정한 경우에만 0이 아닙니다. 이 endpoint에서는 절대 null이 아닙니다(모델에서 생략된 경우 기본값은 0).",
                              "example": 0
                            }
                          }
                        },
                        "warnings": {
                          "type": "array",
                          "description": "위험 신호. `FACE_IN_BLOCKLIST` / `POSSIBLE_FACE_IN_BLOCKLIST`(`error`)는 검색을 거부합니다. `MULTIPLE_FACES_DETECTED`(`warning`) 및 `DUPLICATED_FACE` / `POSSIBLE_DUPLICATED_FACE`(`information`)는 참고용입니다.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "enum": [
                                  "MULTIPLE_FACES_DETECTED",
                                  "FACE_IN_BLOCKLIST",
                                  "POSSIBLE_FACE_IN_BLOCKLIST",
                                  "DUPLICATED_FACE",
                                  "POSSIBLE_DUPLICATED_FACE"
                                ],
                                "description": "기계 판독 가능한 위험 코드입니다."
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "LIVENESS"
                                ],
                                "description": "경고를 발생시킨 기능입니다. 이 endpoint에서는 항상 `LIVENESS`입니다."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "`MULTIPLE_FACES_DETECTED`의 경우 `null`입니다. 차단 목록 일치 항목에는 `{blocklisted_session_id, blocklisted_session_number, api_service}`가 포함되며, 중복 일치 항목에는 첫 번째 일치 세션을 가리키는 `{duplicated_session_id, duplicated_session_number, api_service}`가 포함됩니다."
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error",
                                  "warning",
                                  "information"
                                ],
                                "description": "심각도입니다. `error` 경고는 `status`를 `Declined`로 변경합니다. `warning` 및 `information` 항목은 참고용이며 단독으로 거부되지 않습니다."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "사람이 읽을 수 있는 한 줄의 위험 요약입니다."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "위험에 대한 사람이 읽기 쉬운 설명입니다."
                              }
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "전송한 `vendor_data`의 에코 값 또는 `null`입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "전송한 `metadata` 객체의 에코 값 또는 `null`입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "응답이 생성된 시점의 ISO 8601 타임스탬프(UTC)(예: `2026-06-12T01:04:42.763237+00:00`)입니다."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. `user_image`가 누락되었거나, 5 MB를 초과하거나, 지원되지 않는 확장자이거나, 제출된 이미지에서 **얼굴이 감지되지 않은** 경우 반환됩니다. 필드 오류는 DRF의 `{field: [messages]}` 봉투를 사용하며, 얼굴 감지 실패는 `{\"error\": ...}`를 사용합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "No face detected": {
                    "summary": "이미지는 정상적으로 디코딩되지만 감지 가능한 얼굴이 포함되어 있지 않습니다.",
                    "value": {
                      "error": "No face detected in the image"
                    }
                  },
                  "Missing image": {
                    "summary": "폼 데이터에 `user_image`가 포함되지 않음",
                    "value": {
                      "user_image": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Unsupported file extension": {
                    "summary": "tiff/jpg/jpeg/png/webp 이외의 파일 확장자",
                    "value": {
                      "user_image": [
                        "File extension “txt” is not allowed. Allowed extensions are: tiff, jpg, jpeg, png, webp."
                      ]
                    }
                  },
                  "File too large": {
                    "summary": "업로드가 5MB 제한을 초과함",
                    "value": {
                      "user_image": [
                        "File size should not exceed 5 MB"
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었거나 호출한 조직의 잔액이 호출 비용을 충당할 수 없을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 키가 누락된 경우 `{\"detail\": ...}`과 함께 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 크레딧이 부족한 경우 어떠한 이미지 처리도 진행되기 전에 `{\"error\": ...}`과 함께 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 호출 비용을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/face-search/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'user_image=@./selfie.jpg' \\\n  -F 'search_type=most_similar' \\\n  -F 'save_api_request=true' \\\n  -F 'vendor_data=user-123'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.face_search.search(\n    user_image=open(\"user_image.jpg\", \"rb\"),\n    search_type=\"most_similar\",\n    rotate_image=False,\n    save_api_request=True,\n    vendor_data=\"user-123\",\n    metadata={\"flow\": \"dedup_check\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.faceSearch.search({\n  user_image: await fileFromPath(\"user_image.jpg\"),\n  search_type: \"most_similar\",\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"dedup_check\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FaceSearch.Search(ctx, didit.FaceSearchSearchParams{\n\tUserImage:      didit.FileFromPath(\"user_image.jpg\"),\n\tSearchType:     didit.Some(didit.FaceSearchSearchParamsSearchType(\"most_similar\")),\n\tRotateImage:    didit.Bool(false),\n\tSaveAPIRequest: didit.Bool(true),\n\tVendorData:     didit.String(\"user-123\"),\n\tMetadata:       didit.Some(map[string]any{\"flow\": \"dedup_check\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.FaceSearchSearchParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.faceSearch().search(FaceSearchSearchParams.builder()\n        .userImage(Path.of(\"user_image.jpg\"))\n        .searchType(FaceSearchSearchParams.SearchType.of(\"most_similar\"))\n        .rotateImage(false)\n        .saveApiRequest(true)\n        .vendorData(\"user-123\")\n        .metadata(Map.of(\"flow\", \"dedup_check\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->faceSearch->search([\n    'user_image' => File::fromPath('user_image.jpg'),\n    'search_type' => 'most_similar',\n    'rotate_image' => false,\n    'save_api_request' => true,\n    'vendor_data' => 'user-123',\n    'metadata' => ['flow' => 'dedup_check'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.face_search.search(\n  user_image: Pathname(\"user_image.jpg\"),\n  search_type: \"most_similar\",\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"dedup_check\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FaceSearch.SearchAsync(new FaceSearchSearchParams\n{\n    UserImage = FileUpload.FromPath(\"user_image.jpg\"),\n    SearchType = new FaceSearchSearchParamsSearchType(\"most_similar\"),\n    RotateImage = false,\n    SaveApiRequest = true,\n    VendorData = \"user-123\",\n    Metadata = new Dictionary<string, object> { [\"flow\"] = \"dedup_check\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/sessions/": {
      "get": {
        "summary": "필터 및 페이지네이션을 사용하여 인증 세션(KYC 및/또는 KYB) 목록을 조회합니다",
        "description": "API 키로 식별되는 애플리케이션의 인증 세션을 최신순(내림차순 `session_number`)으로 페이지로 나누어 반환합니다.\n\n**표준 URL:** 경로는 `/v3/sessions/`(끝에 슬래시 포함)입니다. 슬래시가 없는 `/v3/sessions`로 전송된 요청은 쿼리 문자열이 유지된 채 슬래시가 포함된 URL로 `301` 리디렉션되며, 대부분의 HTTP 클라이언트는 GET 요청 시 이를 자동으로 따라갑니다.\n\n**이 endpoint와 webhook을 언제 사용하는지.** 이 endpoint는 대시보드, 백오피스 검색, 대사 작업 및 배치 내보내기에 사용하세요. 개별 인증의 진행 상황을 추적하기 위해 폴링하지 마세요. 대신 세션이 변경되는 즉시 `status.updated` 이벤트를 푸시하는 [webhook](/ko/integration/webhooks)을 구성하세요. 단일 세션의 전체 결과를 확인하려면 `GET /v3/session/{sessionId}/decision/`을 호출하세요.\n\n**KYC 및 KYB 세션.** `session_kind`는 나열할 세션 종류를 선택합니다:\n- `user`(기본값) - 사용자 인증(KYC) 세션만 해당합니다. 하위 호환성을 유지하는 동작입니다.\n- `business` - 기업 확인(KYB) 세션만 해당합니다. 행의 형식이 다르고 더 간소화되어 있습니다(응답 스키마 참조).\n- `all` - 한 번의 응답에 두 종류가 모두 포함됩니다. 동일한 `limit`/`offset`에 대한 KYC 페이지와 KYB 페이지가 `results`에 이어 붙여져 반환되며(KYC 행이 먼저 표시됨), 한 페이지에 최대 `2 x limit`개의 행이 포함될 수 있습니다. `count`는 두 종류의 합계이며 `next`/`previous`는 KYC 측 페이지네이션을 반영합니다. 혼합된 데이터의 엄격한 페이지네이션을 원하시면 `user`와 `business`를 별도로 호출하세요.\n\n모든 행에는 `session_kind` 구분자(`\"user\"` 또는 `\"business\"`)가 포함되어 있습니다.\n\n**페이지네이션.** 표준 limit/offset 방식입니다: `limit`(기본값 50) 및 `offset`(기본값 0)과 함께 바로 사용할 수 있는 `next`/`previous` 페이지 URL이 제공됩니다. KYC 행의 경우 `count`는 정확한 값입니다. KYB 행의 경우 `count`는 제한된 스캔으로 계산되며 최대 100으로 제한됩니다. 100개를 초과하는 일치 항목이 있더라도 100으로 유지되므로, `count`에서 전체 페이지 수를 계산하기보다는 `next`를 사용하거나(또는 전체 페이지가 반환되었는지 확인하여) 반복 처리하세요.\n\n**필터 시맨틱.** 모든 필터는 AND 조건으로 결합되며 KYC 행에 적용됩니다. `session_kind`가 `business` 또는 `all`인 경우, KYB 측에는 공유 파라미터인 `vendor_data`, `status`, `workflow_id`, `country`(법인 등기부 국가 코드), `date_from`, `date_to`, `search`(회사명, 등록번호 — 구분자 없이 입력, 예: `DPC-001`이 아닌 `DPC001` — vendor_data, 세션 번호 또는 세션 UUID), `warning`, `organization_name`이 적용되며, 나머지 KYC 전용 필터는 KYB 행에서 무시됩니다. 쉼표로 구분된 파라미터(`status`, `country`, `document_type`, `region`, `workflow_id`, `document_name`, `warning`, `organization_name`, `session_type`)는 나열된 값 중 하나라도 일치하면 검색됩니다(파라미터 내 OR 조건). `vendor_data`는 정확히 일치해야 합니다. 부분 일치를 원하시면 `search`를 사용하세요. 목록 필터에 알 수 없는 값이 입력되면 단순히 행이 반환되지 않으며(오류 없음), 유형이 지정된 값의 형식이 잘못된 경우(`date_from`, `date_to`, `didit_internal_id`, `api_service`, `session_kind`)는 필드별 오류 객체와 함께 `400`을 반환합니다.\n\n**검색.** `search`는 입력값에 맞게 동작합니다. 완전한 UUID는 `session_id`를 조회하고, 숫자(선택적으로 `+ - . space` 포함)는 세션 번호 접두사, 문서/개인 식별 번호, 전화번호 접두사 또는 `vendor_data`와 일치하며, `@`가 포함된 값은 이메일 접두사와 일치하고, 그 외의 텍스트는 이름(악센트 무시) 및 `vendor_data`와 일치합니다.\n\n고정된 endpoint별 속도 제한은 적용되지 않지만, 목록 폴링 빈도를 낮게 유지하고 실시간 업데이트에는 webhook을 활용하세요.",
        "operationId": "get_v3_sessions",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "session_kind",
            "in": "query",
            "required": false,
            "description": "조회할 세션의 종류: `user`(KYC 전용, 기본값), `business`(KYB 전용), 또는 `all`(둘 다 결합됨 - 병합된 페이지네이션 시맨틱은 설명 참조). 대소문자를 구분하지 않고 일치하며(`BUSINESS`도 동작함), `user`/`business`/`all`의 대소문자 변형 이외의 값은 `400`을 반환합니다.",
            "schema": {
              "type": "string",
              "enum": [
                "user",
                "business",
                "all"
              ],
              "default": "user"
            },
            "example": "all"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "페이지당 최대 행 수(`session_kind=all`인 경우 종류별)입니다. 기본값은 50입니다.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "example": 20
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "반환되는 첫 번째 행 전에 건너뛸 행 수입니다. 기본값은 0입니다. 응답의 `next`/`previous` URL을 따르는 것을 권장합니다.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "example": 20
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "포함할 쉼표로 구분된 세션 상태 목록입니다(예: `Approved,In Review`). 값은 대소문자를 구분합니다. [인증 상태](/ko/integration/verification-statuses)를 참고하십시오. 알 수 없는 값은 아무것도 일치하지 않습니다.",
            "schema": {
              "type": "string"
            },
            "example": "Approved,In Review"
          },
          {
            "name": "vendor_data",
            "in": "query",
            "required": false,
            "description": "세션 생성 시 전송한 `vendor_data`(자체 사용자/기업 식별자)에 대한 정확한 일치 필터입니다. 부분 일치의 경우 대신 `search`를 사용하십시오.",
            "schema": {
              "type": "string"
            },
            "example": "your-user-id-123"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "`S-0001`(사용자) 또는 `B-0001`(기업)과 같은 완전한 표시 참조는 해당 세션 번호 및 종류와 정확히 일치할 때만 검색됩니다. 앞자리 0과 대소문자는 일치 여부에 영향을 주지 않습니다. 스마트 자유 텍스트 검색. 전체 UUID는 `session_id`와 일치합니다. 숫자 입력은 세션 번호 접두사, 문서/개인 식별 번호, 전화번호 접두사 또는 `vendor_data`와 일치합니다. `@`가 포함된 입력은 이메일 접두사와 일치합니다. 기타 텍스트는 이름(악센트 미구분) 및 `vendor_data`와 일치합니다. 숫자가 포함된 자유 텍스트는 문서/개인 식별 번호 검색 필드 및 세션 번호 접두사와도 추가로 일치합니다.",
            "schema": {
              "type": "string"
            },
            "example": "jane doe"
          },
          {
            "name": "workflow_id",
            "in": "query",
            "required": false,
            "description": "쉼표로 구분된 워크플로 UUID 목록입니다(이 UUID는 Console의 Workflows 페이지에서 확인할 수 있습니다). 목록에서 형식이 잘못된 UUID는 무시되며, 유효한 값이 없으면 결과가 비어 있습니다.",
            "schema": {
              "type": "string"
            },
            "example": "9f9b1234-aaaa-bbbb-cccc-1234567890ab"
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "description": "이 날짜(UTC) 이후(해당 날짜 포함)에 생성된 세션만 해당하며, 형식은 `YYYY-MM-DD`입니다. 잘못된 형식의 날짜는 `400`을 반환합니다.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-06-01"
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "description": "이 날짜(UTC)까지 생성된 세션만 해당하며, 형식은 `YYYY-MM-DD`입니다. KYC 행의 경우 당일 전체가 포함되며, KYB 행의 경우 비교 조건이 `created_at <= date_to`(자정)이므로 KYB 세션의 하루 전체를 포함하려면 다음 날 날짜를 사용하십시오.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-06-30"
          },
          {
            "name": "tags",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "쉼표로 구분된 태그 ID(애플리케이션의 `tags`)입니다. 이 중 하나라도 포함된 세션을 반환합니다. 유효한 UUID가 아닌 ID는 무시되며, 유효한 ID가 없으면 목록이 비어 있습니다."
          },
          {
            "name": "decided_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "ISO 8601 일시입니다. 상태가 해당 시점 이후에 마지막으로 변경된 세션을 반환합니다. 생성 시간이 아닌 마지막 상태 변경 시간을 기준으로 필터링합니다."
          },
          {
            "name": "decided_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "ISO 8601 일시입니다. 상태가 해당 시점 이전에 마지막으로 변경된 세션을 반환합니다. 반개방 구간을 설정하려면 `decided_from`과 함께 사용하세요."
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "쉼표로 구분된 국가 필터입니다. KYC 행의 경우: 신분증 발급 국가의 ISO 3166-1 alpha-3 코드(예: `ESP,USA`)이며 국적과 다를 수 있습니다. KYB 행의 경우: 등기된 기업의 국가 코드입니다.",
            "schema": {
              "type": "string"
            },
            "example": "ESP,USA"
          },
          {
            "name": "document_type",
            "in": "query",
            "required": false,
            "description": "세션에서 인증된 신분증 유형 코드의 쉼표로 구분된 목록(KYC 행에만 해당): `P`(여권), `ID`(신분증), `DL`(운전면허증), `RP`(거주 허가증), `SSC`(사회보장 카드), `HIC`(건강보험증), `WP`(취업 허가증), `TC`(세금 카드), `VISA`, `PSC`(공공 서비스 카드), `BC`(출생 증명서), `OTHER`. 응답 필드 `document_type`에는 코드가 아닌 표시 이름이 포함됩니다.",
            "schema": {
              "type": "string"
            },
            "example": "P,ID"
          },
          {
            "name": "document_name",
            "in": "query",
            "required": false,
            "description": "정확한 문서 이름입니다. 쉼표로 구분하여 여러 이름을 전달할 수 있지만, 값이 둘 이상의 ` - ` 구분 기호를 포함할 때만 쉼표 기준으로 분리됩니다(쉼표가 포함된 단일 이름은 전체가 일치 항목으로 처리됨). 이름은 신분증 검증(앞면 또는 뒷면)에서 인식된 형식(예: `Spain - Id Card (2021)`)입니다. KYC 행에만 해당합니다.",
            "schema": {
              "type": "string"
            },
            "example": "Spain - Id Card (2021)"
          },
          {
            "name": "region",
            "in": "query",
            "required": false,
            "description": "쉼표로 구분된 문서 지역/주 값(미국 운전면허증과 같이 지역별로 발급되는 문서용). KYC 행에만 해당합니다.",
            "schema": {
              "type": "string"
            },
            "example": "CA,TX"
          },
          {
            "name": "didit_internal_id",
            "in": "query",
            "required": false,
            "description": "인증된 사용자 한 명의 모든 세션을 나열하려면 Didit의 내부 사용자 식별자(`didit_internal_id` 응답 필드)로 필터링하십시오. 유효한 UUID여야 하며, 형식이 잘못된 값은 `400`을 반환합니다. KYC 행에만 해당합니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "d9e78474-6c8d-4f2a-bb90-6f5c2f3a1147"
          },
          {
            "name": "session_type",
            "in": "query",
            "required": false,
            "description": "쉼표로 구분된 세션 생성 채널: `API`, `HOSTED`, `MIGRATED`. 특수 값 `ALL`(또는 파라미터 생략)은 필터를 비활성화합니다. KYC 행에만 해당합니다.",
            "schema": {
              "type": "string"
            },
            "example": "HOSTED"
          },
          {
            "name": "api_service",
            "in": "query",
            "required": false,
            "description": "서비스별로 독립형 API 세션을 필터링합니다. 유효하지 않은 값은 `400`을 반환합니다. KYC 행 전용입니다.",
            "schema": {
              "type": "string",
              "enum": [
                "ID_VERIFICATION",
                "FACE_MATCH",
                "AGE_ESTIMATION",
                "FACE_SEARCH",
                "POA",
                "AML",
                "KYB_REGISTRY",
                "PASSIVE_LIVENESS",
                "DATABASE_VALIDATION",
                "PHONE_VERIFICATION",
                "EMAIL_VERIFICATION"
              ]
            },
            "example": "AML"
          },
          {
            "name": "screened_full_name",
            "in": "query",
            "required": false,
            "description": "AML 및 데이터베이스 검증 스크리닝 데이터 내에서 악센트를 구분하지 않는 이름 검색입니다. `api_service=AML` 또는 `api_service=DATABASE_VALIDATION`과 결합하면 검색이 해당 기능의 스크리닝 데이터로 제한됩니다. KYC 행에만 해당합니다.",
            "schema": {
              "type": "string"
            },
            "example": "Jane Doe"
          },
          {
            "name": "warning",
            "in": "query",
            "required": false,
            "description": "쉼표로 구분된 경고 위험 코드입니다. 이 중 하나라도 발생시킨 세션을 반환합니다(예: `POSSIBLE_FRAUD`). 위험 코드는 [경고 문서](/ko/integration/webhooks)에 기능별로 나열되어 있습니다. KYC 행에 적용되며, 기업 경고 코드가 있는 경우 KYB 행에도 적용됩니다.",
            "schema": {
              "type": "string"
            },
            "example": "POSSIBLE_FRAUD"
          },
          {
            "name": "status_initialized_as_in_review",
            "in": "query",
            "required": false,
            "description": "`true`인 경우 결정이 처음에 `In Review`에 도달했던 세션만 해당합니다(수동 검토 처리량을 감사할 때 유용함). KYC 행만 해당합니다.",
            "schema": {
              "type": "boolean"
            },
            "example": true
          },
          {
            "name": "is_kyc_to_be_reviewed",
            "in": "query",
            "required": false,
            "description": "`true`는 신분증 인증이 수동 검토 대상으로 표시된 세션을 반환합니다. `false`는 신분증 인증이 명시적으로 수동 검토 대상으로 표시되지 않은 세션을 반환합니다. 비활성화하려면 생략하십시오. KYC 행에만 해당합니다.",
            "schema": {
              "type": "boolean"
            },
            "example": true
          },
          {
            "name": "euuid",
            "in": "query",
            "required": false,
            "description": "최종 사용자의 euuid(인증 중인 사용자에게 할당된 UUID로, Console 딥링크에서 사용됨)로 필터링합니다. 유효한 UUID여야 하며, 형식이 잘못된 값은 400 필드 오류를 반환합니다. KYC 행 전용입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "0f8fad5b-d9cb-469f-a165-70867728950e"
          },
          {
            "name": "organization_name",
            "in": "query",
            "required": false,
            "description": "쉼표로 구분된 조직 이름입니다. 콘솔 중심이며, API 키(이미 하나의 애플리케이션으로 범위가 지정됨)를 사용하면 자체 조직 이름과만 일치합니다.",
            "schema": {
              "type": "string"
            },
            "example": "Acme Inc"
          }
        ],
        "responses": {
          "200": {
            "description": "페이지네이션된 세션 목록입니다. `results` 항목은 `session_kind`에 따라 KYC 행, KYB 행 또는 둘 다일 수 있으며, 각 행의 `session_kind` 필드로 구분합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "필터와 일치하는 세션 수: 최대 100개까지는 정확하며 100개를 초과하면 100으로 제한되므로 총계로 사용하지 마십시오. 추가 페이지가 있는지 확인하려면 `next`를 사용하십시오. `session_kind=all`의 경우 두 종류의 합계이며, 각각 100으로 제한됩니다.",
                      "example": 2
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "다음 페이지의 절대 URL이며, 마지막 페이지에서는 `null`입니다.",
                      "example": "https://verification.didit.me/v3/sessions/?limit=20&offset=20"
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "이전 페이지의 절대 URL이며, 첫 번째 페이지에서는 `null`입니다.",
                      "example": null
                    },
                    "results": {
                      "type": "array",
                      "description": "세션 행 목록으로, 최신순으로 정렬됩니다. `session_kind=all`인 경우 KYC 행이 먼저 표시된 다음 KYB 행이 표시됩니다.",
                      "items": {
                        "oneOf": [
                          {
                            "$ref": "#/components/schemas/UserSessionListItem"
                          },
                          {
                            "$ref": "#/components/schemas/BusinessSessionListItem"
                          }
                        ],
                        "discriminator": {
                          "propertyName": "session_kind",
                          "mapping": {
                            "user": "#/components/schemas/UserSessionListItem",
                            "business": "#/components/schemas/BusinessSessionListItem"
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "KYC sessions (default)": {
                    "summary": "session_kind=user - 완료된 세션 1개 및 시작되지 않은 세션 1개",
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "session_id": "5b3720ed-d429-42ef-b67f-37ea805f48ee",
                          "session_kind": "user",
                          "session_number": 720,
                          "session_url": "https://verify.didit.me/session/CuXoBYCYVO5Y",
                          "portrait_image": "https://<media-host>/portraits/5b3720ed.jpg?X-Amz-Expires=3600&X-Amz-Signature=...",
                          "document_type": "Passport",
                          "full_name": "Jane Marie Doe",
                          "country": "ESP",
                          "status": "Approved",
                          "vendor_data": "your-user-id-123",
                          "didit_internal_id": "d9e78474-6c8d-4f2a-bb90-6f5c2f3a1147",
                          "created_at": "2026-06-09T12:26:54.328364Z",
                          "features": [
                            {
                              "feature": "ID_VERIFICATION",
                              "status": "Approved"
                            },
                            {
                              "feature": "LIVENESS",
                              "status": "Approved"
                            },
                            {
                              "feature": "FACE_MATCH",
                              "status": "Approved"
                            },
                            {
                              "feature": "AML",
                              "status": "Approved"
                            },
                            {
                              "feature": "IP_ANALYSIS",
                              "status": "Approved"
                            }
                          ],
                          "phone_number": {
                            "number": "+14155552671",
                            "is_verified": true
                          },
                          "email_address": {
                            "email": "jane@example.com",
                            "is_verified": true
                          },
                          "additional_details": {
                            "aml": {
                              "total_hits": 0,
                              "entity_type": "person",
                              "is_adverse_media_fetched": false
                            },
                            "liveness": {
                              "method": "PASSIVE",
                              "score": 0.98
                            },
                            "face_match": {
                              "score": 0.95
                            }
                          }
                        },
                        {
                          "session_id": "038ad62f-5ebd-46c2-afe9-4b2956bf687f",
                          "session_kind": "user",
                          "session_number": 719,
                          "session_url": "https://verify.didit.me/session/7RGKiO6ioGH6",
                          "portrait_image": null,
                          "document_type": null,
                          "full_name": null,
                          "country": null,
                          "status": "Not Started",
                          "vendor_data": "your-user-id-124",
                          "didit_internal_id": "eb4e679d-ca4b-461f-9685-687bac29ebdb",
                          "created_at": "2026-06-09T08:02:23.343053Z",
                          "features": [
                            {
                              "feature": "ID_VERIFICATION",
                              "status": "Not Finished"
                            },
                            {
                              "feature": "LIVENESS",
                              "status": "Not Finished"
                            },
                            {
                              "feature": "FACE_MATCH",
                              "status": "Not Finished"
                            },
                            {
                              "feature": "AML",
                              "status": "Not Finished"
                            },
                            {
                              "feature": "IP_ANALYSIS",
                              "status": "Not Finished"
                            }
                          ],
                          "phone_number": null,
                          "email_address": null,
                          "additional_details": null
                        }
                      ]
                    }
                  },
                  "Mixed KYC + KYB (session_kind=all)": {
                    "summary": "session_kind=all - KYC 행 뒤에 KYB 행이 이어집니다",
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "session_id": "5b3720ed-d429-42ef-b67f-37ea805f48ee",
                          "session_kind": "user",
                          "session_number": 720,
                          "session_url": "https://verify.didit.me/session/CuXoBYCYVO5Y",
                          "portrait_image": null,
                          "document_type": "Identity Card",
                          "full_name": "Jane Marie Doe",
                          "country": "ESP",
                          "status": "In Review",
                          "vendor_data": "your-user-id-123",
                          "didit_internal_id": "d9e78474-6c8d-4f2a-bb90-6f5c2f3a1147",
                          "created_at": "2026-06-09T12:26:54.328364Z",
                          "features": [
                            {
                              "feature": "ID_VERIFICATION",
                              "status": "In Review"
                            },
                            {
                              "feature": "LIVENESS",
                              "status": "Approved"
                            }
                          ],
                          "phone_number": null,
                          "email_address": null,
                          "additional_details": {
                            "liveness": {
                              "method": "PASSIVE",
                              "score": 0.98
                            }
                          }
                        },
                        {
                          "session_id": "8a1f63c2-1b9e-4f3a-9c41-2f6a1f0b7d52",
                          "session_kind": "business",
                          "session_number": 42,
                          "status": "Approved",
                          "vendor_data": "your-company-id-77",
                          "created_at": "2026-06-08T09:14:02.118450Z",
                          "workflow_id": "9f9b1234-aaaa-bbbb-cccc-1234567890ab",
                          "workflow_type": "kyb",
                          "workflow_label": "Standard KYB",
                          "company_name": "Acme Holdings S.L.",
                          "registration_number": "B12345678",
                          "country": "ES"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "301": {
            "description": "정규 끝 슬래시 URL로 리디렉션합니다. 요청 경로가 `/v3/sessions`(끝 슬래시 없음)일 때 반환되며, `Location` 헤더는 쿼리 문자열이 보존된 채로 `/v3/sessions/`를 가리킵니다. GET 클라이언트는 일반적으로 이를 자동으로 따릅니다."
          },
          "400": {
            "description": "유효하지 않은 쿼리 파라미터입니다. 본문은 문제가 발생한 파라미터를 키로 갖는 객체입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid session_kind": {
                    "summary": "session_kind가 user/business/all 중 하나가 아닙니다",
                    "value": {
                      "session_kind": "Must be \"user\", \"business\", or \"all\"."
                    }
                  },
                  "Invalid date": {
                    "summary": "잘못된 형식의 date_from/date_to",
                    "value": {
                      "date_from": [
                        "Enter a valid date."
                      ]
                    }
                  },
                  "Invalid didit_internal_id": {
                    "summary": "didit_internal_id가 UUID가 아닙니다",
                    "value": {
                      "didit_internal_id": [
                        "Enter a valid UUID."
                      ]
                    }
                  },
                  "Invalid api_service": {
                    "summary": "api_service가 허용된 선택 항목에 없습니다",
                    "value": {
                      "api_service": [
                        "Select a valid choice. FOO is not one of the available choices."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 형식이 잘못되었거나 폐기되었습니다. 누락된 키는 `403`을 반환하며, 잘못되었거나 폐기되었거나 만료된 키는 `401`을 반환합니다.\n\n**삭제된 애플리케이션:** 애플리케이션이 삭제된 후 몇 분 동안 해당 API 키 중 하나로 요청을 보내면 `{\"detail\": \"This application was deleted.\", \"code\": \"application_deleted\"}`로 응답할 수 있습니다. 다시 시도하지 마세요. 해당 애플리케이션과 API 키는 더 이상 존재하지 않습니다. 몇 분이 지나면 다른 유효하지 않은 키와 마찬가지로 키가 거부됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "You do not have permission to perform this action."
                    },
                    "code": {
                      "type": "string",
                      "description": "기계 판독 가능한 사유로, 일부 실패 시에만 제공됩니다. `application_deleted`: API 키가 삭제된 애플리케이션에 속해 있습니다.",
                      "example": "application_deleted"
                    }
                  },
                  "required": [
                    "detail"
                  ]
                },
                "examples": {
                  "Forbidden": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "ApplicationDeleted": {
                    "summary": "삭제된 애플리케이션의 API 키",
                    "value": {
                      "detail": "This application was deleted.",
                      "code": "application_deleted"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -s 'https://verification.didit.me/v3/sessions/?status=Approved,In%20Review&date_from=2026-06-01&limit=20' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.ListAutoPaging(ctx, didit.SessionsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->sessions->list() as $item) {\n    print_r($item);\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/share/": {
      "post": {
        "summary": "완료된 인증 세션에 대한 공유 토큰 생성",
        "description": "특정 Didit 애플리케이션이 이 완료된 세션을 가져올 수 있도록 수명이 짧은 JWT를 생성합니다. `POST /v3/session/import-shared/`와 함께 사용하십시오.",
        "operationId": "post_v3_session_share",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "share",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "responses": {
          "200": {
            "description": "공유 token이 발행되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "share_token": {
                      "type": "string",
                      "description": "HS256 서명된 JWT입니다. 대상 애플리케이션의 [`POST /v3/session/import-shared/`](/sessions-api/import-shared-session)에 `share_token`으로 그대로 전달하십시오.",
                      "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
                    },
                    "for_application_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "token이 바인딩된 대상 애플리케이션 UUID를 반환합니다.",
                      "example": "a5f3bca2-46e2-411e-90ef-a580900a57ee"
                    },
                    "session_kind": {
                      "type": "string",
                      "enum": [
                        "user",
                        "business"
                      ],
                      "description": "소스 세션이 사용자 인증(KYC) 또는 기업 확인(KYB) 세션인지 여부입니다."
                    }
                  }
                },
                "examples": {
                  "User session": {
                    "summary": "KYC 세션 공유",
                    "value": {
                      "share_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9uX2lkIjoiMjBiYjNjM2ItNjE0Ni00MzlmLTg0YTQtYmQzMGQwMGFjNmEyIiwiZnJvbV9hcHBsaWNhdGlvbl9pZCI6ImRiZDIwZTM0LTQyZTktNGYyYy1iYTkxLWNmMDc2MjAxNmY2NCIsImZvcl9hcHBsaWNhdGlvbl9pZCI6ImE1ZjNiY2EyLTQ2ZTItNDExZS05MGVmLWE1ODA5MDBhNTdlZSIsImlhdCI6MTc1MzYzMDY2NiwiZXhwIjoxNzUzNjM0MjY2fQ.JJ9pNE_hqZsOtbR0XYZIWw4JzidjdEl279iUrsIkhGE",
                      "for_application_id": "a5f3bca2-46e2-411e-90ef-a580900a57ee",
                      "session_kind": "user"
                    }
                  },
                  "Business session": {
                    "summary": "KYB 세션 공유",
                    "value": {
                      "share_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
                      "for_application_id": "a5f3bca2-46e2-411e-90ef-a580900a57ee",
                      "session_kind": "business"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "자격 증명이 누락되었거나 유효하지 않습니다. 대부분의 v3 endpoint와 달리, 이 endpoint는 권한 데코레이터를 통해 인증하며 유효한 token/키가 제공되지 않으면 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Unauthorized": {
                    "summary": "권한 없음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 해당 `session_id`를 가진 세션이 존재하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "세션을 찾을 수 없습니다",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 필드 오류는 필드 이름을 키로 하며, 완료되지 않음 오류는 `detail` 키 아래에 배열로 전달됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Wrong status": {
                    "summary": "소스 세션이 완료되지 않았습니다",
                    "value": {
                      "detail": [
                        "Only finished sessions (\"Approved\", \"Declined\", \"In Review\") can be shared."
                      ]
                    }
                  },
                  "Target missing": {
                    "summary": "대상 애플리케이션이 존재하지 않음",
                    "value": {
                      "for_application_id": [
                        "Target application does not exist."
                      ]
                    }
                  },
                  "Self-share": {
                    "summary": "대상이 호출 애플리케이션임",
                    "value": {
                      "for_application_id": [
                        "Cannot share a session with the same application."
                      ]
                    }
                  },
                  "TTL bounds": {
                    "summary": "ttl_in_seconds가 허용 범위를 벗어났습니다",
                    "value": {
                      "ttl_in_seconds": [
                        "Ensure this value is greater than or equal to 60."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 유효하지만 이 애플리케이션에 대한 `write:sessions` 권한이 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "No Permission": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    },
                    "summary": "권한 없음"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "토큰을 발급할 소스 인증 세션의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "for_application_id"
                ],
                "properties": {
                  "for_application_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "token을 사용할 Didit 애플리케이션의 UUID입니다. 반드시 존재해야 하고, 삭제되지 않아야 하며, 호출하는 애플리케이션과 달라야 합니다. Business Console의 **Settings → Application**에서 확인할 수 있습니다.",
                    "example": "a5f3bca2-46e2-411e-90ef-a580900a57ee"
                  },
                  "ttl_in_seconds": {
                    "type": "integer",
                    "description": "token 유효 기간(초 단위)입니다. 최소 `60`, 최대 `86400`(24시간)입니다. 기본값은 `3600`(1시간)입니다.",
                    "minimum": 60,
                    "maximum": 86400,
                    "default": 3600,
                    "example": 3600
                  }
                }
              },
              "example": {
                "for_application_id": "a5f3bca2-46e2-411e-90ef-a580900a57ee",
                "ttl_in_seconds": 7200
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/share/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"for_application_id\": \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n    \"ttl_in_seconds\": 7200\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.share(\n    \"11111111-2222-3333-4444-555555555555\",\n    for_application_id=\"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n    ttl_in_seconds=7200,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.share(\"11111111-2222-3333-4444-555555555555\", {\n  for_application_id: \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n  ttl_in_seconds: 7200,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Share(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsShareParams{\n\tForApplicationID: \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n\tTTLInSeconds:     didit.Int(7200),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsShareParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().share(\"11111111-2222-3333-4444-555555555555\", SessionsShareParams.builder()\n        .forApplicationId(\"a5f3bca2-46e2-411e-90ef-a580900a57ee\")\n        .ttlInSeconds(7200L)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->share('11111111-2222-3333-4444-555555555555', [\n    'for_application_id' => 'a5f3bca2-46e2-411e-90ef-a580900a57ee',\n    'ttl_in_seconds' => 7200,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.share(\n  \"11111111-2222-3333-4444-555555555555\",\n  for_application_id: \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n  ttl_in_seconds: 7200\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ShareAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsShareParams\n{\n    ForApplicationId = \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n    TtlInSeconds = 7200,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/import-shared/": {
      "post": {
        "summary": "공유 token을 사용하여 인증 세션을 애플리케이션에 복제",
        "description": "공유 token을 사용하여 새 `session_id`로 KYC 또는 KYB 세션을 호출하는 애플리케이션에 복제합니다. 멱등성이 없습니다 — 수신자당 한 번만 token을 사용할 수 있습니다.",
        "operationId": "post_v3_session_import_shared",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "import_shared",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "responses": {
          "201": {
            "description": "세션이 복제되었습니다. 본문은 두 종류 모두에 대한 V3 결정 payload이며, `session_kind`로 구분됩니다. `\"user\"`(KYC)는 `id_verifications`, `liveness_checks`, `aml_screenings`와 같은 목록 기반 기능 블록을 포함하며, `\"business\"`(KYB)는 `registry_checks` 및 `key_people_checks`와 같은 블록을 포함합니다. 둘 다 원본 애플리케이션의 원본 세션 `session_id`인 `shared_from_session`을 포함합니다. `trust_review: false`인 경우 복제된 세션의 `status`는 `In Review`로 강제 설정됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionDecision"
                },
                "examples": {
                  "User session imported": {
                    "summary": "복제된 KYC 세션(축약됨 — 실제로는 전체 V3 결정 payload)",
                    "value": {
                      "session_id": "11111111-2222-3333-4444-555555555555",
                      "session_kind": "user",
                      "shared_from_session": "99999999-8888-7777-6666-555555555555",
                      "session_number": 43762,
                      "session_url": null,
                      "status": "In Review",
                      "workflow_id": "9f9b1234-aaaa-bbbb-cccc-1234567890ab",
                      "vendor_data": "user-1",
                      "created_at": "2026-05-17T08:42:11Z",
                      "expires_at": "2026-05-24T08:42:11Z"
                    }
                  },
                  "Business session imported": {
                    "summary": "복제된 KYB 세션(축약됨 — 실제로는 전체 V3 KYB 결정 payload)",
                    "value": {
                      "session_id": "22222222-3333-4444-5555-666666666666",
                      "session_kind": "business",
                      "shared_from_session": "88888888-7777-6666-5555-444444444444",
                      "session_number": 982,
                      "session_url": null,
                      "status": "Approved",
                      "workflow_id": "9f9b1234-aaaa-bbbb-cccc-1234567890ab",
                      "vendor_data": "company-1"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 오류(token이 유효하지 않거나 만료되었거나 대상이 잘못되었거나 더 이상 존재하지 않는 세션을 참조함).",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Share Token": {
                    "summary": "유효하지 않은 JWT",
                    "value": {
                      "share_token": [
                        "Invalid share token."
                      ]
                    }
                  },
                  "Expired Share Token": {
                    "summary": "`exp`가 지난 token",
                    "value": {
                      "share_token": [
                        "Share token has expired."
                      ]
                    }
                  },
                  "Wrong audience": {
                    "summary": "이 애플리케이션에 바인딩되지 않은 token",
                    "value": {
                      "share_token": [
                        "This token is not valid for this application."
                      ]
                    }
                  },
                  "Original missing": {
                    "summary": "소스 세션이 삭제되었습니다",
                    "value": {
                      "share_token": [
                        "Original session does not exist."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나(잘못되었거나 취소되었거나 만료된 키는 `401` 수신), 이 원본 세션이 이미 호출 애플리케이션으로 가져오기되었습니다(수신자당 1회 교환).",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "summary": "금지됨",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Already imported": {
                    "summary": "출처를 이미 한 번 가져왔습니다",
                    "value": {
                      "detail": "This session has already been shared with your application."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`workflow_id`가 호출하는 애플리케이션에 속하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Workflow not found": {
                    "summary": "알 수 없는 워크플로",
                    "value": {
                      "detail": "Workflow does not exist for this application."
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "share_token",
                  "trust_review",
                  "workflow_id"
                ],
                "properties": {
                  "share_token": {
                    "type": "string",
                    "description": "[`POST /v3/session/{sessionId}/share/`](/sessions-api/share-session)에서 발급된 JWT 공유 token입니다.",
                    "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
                  },
                  "trust_review": {
                    "type": "boolean",
                    "description": "`true`인 경우 복제된 세션이 원본의 최종 `status`를 유지합니다. `false`인 경우 `In Review` 상태로 강제 전환됩니다.",
                    "example": false
                  },
                  "workflow_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "호출하는 애플리케이션 내 워크플로의 UUID입니다. 다른 애플리케이션의 ID는 `404`로 거부됩니다.",
                    "example": "9f9b1234-aaaa-bbbb-cccc-1234567890ab"
                  },
                  "vendor_data": {
                    "type": "string",
                    "nullable": true,
                    "description": "복제된 세션의 `vendor_data`에 대한 선택적 재정의 값입니다.",
                    "example": "user-1"
                  }
                }
              },
              "example": {
                "share_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
                "trust_review": false,
                "workflow_id": "9f9b1234-aaaa-bbbb-cccc-1234567890ab",
                "vendor_data": "user-1"
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/import-shared/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"share_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n    \"trust_review\": false,\n    \"workflow_id\": \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n    \"vendor_data\": \"user-1\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.import_shared(\n    share_token=\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n    trust_review=False,\n    workflow_id=\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n    vendor_data=\"user-1\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.importShared({\n  share_token: \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n  trust_review: false,\n  workflow_id: \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n  vendor_data: \"user-1\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ImportShared(ctx, didit.SessionsImportSharedParams{\n\tShareToken:  \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n\tTrustReview: false,\n\tWorkflowID:  \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n\tVendorData:  didit.String(\"user-1\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsImportSharedParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().importShared(SessionsImportSharedParams.builder()\n        .shareToken(\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\")\n        .trustReview(false)\n        .workflowId(\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\")\n        .vendorData(\"user-1\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->importShared([\n    'share_token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',\n    'trust_review' => false,\n    'workflow_id' => '9f9b1234-aaaa-bbbb-cccc-1234567890ab',\n    'vendor_data' => 'user-1',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.import_shared(\n  share_token: \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n  trust_review: false,\n  workflow_id: \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n  vendor_data: \"user-1\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ImportSharedAsync(new SessionsImportSharedParams\n{\n    ShareToken = \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n    TrustReview = false,\n    WorkflowId = \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n    VendorData = \"user-1\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/kyb/search/": {
      "post": {
        "summary": "KYB 등기부 기업 검색(독립 실행형)",
        "operationId": "post_v3_kyb_search",
        "x-didit-sdk": {
          "resource": "kyb",
          "method": "search",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [],
        "description": "회사명 및/또는 등록번호로 공식 법인 등기부에서 후보 기업을 검색합니다. 이는 2단계 등기부 조회의 1단계입니다. **search**는 가벼운 후보 목록을 반환하고, `POST /v3/kyb/select/`가 한 후보의 전체 프로필을 조회합니다.\n\n**검색 결제.** 유료 기업 데이터 소스를 사용한 성공한 검색에는 후보 수와 관계없이 요청당 USD 0.50가 부과됩니다. 빈 결과, 실패 및 기타 소스로만 제공된 결과에는 요금이 부과되지 않습니다. 해당 가격은 검색 전에 예약되며, 잔액이 부족하면 `insufficient_credits` 코드와 함께 403을 반환합니다. 합의된 계약 요율이 적용되며, 설정되지 않은 계약 검색 요율은 403을 반환합니다. 샌드박스 검색은 무료입니다. 성공한 검색을 반복하면 추가 요금이 발생할 수 있으며, 콜백 전송에는 추가 요금이 부과되지 않습니다. 프로필 조회는 별도로 청구됩니다. 이 검색 수수료는 v2에도 적용됩니다. 후보는 항상 `fetch_status: \"pending\"` 상태로 반환되며, 전체 기업 데이터는 선택(select) 시에만 조회(및 청구)됩니다.\n\n**`kyb_response_id`는 일회성입니다.** 이는 검색별 핸들이며, 영구적인 회사 ID가 아닙니다. 검색 후 즉시 선택하고, 저장하는 대신 다시 검색하여 새로운 핸들을 받으십시오.\n\n**`tier`는 공급자 체인을 선택합니다.** `tier`는 검색이 실행되는 등기부 등급을 지정합니다. `basic`(기본값, Lite 체인), `shareholders` 또는 `ubo`입니다. 검색은 해당 등급을 제공하는 공급자 체인을 사용하며, Lite 검색이 읽는 체인과 항상 동일하지는 않으므로 빈 Lite 검색 결과가 등기부에 회사가 없다는 증거는 아닙니다. 필요한 등급으로 다시 검색하십시오. 지정한 등급을 제공하지 않는 국가는 해당 등급 이하에서 제공하는 최고 등급으로 검색됩니다. 해당 등급을 판매하는 endpoint에서 후보를 조회하십시오. `POST /v3/kyb/select/`(Lite), `POST /v3/kyb/shareholders/` 또는 `POST /v3/kyb/ubo/`.\n\n**인증.** `POST /v3/kyb/search/`(및 `/v2/`)는 `x-api-key` 헤더에 애플리케이션의 API 키를 받습니다. 호스팅된 `POST /v1/kyb/search/`는 호스팅 인증 플로우가 호출하는 세션 인증 경로입니다. API 키에 대해 `403`을 반환하며 `tier`를 받지 않습니다. 워크플로의 KYB 등기부 구성이 체인을 선택합니다.\n\n**두 가지 모드.**\n- *동기(기본값):* API가 검색이 완료될 때까지 등기부를 폴링하고 최종 후보 목록을 반환합니다(`search_resolved: true`).\n- *비동기:* `webhook_url`을 전달하면 API가 즉시 반환되며(일반적으로 `search_status: \"pending\"` 및 빈 후보 목록), 등기부 조회가 완료되면 URL로 `kyb.registry_search.resolved` 콜백을 POST합니다. 콜백 본문은 `{\"event_id\", \"event_type\": \"kyb.registry_search.resolved\", \"request_id\", \"vendor_data\", \"metadata\", \"search_status\", \"search_resolved\", \"kyb_registry\", \"timestamp\", \"created_at\"}`이며(이 endpoint의 ISO `created_at`과 달리 콜백의 `timestamp` 및 `created_at`은 에포크 정수임에 유의), **서명되지 않은** 상태로 전송됩니다(헤더 `X-Didit-Unsigned-Callback: true`, `X-Signature` 없음).\n\n**국가 코드.** ISO 3166-1 alpha-2(`GB`, `DE`)와 등기부가 지역별로 나뉜 경우 `XX-YY` 하위 분할 코드(예: 캘리포니아의 경우 `US-CA`)를 사용합니다.\n\n**샌드박스.** 샌드박스 애플리케이션의 키는 등기부에 접속하지 않고 하나의 정적 후보를 반환합니다.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "country_code"
                ],
                "properties": {
                  "country_code": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "검색할 법인 등기부가 있는 국가의 ISO 3166-1 alpha-2 코드입니다. 예를 들어 `GB`입니다. 법인 등기부가 주 또는 도 단위로 운영되는 경우 `XX-YY` 형식으로 ISO 3166-2 행정 구역 코드를 추가합니다. `US-CA`는 캘리포니아 등기부를 검색합니다. 미국 검색 시에는 항상 행정 구역이 필요하며 단순 `US`는 거부됩니다. 대소문자를 구분하지 않으며 대문자로 정규화됩니다.",
                    "example": "GB"
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "검색할 기업명입니다. `name` 또는 `registration_number` 중 하나는 필수입니다.",
                    "example": "Tesco"
                  },
                  "registration_number": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "검색할 법인 등기부 등록번호입니다. `name` 또는 `registration_number` 중 하나가 필요합니다."
                  },
                  "tier": {
                    "type": "string",
                    "enum": [
                      "basic",
                      "shareholders",
                      "ubo"
                    ],
                    "default": "basic",
                    "description": "이 검색이 실행되는 제공업체 체인의 법인 등기부 등급입니다. `basic`(기본값)은 해당 국가의 Lite 체인을 검색합니다. `shareholders` 및 `ubo`는 해당 등급의 소유 구조 체인을 검색하며 다른 출처일 수 있으므로, Lite 검색 결과가 비어 있다고 해서 법인 등기부에 해당 기업이 없다는 것을 증명하지는 않습니다. 지정된 등급을 제공하지 않는 국가는 해당 등급 이하에서 제공하는 가장 높은 등급으로 검색됩니다. 검색한 등급을 판매하는 endpoint에서 후보를 검색하십시오: `POST /v3/kyb/select/`(Lite), `POST /v3/kyb/shareholders/` 또는 `POST /v3/kyb/ubo/`.",
                    "example": "basic"
                  },
                  "search_type": {
                    "type": "string",
                    "enum": [
                      "contains"
                    ],
                    "default": "contains",
                    "description": "등기부 검색에 적용되는 이름 일치 전략입니다. 허용되는 유일한 값은 `contains`입니다. 검색 대상인 등기부 소스 중 접두사 또는 퍼지 모드를 지원하는 소스가 없으므로 `start_with` 및 `fuzzy`는 `400`(`not a valid choice`) 오류로 거부됩니다."
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "해당 조회에 대한 귀하의 식별자입니다. webhook 콜백에 포함되며 그대로 다시 반환됩니다."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "자유 형식 JSON입니다. 그대로 반환되며 webhook 콜백에 포함됩니다."
                  },
                  "webhook_url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 500,
                    "description": "검색을 비동기 모드로 전환합니다. API가 즉시 반환되며, 후보 목록이 준비되면 이 URL로 서명되지 않은 `kyb.registry_search.resolved` 콜백을 POST합니다."
                  }
                }
              },
              "example": {
                "country_code": "GB",
                "name": "Tesco",
                "search_type": "contains",
                "vendor_data": "company-1234"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/kyb/search/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"country_code\": \"GB\",\n    \"name\": \"Tesco\",\n    \"search_type\": \"contains\",\n    \"vendor_data\": \"company-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.kyb.search(\n    country_code=\"GB\",\n    name=\"Tesco\",\n    search_type=\"contains\",\n    vendor_data=\"company-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.kyb.search({\n  country_code: \"GB\",\n  name: \"Tesco\",\n  search_type: \"contains\",\n  vendor_data: \"company-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.KYB.Search(ctx, didit.KYBSearchParams{\n\tCountryCode: \"GB\",\n\tName:        didit.String(\"Tesco\"),\n\tSearchType:  didit.Some(didit.KYBSearchParamsSearchType(\"contains\")),\n\tVendorData:  didit.String(\"company-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.KybSearchParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.kyb().search(KybSearchParams.builder()\n        .countryCode(\"GB\")\n        .name(\"Tesco\")\n        .searchType(KybSearchParams.SearchType.of(\"contains\"))\n        .vendorData(\"company-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->kyb->search([\n    'country_code' => 'GB',\n    'name' => 'Tesco',\n    'search_type' => 'contains',\n    'vendor_data' => 'company-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.kyb.search(\n  country_code: \"GB\",\n  name: \"Tesco\",\n  search_type: \"contains\",\n  vendor_data: \"company-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Kyb.SearchAsync(new KybSearchParams\n{\n    CountryCode = \"GB\",\n    Name = \"Tesco\",\n    SearchType = new KybSearchParamsSearchType(\"contains\"),\n    VendorData = \"company-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "검색이 접수되었습니다. 동기 모드는 확인된 후보 목록을 반환하며, webhook 모드는 즉시 반환(주로 `search_status: \"pending\"`)하고 `kyb.registry_search.resolved` 콜백을 통해 최종 목록을 전송합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "`webhook_url`이 있는 경우: 영구 저장된 검색 요청 ID로, `kyb.registry_search.resolved` 콜백에서 `request_id`로 반환됩니다. `webhook_url`이 없는 경우: 일회성 상관관계 UUID입니다(검색이 저장되지 않음)."
                    },
                    "kyb_registry": {
                      "$ref": "#/components/schemas/KYBRegistrySearchResults"
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "전송한 `vendor_data`의 에코 값입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "description": "전송한 `metadata`의 에코 값입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "Resolved search": {
                    "summary": "동기 모드 — 최종 후보 목록",
                    "value": {
                      "request_id": "0c7e9a40-3a13-4f7e-8a44-9d2e2f1c5b6a",
                      "kyb_registry": {
                        "companies": [
                          {
                            "kyb_response_id": "69aeeb95febb0f1704042259",
                            "name": "Tesco PLC",
                            "registration_number": "00445790",
                            "status": "active",
                            "type": "Public Limited Company",
                            "risk_level": null,
                            "fetch_status": "pending"
                          },
                          {
                            "kyb_response_id": "69aeeb95febb0f170404225a",
                            "name": "E-TESCO LTD",
                            "registration_number": "15168476",
                            "status": "active",
                            "type": "Private Limited Company",
                            "risk_level": null,
                            "fetch_status": "pending"
                          }
                        ],
                        "pagination": {
                          "total": 2,
                          "page": 1,
                          "per_page": 25
                        },
                        "search_status": "resolved",
                        "search_resolved": true
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:40:00.000000+00:00"
                    }
                  },
                  "Pending search (webhook mode)": {
                    "summary": "`webhook_url` 제공됨 — 후보 목록은 kyb.registry_search.resolved 콜백을 통해 전달됩니다",
                    "value": {
                      "request_id": "5f2d8c1b-7e4a-4b9c-9f0d-3a6e8c2b1d4f",
                      "kyb_registry": {
                        "companies": [],
                        "pagination": {
                          "total": 0,
                          "page": 1,
                          "per_page": 25
                        },
                        "search_status": "pending",
                        "search_resolved": false
                      },
                      "vendor_data": "company-1234",
                      "metadata": {
                        "source": "onboarding"
                      },
                      "created_at": "2026-06-11T10:41:00.000000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 필드 수준 문제는 DRF의 표준 엔벨로프를 사용하며, 이름/등록번호 규칙은 `non_field_errors` 아래에 보고됩니다. 등기소에서 지원하지 않는 국가는 `code: kyb_registry_country_unsupported`와 함께 `400`으로 응답합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing search criteria": {
                    "summary": "`name`과 `registration_number`가 모두 제공되지 않았습니다",
                    "value": {
                      "non_field_errors": [
                        "Either 'name' or 'registration_number' is required."
                      ]
                    }
                  },
                  "Invalid country_code": {
                    "summary": "`XX`(alpha-2) 또는 `XX-YY` 행정 구역이어야 합니다.",
                    "value": {
                      "country_code": [
                        "country_code must be a 2-letter ISO code."
                      ]
                    }
                  },
                  "Invalid search_type": {
                    "summary": "`contains`만 허용됩니다",
                    "value": {
                      "search_type": [
                        "\"start_with\" is not a valid choice."
                      ]
                    }
                  },
                  "Invalid webhook_url": {
                    "summary": "`webhook_url`은 유효한 URL이어야 합니다",
                    "value": {
                      "webhook_url": [
                        "Enter a valid URL."
                      ]
                    }
                  },
                  "Country not covered": {
                    "summary": "해당 국가를 지원하는 법인 등기부가 없습니다",
                    "value": {
                      "detail": "Company registry search is not available for this country. Enter the company details manually to continue.",
                      "code": "kyb_registry_country_unsupported"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 키가 누락된 경우 `{\"detail\": ...}`과 함께 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 또한 검색 전에 해당 검색 요금을 충당할 수 없거나(`code: \"insufficient_credits\"`), 계약 검색 요금이 누락된 경우에도 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했거나 검색 한도를 소진했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유하며(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용), `X-RateLimit-*` 및 `Retry-After` 헤더가 제공됩니다. 이와 별도로 유료 등기부 검색은 애플리케이션당 시간당 600회로 제한됩니다. 이를 초과하면 `code: kyb_registry_search_limit_reached`와 함께 `429` 응답이 반환되며, 무료 소스로만 제공되는 검색은 여전히 작동합니다. 잠시 기다린 후 다시 검색하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  },
                  "Search allowance spent": {
                    "summary": "지난 1시간 동안 600회를 초과하는 유료 검색 발생",
                    "value": {
                      "detail": "The maximum number of company registry searches for this session has been reached. Enter the company details manually to continue.",
                      "code": "kyb_registry_search_limit_reached"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "KYB 등기소 제공업체를 일시적으로 사용할 수 없습니다(업스트림 등기소의 5xx 응답, 시간 초과 또는 연결 실패). 검색 비용은 청구되지 않습니다. 나중에 다시 시도하거나, Didit의 호스팅 인증 플로우에서는 사용자에게 재시도 전용 오류 대신 수동 기업 정보 입력 기능이 자동으로 제공됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Registry provider outage": {
                    "summary": "등기소 공급자가 검색에 응답하지 않았습니다.",
                    "value": {
                      "detail": "The KYB registry provider is temporarily unavailable. Please try again shortly.",
                      "code": "kyb_registry_provider_unavailable"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/kyb/select/": {
      "post": {
        "summary": "KYB 등기부 기업 선택 — Lite 등급(독립 실행형)",
        "operationId": "post_v3_kyb_select",
        "x-didit-sdk": {
          "resource": "kyb",
          "method": "select",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [],
        "description": "`POST /v3/kyb/search/`에서 반환된 후보 중 하나의 **Lite** 법인 등기부 프로필을 조회합니다. 여기에는 기업 세부 정보, 등록 주소, 식별자, 상태, 활동 및 임원 정보와 원본 등기부 payload가 포함됩니다. 주주 및 실소유자는 `POST /v3/kyb/shareholders/` 및 `POST /v3/kyb/ubo/`를 통해 별도로 구매할 수 있습니다.\n\n**검색 결과와 매칭.** 동일한 애플리케이션의 검색에서 반환된 후보의 `kyb_response_id`를 그대로 전달하십시오. 해당 핸들은 일시적이며 해당 검색에만 유효하므로, 즉시 선택하고 핸들을 저장하기보다는 다시 검색하여 새 핸들을 받으십시오.\n\n**결제.** 선택 건마다 해당 국가의 Lite 가격으로 청구됩니다(모든 검색 수수료는 별도입니다). [KYB 등기부 요금](/ko/getting-started/kyb-registry-pricing)을 참조하십시오. 등기부 호출 전 잔액을 확인하며(부족 시 `403`), 청구 내역은 생성된 기업 세션에 기록됩니다.\n\n**영속성은 필수입니다.** 결제 및 조회를 추적할 수 있도록 모든 선택 작업은 기업 세션을 생성하며(세션 ID는 `request_id`임), 콘솔에 표시됩니다. `save_api_request`는 대칭성을 위해 허용되지만 반드시 `true`(기본값)여야 합니다. `false`를 전송하면 `400`이 반환됩니다.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KYBRegistryCandidateRequest"
              },
              "example": {
                "kyb_response_id": "69aeeb95febb0f1704042259",
                "vendor_data": "company-1234"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/kyb/select/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"kyb_response_id\": \"69aeeb95febb0f1704042259\",\n    \"vendor_data\": \"company-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.kyb.select(\n    kyb_response_id=\"69aeeb95febb0f1704042259\",\n    vendor_data=\"company-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.kyb.select({\n  kyb_response_id: \"69aeeb95febb0f1704042259\",\n  vendor_data: \"company-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.KYB.Select(ctx, didit.KYBRegistryCandidateRequest{\n\tKYBResponseID: \"69aeeb95febb0f1704042259\",\n\tVendorData:    didit.String(\"company-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.KYBRegistryCandidateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.kyb().select(KYBRegistryCandidateRequest.builder()\n        .kybResponseId(\"69aeeb95febb0f1704042259\")\n        .vendorData(\"company-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->kyb->select([\n    'kyb_response_id' => '69aeeb95febb0f1704042259',\n    'vendor_data' => 'company-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.kyb.select(\n  kyb_response_id: \"69aeeb95febb0f1704042259\",\n  vendor_data: \"company-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Kyb.SelectAsync(new KYBRegistryCandidateRequest\n{\n    KybResponseId = \"69aeeb95febb0f1704042259\",\n    VendorData = \"company-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "기업 정보가 조회되고 요금이 청구되었습니다. `kyb_registry`에 전체 프로필이 포함되어 있습니다. `data_resolved`를 확인하세요. `false`인 경우 법인 등기부에서 아직 처리 중이며, 조회가 완료되면 저장된 레코드가 자동으로 완성됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "이 조회에 대해 생성된 기업 세션의 Id입니다. 응답 이후 법인 등기부 조회가 완료되면 저장된 레코드(콘솔에서 확인 가능)가 계속 업데이트됩니다."
                    },
                    "registry_tier_requested": {
                      "type": "string",
                      "enum": [
                        "basic",
                        "shareholders",
                        "ubo"
                      ],
                      "description": "이 endpoint에서 판매하는 등급: select의 경우 `basic` (Lite), `shareholders`, `ubo`입니다."
                    },
                    "registry_tier_delivered": {
                      "type": "string",
                      "enum": [
                        "basic",
                        "shareholders",
                        "ubo"
                      ],
                      "description": "실제로 제공되어 결제 청구된 등급입니다. 해당 국가의 등기부에 소유 구조 데이터가 없거나, 등기부에 이 기업의 소유 구조 기록이 없는 경우 요청한 등급보다 낮아집니다."
                    },
                    "kyb_registry": {
                      "type": "object",
                      "description": "전체 등기부 기업 프로필입니다.",
                      "properties": {
                        "uuid": {
                          "type": "string",
                          "format": "uuid",
                          "description": "이 기업 레코드에 대한 Didit의 ID입니다."
                        },
                        "node_id": {
                          "type": "string",
                          "example": "feature_kyb_registry"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "Not Finished",
                            "Approved",
                            "Declined",
                            "In Review"
                          ],
                          "description": "법인 등기부 확인에 대한 Didit의 평가입니다(예: 기업이 등기부에서 활성 상태가 아니거나 소유 구조 데이터를 도출할 수 없는 경우 `In Review`)."
                        },
                        "registry_status": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "active",
                            "dissolved",
                            "deregistered",
                            "see full details",
                            "authorised",
                            "appointed representative",
                            "unauthorised",
                            "inactive",
                            "no longer authorised",
                            "closed",
                            "struck off"
                          ],
                          "description": "등기소에서 보고된 정규화된 기업 상태입니다."
                        },
                        "data_resolved": {
                          "type": "boolean",
                          "description": "등기소에서 전체 프로필을 반환하면 `true`입니다. 폴링 후에도 등기소에서 여전히 처리 중인 경우 `false`이며, 저장된 레코드는 등기소 처리가 완료되면 자동으로 완료됩니다."
                        },
                        "company_name": {
                          "type": "string",
                          "example": "Tesco PLC"
                        },
                        "registration_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "00445790"
                        },
                        "country_code": {
                          "type": "string",
                          "description": "ISO 3166-1 alpha-2.",
                          "example": "GB"
                        },
                        "region": {
                          "type": "string",
                          "nullable": true,
                          "description": "법인 등기부가 지역 단위인 경우 행정 구역 코드(예: `US-CA`의 경우 `CA`), 그렇지 않은 경우 비어 있습니다."
                        },
                        "company_type": {
                          "type": "string",
                          "nullable": true,
                          "example": "Public Limited Company"
                        },
                        "incorporation_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "1947-11-27"
                        },
                        "registered_address": {
                          "type": "string",
                          "nullable": true,
                          "example": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA"
                        },
                        "tax_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "GB412 8925 93"
                        },
                        "risk_level": {
                          "type": "string",
                          "nullable": true,
                          "description": "제공되는 경우, 법인 등기부에 보고된 위험 수준입니다."
                        },
                        "verification_status": {
                          "type": "string",
                          "enum": [
                            "verified",
                            "failed",
                            "unknown"
                          ],
                          "nullable": true,
                          "description": "관할 구역 간 검증 상태: 등기부 상태가 존속 상태(`active`)를 확정하는 경우 `verified`, 회사가 더 이상 존속하지 않음(예: `dissolved`)을 나타내는 경우 `failed`, 그 외의 경우 `unknown`입니다. 등기부에서 가져오지 않은 회사 및 선택이 아직 `pending` 상태인 동안에는 `null`입니다."
                        },
                        "is_from_registry": {
                          "type": "boolean",
                          "description": "이 endpoint의 경우 항상 `true`입니다. 프로필을 공식 등기부에서 조회했습니다."
                        },
                        "fetch_status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "resolved"
                          ],
                          "description": "법인 등기부 조회 라이프사이클입니다. `data_resolved`에 반영됩니다."
                        },
                        "alternative_names": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우, 텍스트 형태의 대체명, 상호명, 이전 명칭 또는 원어 기업명입니다."
                        },
                        "nature_of_business": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우의 업종 설명 또는 분류 코드입니다."
                        },
                        "registered_capital": {
                          "type": "string",
                          "nullable": true
                        },
                        "registered_capital_amount": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우, 문자열 형태의 십진수 금액입니다."
                        },
                        "registered_capital_currency": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우의 ISO 4217 코드입니다."
                        },
                        "website": {
                          "type": "string",
                          "nullable": true,
                          "example": "https://www.tesco.com/"
                        },
                        "email": {
                          "type": "string",
                          "nullable": true,
                          "example": "customer.service@tesco.co.uk"
                        },
                        "phone": {
                          "type": "string",
                          "nullable": true,
                          "example": "03301231688"
                        },
                        "legal_entity_identifier": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우의 LEI입니다."
                        },
                        "location_of_registration": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우, 기업이 등록된 법인 등기부/관할 구역입니다."
                        },
                        "vat_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "호스팅 법인 등기부 단계에서 수집되었거나 이후 편집된 EU VAT 번호입니다. 선택 시점에는 일반적으로 아직 설정되지 않습니다. VAT 및 납세자 번호 검증은 최종 사용자가 호스팅 흐름에서 법인 등기부 단계를 제출할 때 실행됩니다."
                        },
                        "vat_validation_status": {
                          "type": "string",
                          "enum": [
                            "valid",
                            "invalid",
                            "format_valid",
                            "invalid_format",
                            "could_not_validate",
                            "not_applicable"
                          ],
                          "description": "법인 등기부 제출 시 VAT 번호 또는 없는 경우 `tax_number`를 검증한 결과입니다. `valid` / `invalid`: 해당 국가의 공식 등기소(EU VIES, 노르웨이, 스위스, 브라질, 콜롬비아, 코스타리카, 에콰도르, 파라과이, 폴란드의 경우 국내 VAT 등록부 포함)에서 결정됩니다. `format_valid` / `invalid_format`: 등기소 조회가 불가능한 경우 해당 국가의 서식 및 체크 디지트 규칙에 따라 결정됩니다. `could_not_validate`: 등기소를 사용할 수 없습니다. `not_applicable`: 번호가 없거나, 등기소나 규칙이 없는 국가이거나, 샌드박스 세션인 경우입니다."
                        },
                        "vat_validated_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "출처가 인식하는 확인된 번호입니다(예: 프랑스 SIREN 또는 네덜란드 RSIN에서 파생된 VAT 번호). 확인이 실행되지 않은 경우 `null`입니다."
                        },
                        "vat_validation_source": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "eu_vies",
                            "pl_vat_white_list",
                            "no_brreg",
                            "ch_uid_register",
                            "br_receita_federal",
                            "co_rues",
                            "cr_hacienda",
                            "ec_sri",
                            "py_dnit",
                            "format_rules",
                            null
                          ],
                          "description": "`vat_validation_status`를 결정한 소스(공식 등기소 또는 `format_rules`)입니다. 검사가 실행되지 않은 경우 `null`입니다."
                        },
                        "vat_validated_name": {
                          "type": "string",
                          "nullable": true,
                          "description": "해당 번호를 검증한 소스에 등록된 이름(소스를 통해 공개된 경우). 상태가 `valid`인 경우에만 설정됩니다."
                        },
                        "vat_validated_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "번호를 검증한 출처에 등록된 주소(출처에서 제공하는 경우)입니다. 상태가 `valid`일 때만 설정됩니다."
                        },
                        "vat_checked_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "검사의 타임스탬프입니다. 검사가 실행되지 않은 경우 `null`입니다."
                        },
                        "financial_summary": {
                          "type": "object",
                          "nullable": true,
                          "description": "제공되는 경우, 법인 등기부에 보고된 주식/자본 세부 정보(통화, 총 주식 수, 주식 클래스)입니다."
                        },
                        "officers": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "uuid": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "name": {
                                "type": "string",
                                "example": "MELISSA BETHELL"
                              },
                              "designation": {
                                "type": "string",
                                "nullable": true,
                                "description": "원시 등기 직함(예: `Director`, `Secretary`)입니다."
                              },
                              "role": {
                                "type": "string",
                                "description": "직함에서 파생된 정규화된 역할입니다. 17개 값으로 구성된 전체 모델 세트이며, 이 endpoint의 등기부 파싱은 일반적으로 director, non_executive_director, secretary, chairman 또는 company_officer를 내보냅니다.",
                                "enum": [
                                  "director",
                                  "non_executive_director",
                                  "secretary",
                                  "chairman",
                                  "ubo",
                                  "shareholder",
                                  "representative",
                                  "founder",
                                  "legal_advisor",
                                  "authorized_signatory",
                                  "trustee",
                                  "beneficiary",
                                  "company_officer",
                                  "settlor",
                                  "protector",
                                  "investor",
                                  "other"
                                ]
                              },
                              "nationality": {
                                "type": "string",
                                "nullable": true
                              },
                              "is_active": {
                                "type": "boolean",
                                "description": "등기소에서 해당 임명이 사임한 것으로 표시된 경우 `false`."
                              },
                              "kyc_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "Approved",
                                  "Declined",
                                  "Pending"
                                ],
                                "description": "이 임원에 대해 연결된 KYC 세션이 시작된 경우 해당 세션의 상태입니다. 그렇지 않은 경우 `null`입니다."
                              },
                              "kyc_session_url": {
                                "type": "string",
                                "nullable": true,
                                "description": "연결된 KYC 세션이 존재하는 경우 해당 세션의 인증 URL입니다."
                              },
                              "first_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "등기소에서 명시적으로 보고한 경우의 이름입니다. 성명에서 유추되지 않습니다."
                              },
                              "last_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "등기소에서 명시적으로 보고한 경우의 성입니다."
                              },
                              "address": {
                                "type": "string",
                                "nullable": true,
                                "description": "등기부에서 보고된 임원 주소입니다."
                              },
                              "appointment_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "임원이 선임된 날짜입니다.",
                                "format": "date"
                              },
                              "termination_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "보고된 경우 선임 종료일입니다.",
                                "format": "date"
                              },
                              "date_of_birth": {
                                "type": "string",
                                "nullable": true,
                                "description": "법인 등기부에 보고된 전체 생년월일입니다. 출생 연도 또는 월만 알려진 경우 null입니다.",
                                "format": "date"
                              },
                              "date_of_birth_year": {
                                "type": "integer",
                                "nullable": true,
                                "minimum": 1,
                                "maximum": 9999,
                                "description": "전체 날짜를 알 수 없는 경우를 포함하여, 법인 등기부에 보고된 출생 연도입니다."
                              },
                              "date_of_birth_month": {
                                "type": "integer",
                                "nullable": true,
                                "minimum": 1,
                                "maximum": 12,
                                "description": "법인 등기부에 보고된 출생 월입니다. 연도만 알려진 경우 null입니다."
                              }
                            }
                          },
                          "description": "등기부에서 추출된 이사, 비서 및 기타 임원입니다."
                        },
                        "beneficial_owners": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "uuid": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "name": {
                                "type": "string"
                              },
                              "first_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "last_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "entity_type": {
                                "type": "string",
                                "enum": [
                                  "person",
                                  "company"
                                ],
                                "description": "소유자가 자연인인지 법인인지 여부입니다."
                              },
                              "roles": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "정규화된 역할입니다(예: `ubo`, `shareholder`)."
                              },
                              "ownership_min_shares": {
                                "type": "string",
                                "nullable": true,
                                "description": "등기소에서 보고한 소유 지분 구간의 하한값(예: `25%`)."
                              },
                              "ownership_max_shares": {
                                "type": "string",
                                "nullable": true,
                                "description": "법인 등기부에서 보고한 소유 구조 구간의 상한선입니다."
                              },
                              "is_active": {
                                "type": "boolean"
                              },
                              "kyc_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "Approved",
                                  "Declined",
                                  "Pending"
                                ]
                              },
                              "kyc_session_url": {
                                "type": "string",
                                "nullable": true
                              },
                              "effective_ownership_percent": {
                                "type": "number",
                                "nullable": true,
                                "description": "파싱된 소유 구조 백분율입니다(최댓값을 사용하고, 최댓값이 없으면 최솟값을 사용합니다)."
                              },
                              "company_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "registration_number": {
                                "type": "string",
                                "nullable": true
                              },
                              "country_of_birth": {
                                "type": "string",
                                "nullable": true
                              },
                              "email": {
                                "type": "string",
                                "nullable": true
                              },
                              "nationality": {
                                "type": "string",
                                "nullable": true
                              },
                              "designation": {
                                "type": "string",
                                "nullable": true
                              },
                              "voting_min_shares": {
                                "type": "string",
                                "nullable": true
                              },
                              "voting_max_shares": {
                                "type": "string",
                                "nullable": true
                              },
                              "date_of_birth": {
                                "type": "string",
                                "nullable": true,
                                "description": "보고된 전체 생년월일입니다.",
                                "format": "date"
                              },
                              "appointment_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "신고된 선임일입니다.",
                                "format": "date"
                              },
                              "shareholding": {
                                "$ref": "#/components/schemas/KYBRegistryShareholding"
                              }
                            }
                          },
                          "description": "등기부에서 추출한 실소유자 / 중대한 지배력을 가진 자입니다. 등기부에서 소유 구조를 공개하지 않는 경우 비어 있을 수 있습니다."
                        },
                        "addresses": {
                          "type": "array",
                          "nullable": true,
                          "description": "등기부에 기재된 모든 주소의 표준 형식입니다. 기재된 내용이 없으면 null입니다.",
                          "items": {
                            "$ref": "#/components/schemas/KYBRegistryAddress"
                          }
                        },
                        "industries": {
                          "type": "array",
                          "nullable": true,
                          "description": "등기부에서 기업을 분류하는 표준 형태의 활동입니다. 명시된 활동이 없는 경우 null입니다.",
                          "items": {
                            "$ref": "#/components/schemas/KYBRegistryIndustry"
                          }
                        },
                        "accounts": {
                          "type": "object",
                          "nullable": true,
                          "additionalProperties": true,
                          "description": "제공되는 경우 법인 등기부 제출 날짜입니다. 연차 보고서 및 주주총회에는 last_annual_return_date 및 last_agm_date를 사용하며, 재무제표와는 구별됩니다."
                        },
                        "registry_data": {
                          "$ref": "#/components/schemas/KYBRegistryData"
                        },
                        "user_provided_data": {
                          "type": "object",
                          "nullable": true,
                          "description": "이 endpoint에서는 항상 `null`입니다(최종 사용자가 등기부 데이터를 편집할 때 호스팅 KYB 워크플로에서 사용됨)."
                        },
                        "confirmed_by_user_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "이 endpoint에서는 항상 `null`입니다."
                        },
                        "last_console_edit_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "콘솔 검토자가 나중에 기록을 수정할 때 설정됩니다."
                        },
                        "is_editable": {
                          "type": "boolean",
                          "description": "법인 등기부에서 가져온 데이터를 호스팅된 플로우/콘솔에서 계속 수정할 수 있는지 여부입니다."
                        },
                        "registry_tier_delivered": {
                          "type": "string",
                          "enum": [
                            "basic",
                            "shareholders",
                            "ubo"
                          ],
                          "description": "최상위 `registry_tier_delivered`와 동일합니다."
                        },
                        "registry_ownership_status": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "not_requested",
                            "delivered",
                            "not_held",
                            "unavailable"
                          ],
                          "description": "소유 구조 데이터가 반환된 경우 `delivered`, 소유 구조 등기소가 응답했으나 이 기업이 등재되어 있지 않은 경우 `not_held`(`registry_data.ownership_error` 참조), 소유 구조 등급을 요청했으나 등기소에 해당 기업의 데이터가 없거나 조회를 요청할 수 없는 경우 `unavailable`(`registry_data.ownership_error` 참조), Lite 등급인 경우 `not_requested`."
                        },
                        "ownership": {
                          "$ref": "#/components/schemas/KYBRegistryOwnership"
                        },
                        "registry_tier": {
                          "type": "string",
                          "nullable": true,
                          "description": "워크플로가 주문한 등기소 등급(`basic`, `shareholders` 또는 `ubo`)입니다. `ownership.tier_requested`에도 포함됩니다."
                        },
                        "registry_monitoring": {
                          "type": "object",
                          "nullable": true,
                          "description": "기업의 최신 등기부 모니터링 정보 또는 존재하지 않는 경우 `null`입니다.",
                          "properties": {
                            "uuid": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "status": {
                              "type": "string"
                            },
                            "unavailable_reason": {
                              "type": "string",
                              "nullable": true
                            },
                            "enrolled_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "cancelled_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "last_bill_date": {
                              "type": "string",
                              "format": "date",
                              "nullable": true
                            },
                            "next_bill_date": {
                              "type": "string",
                              "format": "date",
                              "nullable": true
                            },
                            "last_event_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "events_count": {
                              "type": "integer"
                            },
                            "watched_fields": {
                              "description": "모니터가 감시하는 기업 필드입니다."
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "전송한 `vendor_data`의 에코 값입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "description": "전송한 `metadata`의 에코 값입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "Resolved company": {
                    "summary": "전체 등기부 프로필(간결성을 위해 임원 목록은 축약됨)",
                    "value": {
                      "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e",
                      "kyb_registry": {
                        "uuid": "f1e2d3c4-b5a6-4789-9c0d-1e2f3a4b5c6d",
                        "node_id": "feature_kyb_registry",
                        "status": "In Review",
                        "registry_status": "active",
                        "data_resolved": true,
                        "company_name": "Tesco PLC",
                        "registration_number": "00445790",
                        "country_code": "GB",
                        "region": "",
                        "company_type": "Public Limited Company",
                        "incorporation_date": "1947-11-27",
                        "registered_address": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA",
                        "tax_number": "GB412 8925 93",
                        "risk_level": "low risk",
                        "verification_status": "verified",
                        "is_from_registry": true,
                        "fetch_status": "resolved",
                        "alternative_names": "TESCO STORES (HOLDINGS) PUBLIC LIMITED COMPANY",
                        "nature_of_business": null,
                        "registered_capital": null,
                        "registered_capital_amount": null,
                        "registered_capital_currency": null,
                        "website": "https://www.tesco.com/",
                        "email": "customer.service@tesco.co.uk",
                        "phone": "03301231688",
                        "legal_entity_identifier": null,
                        "location_of_registration": null,
                        "financial_summary": {
                          "currency": "Pound (£)",
                          "total_number_of_shares": "8174378721",
                          "meta_detail": {
                            "Class_Of_Share": "Ordinary"
                          }
                        },
                        "officers": [
                          {
                            "uuid": "a1b2c3d4-e5f6-4789-9a0b-1c2d3e4f5a6b",
                            "name": "CHRISTOPHER JON TAYLOR",
                            "designation": "Secretary",
                            "role": "secretary",
                            "nationality": null,
                            "is_active": true,
                            "kyc_status": null,
                            "kyc_session_url": null
                          },
                          {
                            "uuid": "b2c3d4e5-f6a7-4890-8b1c-2d3e4f5a6b7c",
                            "name": "MELISSA BETHELL",
                            "designation": "Director",
                            "role": "director",
                            "nationality": "British",
                            "is_active": true,
                            "kyc_status": null,
                            "kyc_session_url": null
                          }
                        ],
                        "beneficial_owners": [],
                        "addresses": [
                          {
                            "address": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA",
                            "type": "legal_entity_registry_address",
                            "description": "registered office address"
                          }
                        ],
                        "industries": null,
                        "accounts": {
                          "last_account": "26 February 2025",
                          "next_account": "26 February 2026",
                          "due_by_date": "26 August 2026"
                        },
                        "registry_data": {},
                        "user_provided_data": null,
                        "confirmed_by_user_at": null,
                        "last_console_edit_at": null,
                        "is_editable": true
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:45:00.000000+00:00"
                    }
                  },
                  "Pending (registry still resolving)": {
                    "summary": "폴링 후에도 선택 항목이 대기 상태로 유지됨 — 희소 필드, 서버 측에서 자동 완성됨",
                    "value": {
                      "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e",
                      "kyb_registry": {
                        "uuid": "7c0a4f7e-2b1d-4f6a-9c3e-8d5b2a1f0e9d",
                        "node_id": "feature_kyb_registry",
                        "status": "Not Finished",
                        "registry_status": null,
                        "data_resolved": false,
                        "company_name": "Tesco PLC",
                        "registration_number": "00445790",
                        "country_code": "GB",
                        "region": null,
                        "company_type": null,
                        "incorporation_date": null,
                        "registered_address": null,
                        "tax_number": null,
                        "risk_level": null,
                        "verification_status": null,
                        "is_from_registry": true,
                        "fetch_status": "pending",
                        "alternative_names": null,
                        "nature_of_business": null,
                        "registered_capital": null,
                        "registered_capital_amount": null,
                        "registered_capital_currency": null,
                        "website": null,
                        "email": null,
                        "phone": null,
                        "legal_entity_identifier": null,
                        "location_of_registration": null,
                        "financial_summary": {},
                        "officers": [],
                        "beneficial_owners": [],
                        "addresses": null,
                        "industries": null,
                        "accounts": null,
                        "registry_data": {},
                        "user_provided_data": null,
                        "confirmed_by_user_at": null,
                        "last_console_edit_at": null,
                        "is_editable": true
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:45:00.000000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 필드 수준 문제는 DRF의 표준 엔벨로프를 사용합니다. 등기소에서 지원하지 않는 국가는 `code: kyb_registry_country_unsupported`와 함께 `400`으로 응답합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing kyb_response_id": {
                    "summary": "`kyb_response_id`는 필수 항목입니다.",
                    "value": {
                      "kyb_response_id": [
                        "This field is required."
                      ]
                    }
                  },
                  "save_api_request=false rejected": {
                    "summary": "선택 항목은 항상 지속됩니다",
                    "value": {
                      "save_api_request": [
                        "KYB registry select must be saved so billing and retrieval can be tracked."
                      ]
                    }
                  },
                  "Country not covered": {
                    "summary": "해당 국가를 지원하는 법인 등기부가 없습니다",
                    "value": {
                      "detail": "Company registry search is not available for this country. Enter the company details manually to continue.",
                      "code": "kyb_registry_country_unsupported"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었거나 호출한 조직의 잔액이 호출 비용을 충당할 수 없을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 키가 누락된 경우 `{\"detail\": ...}`과 함께 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 크레딧이 부족한 경우 어떠한 스크리닝이나 제공업체 호출도 진행되기 전에 `{\"error\": ...}`과 함께 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 호출 비용을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/passive-liveness/": {
      "post": {
        "summary": "패시브 라이브니스",
        "description": "단일 얼굴 이미지에서 인쇄된 사진, 화면 재생, 가면, 딥페이크와 같은 프레젠테이션 공격을 감지합니다. 비디오, 움직임 또는 사용자 상호작용이 필요하지 않습니다.\n\n**작동 방식.** 이미지는 생체 인식 모델에 의해 분석되며, 감지된 가장 큰 얼굴을 평가하여 라이브니스 `score`(0~100)를 산출합니다. `error` 심각도 경고가 발생하면 `status`는 `Declined`가 됩니다:\n- `NO_FACE_DETECTED` — 라이브니스 모델이 얼굴을 찾지 못함,\n- `LOW_LIVENESS_SCORE` — 점수가 `face_liveness_score_decline_threshold`(기본값 `30`) 이하임,\n- `LIVENESS_FACE_ATTACK` — 모델이 프레젠테이션 공격을 감지함,\n- `FACE_IN_BLOCKLIST` / `POSSIBLE_FACE_IN_BLOCKLIST` — 얼굴이 얼굴 차단 목록의 항목과 일치함.\n\n`MULTIPLE_FACES_DETECTED`는 `warning` 심각도 신호이며(거부되지 않음), `DUPLICATED_FACE` / `POSSIBLE_DUPLICATED_FACE`는 동일한 얼굴이 이미 다른 승인된 세션에 나타났음을 나타내는 `information` 심각도 신호입니다(절대 거부되지 않음). `face_quality` 및 `face_luminance`(0~100, nullable)는 캡처 품질을 나타냅니다.\n\n**차단 목록 및 중복 스크리닝.** 감지된 얼굴을 애플리케이션의 얼굴 검색 색인과 대조하여 `save_api_request` 설정 여부와 관계없이 **모든** 호출에서 실행됩니다. 동일한 `vendor_data`를 가진 이전 얼굴은 전체 색인 검색에서 제외되므로, 동일한 사용자에 대해 라이브니스를 다시 실행해도 `DUPLICATED_FACE`가 발생하지 않으며 호출자의 자체 `vendor_data`가 포함된 세션에서 유래한 차단 목록 얼굴 또한 플래그가 지정되지 않습니다(동일한 `vendor_data` 얼굴에 대해서는 `FACE_IN_BLOCKLIST` 스크리닝이 건너뛰어짐).\n\n**결제.** 각 `200` 응답은 패시브 라이브니스 API 크레딧 1개를 소비합니다(요금제 크레딧 또는 충전 잔액에서 차감). 잔액이 부족하면 이미지 처리 전에 `403`이 반환됩니다.\n\n**세션 유지 및 얼굴 등록(`save_api_request`, 기본값 `true`).** `true`인 경우, 호출은 API 유형 세션(Business Console, 반환된 `request_id`를 통한 `GET /v3/session/{sessionId}/decision/`, `status.updated` webhook)으로 유지되고 기준 이미지와 얼굴 크롭이 저장되며, 감지된 얼굴이 **얼굴 검색 색인에 등록**되어 이후의 얼굴 검색 호출 및 중복 확인에서 일치 여부를 대조할 수 있습니다. `false`인 경우, 일회성 호출로 처리되어 아무것도 저장되지 않고 얼굴도 등록되지 않습니다(차단 목록/중복 스크리닝은 계속 실행됨).\n\n**샌드박스.** 샌드박스 API 키는 모든 처리 및 결제를 건너뜁니다. 요청 유효성 검사 후(형식이 잘못된 입력은 여전히 `400` 반환), endpoint는 정적 `Approved` 모의 payload를 반환하고, 세션은 유지되지 않으며, 크레딧도 소비되지 않습니다.\n\n**인증.** 애플리케이션의 API 키를 `x-api-key` 헤더로 전송하십시오. 인증 정보가 누락되거나 잘못된 경우 `403`(`{\"detail\": \"You do not have permission to perform this action.\"}`)이 반환되며, 이 API는 절대로 `401`을 반환하지 않습니다.\n\n**속도 제한.** 모든 POST/PATCH/DELETE endpoint에 걸쳐 API 키당 분당 300회의 쓰기 예산이 공유되며, 이를 초과하면 `429`가 반환됩니다.",
        "operationId": "post_v3passive-liveness",
        "x-didit-sdk": {
          "resource": "passive_liveness",
          "method": "check",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "user_image"
                ],
                "properties": {
                  "user_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "정면 얼굴 이미지입니다(예: 셀피). 허용되는 확장자: `tiff`, `jpg`, `jpeg`, `png`, `webp`. 최대 업로드 크기: **5 MB**(더 큰 파일은 `400` 오류로 거부됨). 이미지는 처리 전에 자동으로 ~0.5 MB로 압축되므로 매우 높은 해상도라고 해서 정확도가 향상되지는 않습니다. 이미지에는 단일 대상만 포함되어야 합니다. 여러 얼굴이 있는 경우 가장 큰 얼굴이 평가되며 `MULTIPLE_FACES_DETECTED` 경고가 추가됩니다."
                  },
                  "face_liveness_score_decline_threshold": {
                    "type": "number",
                    "format": "float",
                    "default": 30,
                    "minimum": 0,
                    "maximum": 100,
                    "description": "라이브니스 점수 임계값(0–100). 계산된 점수가 이 값 **이하**인 경우 `LOW_LIVENESS_SCORE` 경고를 생성하고 `status`를 `Declined`로 설정합니다. 기본값은 `30`입니다. 더 엄격한 안티 스푸핑 태세를 위해 값을 올리십시오. 0–100 범위를 벗어난 값은 `400`을 반환합니다.",
                    "example": 30
                  },
                  "rotate_image": {
                    "type": "boolean",
                    "default": false,
                    "description": "`true`인 경우 서비스가 입력을 90도씩 회전해 보고 최적의 얼굴 감지 결과를 제공하는 방향을 사용합니다. EXIF 방향 정보가 누락되었을 때 유용합니다. 지연 시간이 증가합니다.",
                    "example": false
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "`true`(기본값)인 경우 호출을 API 유형의 세션으로 저장하고, 얼굴 이미지를 저장하며, `status.updated` webhook을 발행하고, 감지된 얼굴을 얼굴 검색 인덱스에 등록합니다. `false`인 경우 호출은 단발성으로 처리되어 아무것도 저장되지 않고 얼굴도 등록되지 않습니다. 차단 목록 및 중복 스크리닝은 어느 쪽이든 실행됩니다.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "저장된 세션에 저장되고 다시 반환되는 선택적 불투명 식별자(사용자 ID, 이메일, UUID 등)입니다. 또한 동일한 `vendor_data`를 가진 이전 세션을 중복 얼굴 확인에서 제외하는 데 사용되므로, 동일한 사용자를 재인증할 때 `DUPLICATED_FACE`가 발생하지 않습니다.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "세션과 함께 저장되고(`save_api_request=true`인 경우) 그대로 반환되는 선택적 JSON 객체입니다. multipart 요청에서는 JSON 인코딩된 문자열 필드로 전송하십시오. 객체로 파싱됩니다.",
                    "example": {
                      "flow": "withdrawal"
                    }
                  }
                }
              },
              "example": {
                "user_image": "(binary JPEG/PNG selfie)",
                "face_liveness_score_decline_threshold": 30,
                "rotate_image": false,
                "save_api_request": true,
                "vendor_data": "user-123",
                "metadata": {
                  "flow": "withdrawal"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "패시브 라이브니스가 완료되었습니다. `liveness.score`는 이미지가 실제 사람인지에 대한 모델의 0–100 신뢰도 점수입니다. `error` 심각도 경고가 발생하지 않는 한 `status`는 `Approved`입니다. 스푸핑되었거나 차단 목록에 등록된 얼굴도 `200`을 반환하므로, HTTP 코드뿐만 아니라 `liveness.status`와 `liveness.warnings`를 확인해야 합니다. `save_api_request=true`인 경우, `request_id`는 저장된 세션 ID입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Approved": {
                    "summary": "실제 얼굴 — 경고 없음",
                    "value": {
                      "request_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
                      "liveness": {
                        "status": "Approved",
                        "method": "PASSIVE",
                        "score": 95.0,
                        "user_image": {
                          "entities": [
                            {
                              "bbox": [
                                661,
                                728,
                                1688,
                                2188
                              ],
                              "confidence": 0.732973,
                              "age": 26.91,
                              "gender": "male",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "warnings": [],
                        "face_quality": 84.21,
                        "face_luminance": 50.33
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T01:04:42.763237+00:00"
                    }
                  },
                  "Declined - presentation attack": {
                    "summary": "모델이 스푸핑(인쇄물, 재생, 가면 등)을 감지했습니다.",
                    "value": {
                      "request_id": "f1c8c9b2-d3e4-4f5a-9b8c-7d6e5f4a3b2c",
                      "liveness": {
                        "status": "Declined",
                        "method": "PASSIVE",
                        "score": 12.5,
                        "user_image": {
                          "entities": [
                            {
                              "bbox": [
                                100,
                                120,
                                420,
                                540
                              ],
                              "confidence": 0.81,
                              "age": 30.1,
                              "gender": "female",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "warnings": [
                          {
                            "risk": "LOW_LIVENESS_SCORE",
                            "feature": "LIVENESS",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Low liveness score",
                            "long_description": "The liveness check resulted in a low score, indicating potential use of non-live facial representations or poor-quality biometric data."
                          },
                          {
                            "risk": "LIVENESS_FACE_ATTACK",
                            "feature": "LIVENESS",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Liveness Face Attack",
                            "long_description": "The system detected a potential attempt to bypass the liveness check."
                          }
                        ],
                        "face_quality": 72.4,
                        "face_luminance": 48.2
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T01:04:42.763237+00:00"
                    }
                  },
                  "Declined - face on blocklist": {
                    "summary": "실제 얼굴이지만 차단 목록 항목과 일치함",
                    "value": {
                      "request_id": "0b54a1de-22aa-4e0f-9c84-5a2b1f3c4d5e",
                      "liveness": {
                        "status": "Declined",
                        "method": "PASSIVE",
                        "score": 93.75,
                        "user_image": {
                          "entities": [
                            {
                              "bbox": [
                                40,
                                40,
                                100,
                                100
                              ],
                              "confidence": 0.722082,
                              "age": 27.0,
                              "gender": "male",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "warnings": [
                          {
                            "risk": "FACE_IN_BLOCKLIST",
                            "feature": "LIVENESS",
                            "additional_data": {
                              "blocklisted_session_id": "882c42d5-8a4d-4d20-8080-a22f57822c86",
                              "blocklisted_session_number": 3242,
                              "api_service": null
                            },
                            "log_type": "error",
                            "short_description": "Face in blocklist",
                            "long_description": "The system identified a face in the blocklist, which means the face is not allowed to be verified."
                          }
                        ],
                        "face_quality": null,
                        "face_luminance": null
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T01:04:42.763237+00:00"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "`save_api_request=true`일 때 유지된 세션 ID(`GET /v3/session/{sessionId}/decision/`와 함께 사용 가능), 그렇지 않으면 임시 상관관계 UUID입니다."
                    },
                    "liveness": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined"
                          ],
                          "description": "최소 하나 이상의 `error` 심각도 경고(얼굴 없음, 낮은 점수, 프레젠테이션 공격 또는 차단 목록 일치)가 발생한 경우 `Declined`, 그렇지 않은 경우 `Approved`. `warning`/`information` 항목(다중 얼굴, 중복)은 단독으로 거부되지 않습니다."
                        },
                        "method": {
                          "type": "string",
                          "enum": [
                            "PASSIVE"
                          ],
                          "description": "이 endpoint의 경우 항상 `PASSIVE`입니다."
                        },
                        "score": {
                          "type": "number",
                          "format": "float",
                          "nullable": true,
                          "minimum": 0,
                          "maximum": 100,
                          "description": "이미지가 스푸핑이 아닌 실제 인물을 묘사하고 있는지에 대한 라이브니스 신뢰도(0–100, 소수점 둘째 자리). 모델이 신뢰도를 반환하지 않은 경우 `null`입니다.",
                          "example": 95.0
                        },
                        "user_image": {
                          "type": "object",
                          "description": "제출된 이미지에 대한 얼굴 감지 결과입니다.",
                          "properties": {
                            "entities": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "bbox": {
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    },
                                    "minItems": 4,
                                    "maxItems": 4,
                                    "description": "처리된 이미지에서 `[x_min, y_min, x_max, y_max]` 픽셀 좌표로 표시된 감지된 얼굴의 경계 상자입니다.",
                                    "example": [
                                      661,
                                      728,
                                      1688,
                                      2188
                                    ]
                                  },
                                  "confidence": {
                                    "type": "number",
                                    "format": "float",
                                    "minimum": 0,
                                    "maximum": 1,
                                    "description": "얼굴 감지 신뢰도(0–1).",
                                    "example": 0.732973
                                  },
                                  "age": {
                                    "type": "number",
                                    "format": "float",
                                    "description": "감지된 얼굴의 모델 추정 연령(세 단위)입니다. 정보 제공용일 뿐이며 라이브니스 결정에는 영향을 미치지 않습니다.",
                                    "example": 26.91
                                  },
                                  "gender": {
                                    "type": "string",
                                    "description": "감지된 얼굴의 모델 예측 성별(`male` 또는 `female`)입니다. 정보 제공용입니다.",
                                    "example": "male"
                                  },
                                  "race": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "예약된 필드 — 이 endpoint의 응답에서는 항상 `null`입니다.",
                                    "example": null
                                  }
                                }
                              },
                              "description": "감지된 얼굴당 항목 1개입니다. 가장 큰 얼굴이 평가 대상이 됩니다."
                            },
                            "best_angle": {
                              "type": "integer",
                              "nullable": true,
                              "description": "가장 우수한 얼굴 감지를 생성한 회전 각도(도). `rotate_image=true`로 방향을 수정한 경우에만 0이 아닙니다.",
                              "example": 0
                            }
                          }
                        },
                        "warnings": {
                          "type": "array",
                          "description": "위험 신호. `error` 심각도(거부): `NO_FACE_DETECTED`, `LOW_LIVENESS_SCORE`(임계값 이하 점수), `LIVENESS_FACE_ATTACK`, `FACE_IN_BLOCKLIST`, `POSSIBLE_FACE_IN_BLOCKLIST`. `warning` 심각도(검토, 거부되지 않음): `MULTIPLE_FACES_DETECTED`. `information` 심각도(거부되지 않음): `DUPLICATED_FACE`, `POSSIBLE_DUPLICATED_FACE` — 동일한 얼굴이 이미 다른 승인된 세션에 나타났습니다.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "enum": [
                                  "NO_FACE_DETECTED",
                                  "LOW_LIVENESS_SCORE",
                                  "LIVENESS_FACE_ATTACK",
                                  "MULTIPLE_FACES_DETECTED",
                                  "FACE_IN_BLOCKLIST",
                                  "POSSIBLE_FACE_IN_BLOCKLIST",
                                  "DUPLICATED_FACE",
                                  "POSSIBLE_DUPLICATED_FACE"
                                ],
                                "description": "기계 판독 가능한 위험 코드입니다."
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "LIVENESS"
                                ],
                                "description": "경고를 발생시킨 기능입니다. 이 endpoint에서는 항상 `LIVENESS`입니다."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "대부분의 경고의 경우 `null`입니다. 차단 목록 일치 항목에는 `{blocklisted_session_id, blocklisted_session_number, api_service}`가 포함되며, 중복 일치 항목에는 일치하는 세션을 가리키는 `{duplicated_session_id, duplicated_session_number, api_service}`가 포함됩니다."
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error",
                                  "warning",
                                  "information"
                                ],
                                "description": "심각도입니다. `error` 경고는 `status`를 `Declined`로 변경합니다. `warning` 및 `information` 항목은 참고용이며 단독으로 거부되지 않습니다."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "사람이 읽을 수 있는 한 줄의 위험 요약입니다."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "위험에 대한 사람이 읽기 쉬운 설명입니다."
                              }
                            }
                          }
                        },
                        "face_quality": {
                          "type": "number",
                          "format": "float",
                          "nullable": true,
                          "minimum": 0,
                          "maximum": 100,
                          "description": "감지된 얼굴의 촬영 품질 점수(0–100으로 정규화됨). 모델이 신뢰할 수 있는 값을 생성할 수 없는 경우 `null`입니다.",
                          "example": 84.21
                        },
                        "face_luminance": {
                          "type": "number",
                          "format": "float",
                          "nullable": true,
                          "minimum": 0,
                          "maximum": 100,
                          "description": "감지된 얼굴의 밝기로, 0–100으로 정규화됩니다. 사용할 수 없는 경우 `null`입니다.",
                          "example": 50.33
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "전송한 `vendor_data`의 에코 값 또는 `null`입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "전송한 `metadata` 객체의 에코 값 또는 `null`입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "응답이 생성된 시점의 ISO 8601 타임스탬프(UTC)(예: `2026-06-12T01:04:42.763237+00:00`)입니다."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. `user_image`가 누락되었거나, 5 MB를 초과하거나, 지원되지 않는 확장자이거나, 서버 측 이미지 디코딩에 실패했거나, 옵션이 범위를 벗어난 경우 반환됩니다. 필드 오류는 DRF의 `{field: [messages]}` 봉투를 사용하며, 이미지 디코딩 실패는 `{\"error\": ...}`를 사용합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing image": {
                    "summary": "폼 데이터에 `user_image`가 포함되지 않음",
                    "value": {
                      "user_image": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Invalid image format": {
                    "summary": "허용된 확장자이지만 디코딩할 수 없는 이미지 콘텐츠입니다.",
                    "value": {
                      "error": "Invalid user image format.",
                      "code": "invalid_image"
                    }
                  },
                  "Unsupported file extension": {
                    "summary": "tiff/jpg/jpeg/png/webp 이외의 파일 확장자",
                    "value": {
                      "user_image": [
                        "File extension “txt” is not allowed. Allowed extensions are: tiff, jpg, jpeg, png, webp."
                      ]
                    }
                  },
                  "File too large": {
                    "summary": "업로드가 5MB 제한을 초과함",
                    "value": {
                      "user_image": [
                        "File size should not exceed 5 MB"
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었거나 호출한 조직의 잔액이 호출 비용을 충당할 수 없을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 키가 누락된 경우 `{\"detail\": ...}`과 함께 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 크레딧이 부족한 경우 어떠한 이미지 처리도 진행되기 전에 `{\"error\": ...}`과 함께 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 호출 비용을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/passive-liveness/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'user_image=@./selfie.jpg' \\\n  -F 'face_liveness_score_decline_threshold=30' \\\n  -F 'save_api_request=true' \\\n  -F 'vendor_data=user-123'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.passive_liveness.check(\n    user_image=open(\"user_image.jpg\", \"rb\"),\n    face_liveness_score_decline_threshold=30.0,\n    rotate_image=False,\n    save_api_request=True,\n    vendor_data=\"user-123\",\n    metadata={\"flow\": \"withdrawal\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.passiveLiveness.check({\n  user_image: await fileFromPath(\"user_image.jpg\"),\n  face_liveness_score_decline_threshold: 30.0,\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"withdrawal\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.PassiveLiveness.Check(ctx, didit.PassiveLivenessCheckParams{\n\tUserImage:                         didit.FileFromPath(\"user_image.jpg\"),\n\tFaceLivenessScoreDeclineThreshold: didit.Float(30.0),\n\tRotateImage:                       didit.Bool(false),\n\tSaveAPIRequest:                    didit.Bool(true),\n\tVendorData:                        didit.String(\"user-123\"),\n\tMetadata:                          didit.Some(map[string]any{\"flow\": \"withdrawal\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.PassiveLivenessCheckParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.passiveLiveness().check(PassiveLivenessCheckParams.builder()\n        .userImage(Path.of(\"user_image.jpg\"))\n        .faceLivenessScoreDeclineThreshold(30.0)\n        .rotateImage(false)\n        .saveApiRequest(true)\n        .vendorData(\"user-123\")\n        .metadata(Map.of(\"flow\", \"withdrawal\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->passiveLiveness->check([\n    'user_image' => File::fromPath('user_image.jpg'),\n    'face_liveness_score_decline_threshold' => 30.0,\n    'rotate_image' => false,\n    'save_api_request' => true,\n    'vendor_data' => 'user-123',\n    'metadata' => ['flow' => 'withdrawal'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.passive_liveness.check(\n  user_image: Pathname(\"user_image.jpg\"),\n  face_liveness_score_decline_threshold: 30.0,\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"withdrawal\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.PassiveLiveness.CheckAsync(new PassiveLivenessCheckParams\n{\n    UserImage = FileUpload.FromPath(\"user_image.jpg\"),\n    FaceLivenessScoreDeclineThreshold = 30.0,\n    RotateImage = false,\n    SaveApiRequest = true,\n    VendorData = \"user-123\",\n    Metadata = new Dictionary<string, object> { [\"flow\"] = \"withdrawal\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/database-validation/": {
      "post": {
        "summary": "데이터베이스 검증 (단독)",
        "operationId": "post_v3database-validation",
        "x-didit-sdk": {
          "resource": "database_validation",
          "method": "validate",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [],
        "description": "공식 정부 및 등록부 출처(브라질의 CPF, 아르헨티나의 RENAPER, 스페인 및 페루의 DNI 등록부, 멕시코의 INE 및 60+개국에 걸친 100+개 이상의 서비스)를 대상으로 개인의 신원 데이터를 검증합니다.\n\n**서비스 선택.** 각 국가는 `service_id`(예: `bra_cpf`, `arg_renaper`, `pan_cedula_sib`)로 식별되는 하나 이상의 카탈로그 서비스를 제공합니다. `services` 배열로 원하는 서비스를 지정하세요. 이를 생략하면 정확히 **하나**의 기본 서비스(해당 국가에서 가장 오래 운영된 라이브 서비스)가 실행됩니다. 또한 `services`를 전송하면 응답이 `services_used` 및 `match_score`가 포함된 확장된 형식으로 전환됩니다. 서비스, 필수 필드 및 가격은 `GET /v1/organization/database-validation-countries/`(이 사양에 문서화되지 않은 카탈로그 endpoint) 또는 Business Console 워크플로 편집기를 통해 확인할 수 있습니다. 일부 서비스는 카탈로그에서 `requires_consent=true`로 표시되어 `consent=true`를 요구하며, 다른 서비스는 호출하기 전에 조직에 대한 온보딩이 필요합니다.\n\n**입력 필드.** `identification_number`는 해당 국가별 필드에 자동으로 매핑되는 범용 필드입니다(설명 참조). 공급자를 호출하기 전에 국가별 형식 규칙이 적용되며(예: 브라질 CPF는 정확히 11자리여야 함), 형식 오류에 대해서는 비용이 청구되지 않습니다. 생체 인식 서비스는 `selfie` 업로드(multipart 전용)가 필요하며, 아르헨티나 RENAPER는 추가로 `gender`를 요구합니다.\n\n**결과.** 각 서비스는 필드별 `validation` 맵과 공급자 중립적인 `outcome_code`(`MATCH`, `PARTIAL_MATCH`, `NO_MATCH`, `DOCUMENT_NOT_FOUND`, `INVALID_DOCUMENT_FORMAT`, `INVALID_INPUT`, `MINOR_BLOCKED`, `DECEASED`, `BIOMETRIC_NO_MATCH`, `BIOMETRIC_IMAGE_UNUSABLE`, `INCONCLUSIVE`, `DOCUMENT_SUPERSEDED`, `REGISTRY_UNAVAILABLE`, `REGISTRY_ERROR`)를 반환합니다. 차이점에 유의하세요. `NO_MATCH`는 확정적 불일치이며, `INCONCLUSIVE`는 등록부가 어느 쪽으로도 확인할 수 없음을 의미합니다(거부가 아닌 검토 필요). 또한 `BIOMETRIC_IMAGE_UNUSABLE`은 확정적 `BIOMETRIC_NO_MATCH`와 달리 셀피의 기술적 문제(재촬영)입니다. 전체 `match_type`은 여러 서비스에 걸쳐 집계되며(완전 일치가 하나라도 있으면 → `full_match`, 그렇지 않고 부분 일치가 하나라도 있으면 → `partial_match`, 그 외에는 `no_match`), `no_match_action`/`partial_match_action`이 이를 최종 `status`로 변환합니다. `validation_type`은 도출된 값입니다. 두 개 이상의 서로 다른 서비스에서 완전 일치(식별 번호 일치, 성명 + 생년월일 동시 일치, 또는 모순 없는 주소 일치)를 생성한 경우 `two_by_two`가 되며, 그렇지 않으면 `one_by_one`이 됩니다.\n\n**영속성.** `save_api_request`의 기본값은 **true**입니다. 결과는 세션으로 저장되고(`request_id`는 `GET /v3/session/{sessionId}/decision/`에서 작동함), 콘솔에 표시되며, `status.updated` webhook을 트리거합니다. 또한 `validations`의 형식을 제어합니다. 저장된 경우에는 서비스별 객체로, 저장되지 않은 경우에는 병합된 `{field: match}` 맵으로 제공됩니다.\n\n**결제.** 서비스별: 청구 가능한 결과를 반환하는 각 서비스에 고유한 카탈로그 가격이 청구됩니다. 실패하거나 건너뛴 서비스에는 비용이 청구되지 않으며, `400`으로 거부된 요청에는 비용이 발생하지 않습니다. 사전 잔액 확인은 선택한 서비스 가격의 합계를 대상으로 수행됩니다(잔액 부족 시 `403`).\n\n**실패.** 선택한 서비스 중 사용할 수 있는 결과를 반환한 서비스가 없을 때, 사용 가능한 결과를 반환하지 않은 모든 시도가 입력을 명시적으로 거부한 경우(`provider_rejected_input`, `retryable: false`), API는 `validation_errors`와 함께 `400`을 반환합니다. 입력을 수정한 후 다시 시도하세요. 그렇지 않은 경우(입력 거부와 사용 불가능한 대체 시도가 혼합된 경우 포함), `validation_errors`(`empty_provider_response`, `retryable: true`)와 함께 `502`를 반환합니다. 비용은 청구되지 않습니다(`save_api_request=true`인 경우 상태가 `Not Finished`인 세션이 계속 기록됨). 일부 서비스만 실패한 경우, `200` 응답의 `database_validation.errors`에 해당 실패 내용이 포함됩니다.\n\n**샌드박스.** 샌드박스 애플리케이션의 키는 등록부 호출 및 결제를 건너뛰고 정적 `full_match` 응답을 반환합니다. 샌드박스 payload에는 `services` 전송 방식과 관계없이 항상 `services_used` 및 `match_score: 100`이 포함되므로, 샌드박스 응답을 기준으로 프로덕션의 확장된 형식 전환 조건이나 0.0–1.0 범위의 `match_score` 소수값을 검증하지 마세요.\n\n`application/json`으로 요청을 전송하거나, `selfie`를 업로드할 때는 `multipart/form-data`로 전송하세요.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "issuing_state"
                ],
                "properties": {
                  "issuing_state": {
                    "type": "string",
                    "description": "유효성을 검증할 등기부의 ISO 3166-1 **alpha-3** 국가 코드(예: `BRA`, `ESP`, `COL`)입니다. 사용 가능한 서비스를 결정합니다. 지원되지 않는 코드는 유효한 옵션의 전체 목록과 함께 `400`을 반환합니다.",
                    "example": "BRA"
                  },
                  "services": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "해당 국가에 대해 실행할 카탈로그 `service_id` 목록(예: `[\"bra_cpf\"]`). 단일 문자열이나 쉼표로 구분된/JSON으로 인코딩된 문자열도 허용합니다. **생략되거나 비어 있는 경우 정확히 하나의 기본 서비스가 실행됩니다** — 해당 국가에서 가장 오래 운영된 라이브 서비스입니다. 최신 서비스, 생체 인식 서비스 및 종량제 서비스는 명시적으로 지정해야 합니다. `services`를 전송하면 응답이 확장된 형태(`services_used` 및 `match_score` 추가)로 전환됩니다. 모든 id는 `issuing_state`에 존재하고 활성 상태여야 합니다. 온보딩이 필요한 서비스는 조직에 활성화될 때까지 `400`을 반환합니다. 국가별 사용 가능한 서비스는 `GET /v1/organization/database-validation-countries/`(이 사양에 문서화되지 않은 카탈로그 endpoint) 또는 Business Console 워크플로 편집기를 통해 확인할 수 있습니다.",
                    "example": [
                      "bra_cpf"
                    ]
                  },
                  "validation_type": {
                    "type": "string",
                    "deprecated": true,
                    "description": "지원 중단됨. 이전 버전과의 호환성을 위해 허용되지만 무시됩니다. 이제 응답의 `validation_type`은 완전히 일치한 서비스 수에서 파생됩니다. 특정 서비스를 고정하려면 `services`를 사용하세요."
                  },
                  "consent": {
                    "type": "boolean",
                    "default": false,
                    "description": "최종 사용자가 선택한 검증 서비스에 명시적으로 동의한 경우 `true`로 설정합니다. 카탈로그에서 `requires_consent=true`로 표시된 서비스의 경우 필수입니다. 동의하지 않으면 해당 서비스는 `services_requiring_consent`와 함께 `400`을 반환합니다."
                  },
                  "identification_number": {
                    "type": "string",
                    "description": "범용 식별 번호 — 해당 국가별 필드에 자동으로 매핑되므로 `personal_number`/`tax_number`/`document_number` 대신 사용할 수 있습니다: ARG→document_number (DNI), BOL→document_number (CI), BRA→tax_number (CPF, 11자리), CHL→personal_number (RUT), COL→personal_number (Cédula), CRI→personal_number (Cédula), DOM→personal_number (Cédula, 11자리), ECU→personal_number (Cédula, 10자리), ESP→personal_number (DNI/NIE), GTM→document_number (DPI), HND→document_number (DNI), MEX→personal_number (CURP, 18자), PAN→personal_number (Cédula), PER→personal_number (DNI, 8자리), PRY→document_number (CI), SLV→document_number (DUI), URY→personal_number (CI), VEN→document_number (Cédula). 명시적으로 제공된 국가별 필드를 절대 덮어쓰지 않습니다."
                  },
                  "first_name": {
                    "type": "string",
                    "description": "개인의 이름입니다. 일부 서비스/국가에서 필수입니다.",
                    "example": "John"
                  },
                  "last_name": {
                    "type": "string",
                    "description": "개인의 성입니다. 일부 서비스/국가에서 필수입니다.",
                    "example": "Doe"
                  },
                  "middle_name": {
                    "type": "string",
                    "description": "일부 국가 서비스(AUS, NZL 등)에서 사용되는 중간 이름입니다."
                  },
                  "full_name": {
                    "type": "string",
                    "description": "성명 — 일부 서비스에서는 이름/성 대신 이를 허용합니다(예: 고유 문자 체계 이름을 일치시키는 CHN 서비스)."
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "description": "생년월일, `YYYY-MM-DD`입니다. 많은 서비스에서 필수 항목입니다.",
                    "example": "1980-01-01"
                  },
                  "personal_number": {
                    "type": "string",
                    "description": "정부 발급 고유 개인 식별자입니다. 다음 국가에서 사용됩니다: CHL(RUT), COL(Cédula), CRI, DOM, ECU, ESP(DNI/NIE), MEX(CURP), PAN(Cédula), PER(DNI), URY. 대신 `identification_number`를 사용하는 것을 고려하십시오."
                  },
                  "tax_number": {
                    "type": "string",
                    "description": "납세자 번호입니다. 사용 국가: BRA(CPF, 11자리). 대신 `identification_number` 사용을 고려하십시오."
                  },
                  "document_number": {
                    "type": "string",
                    "description": "문서 번호입니다. 다음 국가에서 사용됩니다: ARG (DNI), BOL (CI), GTM (DPI), HND (DNI), PRY (CI), SLV (DUI), VEN (Cédula). 대신 `identification_number` 사용을 고려하세요."
                  },
                  "document_type": {
                    "type": "string",
                    "enum": [
                      "P",
                      "DL",
                      "ID",
                      "RP",
                      "SSC",
                      "HIC",
                      "WP",
                      "TC",
                      "VISA",
                      "PSC",
                      "BC",
                      "OTHER"
                    ],
                    "description": "검증 중인 문서 유형: `P`(여권), `DL`(운전면허증), `ID`(국가 신분증), `RP`(거주 허가증)(추가로 `SSC`, `HIC`, `WP`, `TC`, `VISA`, `PSC`, `BC`, `OTHER`). 일부 서비스(예: ESP)에서 필수입니다."
                  },
                  "expiration_date": {
                    "type": "string",
                    "format": "date",
                    "description": "문서 만료일(`YYYY-MM-DD`)입니다. ESP(스페인) 검증에 필요합니다.",
                    "example": "2030-01-15"
                  },
                  "date_of_issue": {
                    "type": "string",
                    "format": "date",
                    "description": "문서 발급일, `YYYY-MM-DD`(fecha de expedición)입니다. COL(콜롬비아) cédula 검증에 필요합니다.",
                    "example": "2015-06-20"
                  },
                  "nationality": {
                    "type": "string",
                    "description": "ISO 3166-1 alpha-3 형식의 국적입니다. 일부 서비스에서 필수입니다."
                  },
                  "gender": {
                    "type": "string",
                    "enum": [
                      "M",
                      "F",
                      "X"
                    ],
                    "description": "성별: `M`, `F` 또는 `X`(기타/알 수 없음). 아르헨티나 RENAPER 검증(`arg_renaper`) 시 필수입니다."
                  },
                  "address": {
                    "description": "거주지 주소입니다. 구조화된 객체 `{\"street_1\":\"123 Main St\",\"street_2\":\"Apt 4B\",\"city\":\"Springfield\",\"region\":\"IL\",\"postal_code\":\"62701\",\"country\":\"US\"}` 형식을 권장하지만, 완전한 단일 라인 문자열도 허용됩니다. 주소 검증 서비스에 필수입니다. 서비스에 주소 요구사항이 정의되어 있는 경우 누락된 구성 요소가 있으면 `address_fields_required_by`와 함께 `400`이 반환됩니다.",
                    "oneOf": [
                      {
                        "type": "object",
                        "properties": {
                          "street_1": {
                            "type": "string"
                          },
                          "street_2": {
                            "type": "string"
                          },
                          "city": {
                            "type": "string"
                          },
                          "region": {
                            "type": "string"
                          },
                          "postal_code": {
                            "type": "string"
                          },
                          "country": {
                            "type": "string"
                          }
                        }
                      },
                      {
                        "type": "string",
                        "description": "한 줄로 작성된 전체 주소(레거시)입니다."
                      }
                    ]
                  },
                  "address_element_1": {
                    "type": "string",
                    "description": "도로명 번호 및 유형을 포함한 도로명 주소입니다. 생략 시 `address`에서 파생됩니다."
                  },
                  "address_element_2": {
                    "type": "string",
                    "description": "아파트, 동/호수, 건물, 층 또는 추가 주소 라인입니다. 명시적으로 보유한 경우에만 전송하십시오."
                  },
                  "address_element_3": {
                    "type": "string",
                    "description": "시, 교외, 구, 지역 또는 동입니다. 생략된 경우 `address`에서 파생됩니다."
                  },
                  "address_element_4": {
                    "type": "string",
                    "description": "주, 도, 지역 또는 시/군/구입니다. 생략된 경우 `address`에서 파생됩니다."
                  },
                  "address_element_5": {
                    "type": "string",
                    "description": "우편번호입니다. `postal_code`도 별칭으로 허용됩니다."
                  },
                  "postal_code": {
                    "type": "string",
                    "description": "주소 기반 서비스를 위한 우편번호(`address_element_5`의 별칭)입니다."
                  },
                  "driver_license_number": {
                    "type": "string",
                    "description": "정부 문서 검증 서비스(AUS, NZL, IND)용 운전면허증 번호입니다."
                  },
                  "driver_license_card_number": {
                    "type": "string",
                    "description": "면허증 번호와 별도로 요구되는 경우 실물 운전면허증 카드 번호(AUS)."
                  },
                  "driver_license_state": {
                    "type": "string",
                    "description": "운전면허증 발급 주 또는 테리토리(AUS)입니다."
                  },
                  "driver_license_version": {
                    "type": "string",
                    "description": "운전면허증 버전 코드(NZL)입니다."
                  },
                  "passport_number": {
                    "type": "string",
                    "description": "정부 여권 검증 서비스(AUS, NZL, IND, CHN)용 여권 번호입니다."
                  },
                  "passport_expiration_date": {
                    "type": "string",
                    "format": "date",
                    "description": "여권 검증 서비스를 위한 여권 만료일(`YYYY-MM-DD`)입니다."
                  },
                  "passport_file_number": {
                    "type": "string",
                    "description": "여권 파일 번호(IND)입니다."
                  },
                  "passport_issue_country": {
                    "type": "string",
                    "description": "여권 인증 서비스용 여권 발급 국가(ISO 3166-1 alpha-3)입니다."
                  },
                  "medicare_card_number": {
                    "type": "string",
                    "description": "Medicare 카드 번호(AUS)."
                  },
                  "immi_card_number": {
                    "type": "string",
                    "description": "호주 ImmiCard 번호입니다."
                  },
                  "immi_card_expiry_date": {
                    "type": "string",
                    "format": "date",
                    "description": "호주 ImmiCard 만료일입니다."
                  },
                  "citizenship_certificate_number": {
                    "type": "string",
                    "description": "시민권 증명서 번호(AUS)입니다."
                  },
                  "birth_registration_number": {
                    "type": "string",
                    "description": "출생증명서 등록번호(호주)."
                  },
                  "birth_registration_date": {
                    "type": "string",
                    "format": "date",
                    "description": "출생증명서 등록일(호주)."
                  },
                  "birth_registration_state": {
                    "type": "string",
                    "description": "출생증명서 등록 주/지역(호주)."
                  },
                  "marriage_certificate_number": {
                    "type": "string",
                    "description": "혼인 증명서 번호(AUS)."
                  },
                  "change_of_name_certificate_number": {
                    "type": "string",
                    "description": "개명 증명서 번호(호주)."
                  },
                  "first_partner_name": {
                    "type": "string",
                    "description": "결혼 증명서상의 배우자 이름(호주)입니다."
                  },
                  "last_partner_name": {
                    "type": "string",
                    "description": "결혼 증명서(AUS)에 기재된 배우자의 성입니다."
                  },
                  "voter_id": {
                    "type": "string",
                    "description": "유권자 등록번호(IND EPIC, IRL)입니다."
                  },
                  "epic_card": {
                    "type": "string",
                    "description": "인도 EPIC 유권자 카드 번호."
                  },
                  "pan": {
                    "type": "string",
                    "description": "인도 PAN(영구 계좌 번호)."
                  },
                  "national_id": {
                    "type": "string",
                    "description": "국가 신분증 번호(CHN, MYS, KEN, KHM, NGA, ZAF, …)."
                  },
                  "cic": {
                    "type": "string",
                    "description": "멕시코 INE/IFE 신분증 식별 코드(CIC, 9자리)입니다. 멕시코 INE 신분증 유효성 서비스(`mex_ine_vigencia`)에서 사용됩니다."
                  },
                  "identificador_ciudadano": {
                    "type": "string",
                    "description": "멕시코 INE 시민 식별자(Identificador del Ciudadano, 9자리)입니다. `mex_ine_vigencia`에서 최신 INE 모델(E/F/G/H)의 `cic`와 함께 사용됩니다."
                  },
                  "ocr": {
                    "type": "string",
                    "description": "멕시코 INE OCR 번호(13자리, 카드 뒷면)입니다. `mex_ine_vigencia`에서 모델 D의 `cic`와 함께 사용됩니다."
                  },
                  "voter_number": {
                    "type": "string",
                    "description": "멕시코 INE 유권자 식별 번호(Clave de Elector, 18자)입니다. `mex_ine_vigencia`에서 기존 IFE 모델(A/B/C)의 `emission_number`와 함께 사용됩니다."
                  },
                  "emission_number": {
                    "type": "string",
                    "description": "멕시코 INE 발급 번호(Número de Emisión)입니다. `mex_ine_vigencia`에서 기존 IFE 모델(A/B/C)의 `voter_number`와 함께 사용됩니다."
                  },
                  "bvn": {
                    "type": "string",
                    "description": "나이지리아 은행 검증 번호입니다."
                  },
                  "bank_card_number": {
                    "type": "string",
                    "description": "은행 카드 번호입니다(중국 은행 카드 인증)."
                  },
                  "company_registration_number": {
                    "type": "string",
                    "description": "법인 등기부에서 발급한 기업 등록번호입니다. 예를 들어 브라질의 CNPJ(예: `11222333000181`), 남아프리카공화국의 등록번호(예: `1936/007721/06`) 등이 있습니다. 법인 등기부 및 기업 이사 조회 서비스(`bra_company_registry`, `bra_company_directors`, `zaf_company_registry`, `zaf_company_directors`)에서 필수입니다."
                  },
                  "company_name": {
                    "type": "string",
                    "description": "등록부 항목과 대조 확인된 등록 회사명입니다. `zaf_company_registry`의 경우 선택 사항입니다."
                  },
                  "initials": {
                    "type": "string",
                    "description": "문서에 인쇄된 해당 인물의 이니셜입니다. `zaf_drivers_license`에는 필수이며, `zaf_bank_account_holder`에서는 허용됩니다."
                  },
                  "licence_number": {
                    "type": "string",
                    "description": "`zaf_drivers_license`의 카드에 인쇄된 운전면허증 번호입니다. 생략 시 `document_number`가 사용됩니다."
                  },
                  "refugee_file_number": {
                    "type": "string",
                    "description": "남아프리카공화국 내무부에서 발급한 난민 파일 번호입니다. `zaf_refugee`에 필수입니다."
                  },
                  "bank_name": {
                    "type": "string",
                    "description": "계좌를 보유한 은행의 이름입니다. `zaf_bank_account_holder`에 필수입니다."
                  },
                  "bank_account_number": {
                    "type": "string",
                    "description": "은행 계좌번호입니다. `zaf_bank_account_holder`에 필수이며, `zaf_fraud_prevention`에서 허용됩니다."
                  },
                  "account_type": {
                    "type": "string",
                    "description": "`zaf_bank_account_holder`의 은행 계좌 유형: `current`, `savings`, `transmission`, `subscriptionShare` 또는 `notKnown`(대소문자 구분 없음). 다른 모든 값은 `400`을 반환합니다. 유형을 모르는 경우 생략하십시오. 이 경우 계좌 유형 교차 검증은 확인되지 않음으로 보고됩니다."
                  },
                  "phone_number": {
                    "type": "string",
                    "description": "연락 가능 여부를 교차 확인하는 서비스(`zaf_bank_account_holder`, `zaf_fraud_prevention`, `zaf_refugee`)를 위한 연락처 휴대폰 번호입니다."
                  },
                  "right_thumb": {
                    "type": "string",
                    "description": "`zaf_dha_fingerprint_match`를 위한 Base64 인코딩된 오른손 엄지 지문으로, `left_thumb`와 함께 전송하거나 단독으로 전송합니다."
                  },
                  "left_thumb": {
                    "type": "string",
                    "description": "`zaf_dha_fingerprint_match`를 위한 Base64 인코딩된 왼손 엄지 지문으로, `right_thumb`와 함께 전송하거나 단독으로 전송합니다."
                  },
                  "score_level": {
                    "type": "integer",
                    "description": "`zaf_criminal_face_screening`의 최소 생체 인식 점수 등급입니다. 기본값은 `3`입니다."
                  },
                  "max_matches": {
                    "type": "integer",
                    "description": "`zaf_criminal_face_screening`이 반환하는 최대 후보 일치 항목 수입니다. 기본값은 `1`입니다."
                  },
                  "vehicle_register_number": {
                    "type": "string",
                    "description": "차량 등록번호. `zaf_vehicle_ownership`에서 `vehicle_licence_plate` 및 `vin`과 함께 필수입니다."
                  },
                  "vehicle_licence_plate": {
                    "type": "string",
                    "description": "차량 번호판 번호. `zaf_vehicle_ownership`에서 `vehicle_register_number` 및 `vin`과 함께 필수입니다."
                  },
                  "vin": {
                    "type": "string",
                    "description": "차대번호(VIN 또는 섀시 번호). `zaf_vehicle_ownership`에서 `vehicle_register_number` 및 `vehicle_licence_plate`와 함께 필수입니다."
                  },
                  "ssn": {
                    "type": "string",
                    "description": "사회보장번호(미국)."
                  },
                  "phone": {
                    "type": "string",
                    "description": "전화번호 인증 서비스를 위한 전화번호입니다."
                  },
                  "landline": {
                    "type": "string",
                    "description": "전화번호 인증 서비스용 유선 전화번호입니다."
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "신원 인증 서비스에 사용할 이메일 주소입니다."
                  },
                  "country_of_residence": {
                    "type": "string",
                    "description": "거주 국가의 ISO 3166-1 alpha-2 코드입니다. 글로벌 신원 보강 서비스(예: `glb_identity_enrichment`)에서 조회를 세부 조정하는 데 사용됩니다.",
                    "example": "US"
                  },
                  "partial_match_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "NO_ACTION",
                    "description": "`partial_match`가 `database_validation.status`에 적용하는 영향입니다. 기본값은 `NO_ACTION`입니다(상태는 경고와 함께 `Approved`로 유지됨)."
                  },
                  "no_match_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "`no_match`가 `database_validation.status`에 적용하는 영향입니다. 기본값은 `DECLINE`입니다."
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "검증을 세션으로 유지합니다(콘솔 표시, 결정 endpoint, `status.updated` webhook). 또한 `validations` 응답 형태를 변경합니다: `true`(기본값)인 경우 서비스별 객체, `false`인 경우 병합된 필드 맵."
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "검증 대상 사용자에 대한 귀하의 식별자입니다. 세션에 저장되며 그대로 다시 반환됩니다."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "요청과 함께 저장되고 그대로 반환되는 자유 형식 JSON입니다."
                  }
                }
              },
              "example": {
                "issuing_state": "BRA",
                "services": [
                  "bra_cpf"
                ],
                "identification_number": "12345678900",
                "first_name": "John",
                "last_name": "Doe",
                "date_of_birth": "1980-01-01",
                "vendor_data": "user-1234"
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "issuing_state"
                ],
                "properties": {
                  "issuing_state": {
                    "type": "string",
                    "description": "유효성을 검증할 등기부의 ISO 3166-1 **alpha-3** 국가 코드(예: `BRA`, `ESP`, `COL`)입니다. 사용 가능한 서비스를 결정합니다. 지원되지 않는 코드는 유효한 옵션의 전체 목록과 함께 `400`을 반환합니다.",
                    "example": "BRA"
                  },
                  "services": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "해당 국가에 대해 실행할 카탈로그 `service_id` 목록(예: `[\"bra_cpf\"]`). 단일 문자열이나 쉼표로 구분된/JSON으로 인코딩된 문자열도 허용합니다. **생략되거나 비어 있는 경우 정확히 하나의 기본 서비스가 실행됩니다** — 해당 국가에서 가장 오래 운영된 라이브 서비스입니다. 최신 서비스, 생체 인식 서비스 및 종량제 서비스는 명시적으로 지정해야 합니다. `services`를 전송하면 응답이 확장된 형태(`services_used` 및 `match_score` 추가)로 전환됩니다. 모든 id는 `issuing_state`에 존재하고 활성 상태여야 합니다. 온보딩이 필요한 서비스는 조직에 활성화될 때까지 `400`을 반환합니다. 국가별 사용 가능한 서비스는 `GET /v1/organization/database-validation-countries/`(이 사양에 문서화되지 않은 카탈로그 endpoint) 또는 Business Console 워크플로 편집기를 통해 확인할 수 있습니다.",
                    "example": [
                      "bra_cpf"
                    ]
                  },
                  "validation_type": {
                    "type": "string",
                    "deprecated": true,
                    "description": "지원 중단됨. 이전 버전과의 호환성을 위해 허용되지만 무시됩니다. 이제 응답의 `validation_type`은 완전히 일치한 서비스 수에서 파생됩니다. 특정 서비스를 고정하려면 `services`를 사용하세요."
                  },
                  "consent": {
                    "type": "boolean",
                    "default": false,
                    "description": "최종 사용자가 선택한 검증 서비스에 명시적으로 동의한 경우 `true`로 설정합니다. 카탈로그에서 `requires_consent=true`로 표시된 서비스의 경우 필수입니다. 동의하지 않으면 해당 서비스는 `services_requiring_consent`와 함께 `400`을 반환합니다."
                  },
                  "identification_number": {
                    "type": "string",
                    "description": "범용 식별 번호 — 해당 국가별 필드에 자동으로 매핑되므로 `personal_number`/`tax_number`/`document_number` 대신 사용할 수 있습니다: ARG→document_number (DNI), BOL→document_number (CI), BRA→tax_number (CPF, 11자리), CHL→personal_number (RUT), COL→personal_number (Cédula), CRI→personal_number (Cédula), DOM→personal_number (Cédula, 11자리), ECU→personal_number (Cédula, 10자리), ESP→personal_number (DNI/NIE), GTM→document_number (DPI), HND→document_number (DNI), MEX→personal_number (CURP, 18자), PAN→personal_number (Cédula), PER→personal_number (DNI, 8자리), PRY→document_number (CI), SLV→document_number (DUI), URY→personal_number (CI), VEN→document_number (Cédula). 명시적으로 제공된 국가별 필드를 절대 덮어쓰지 않습니다."
                  },
                  "first_name": {
                    "type": "string",
                    "description": "개인의 이름입니다. 일부 서비스/국가에서 필수입니다.",
                    "example": "John"
                  },
                  "last_name": {
                    "type": "string",
                    "description": "개인의 성입니다. 일부 서비스/국가에서 필수입니다.",
                    "example": "Doe"
                  },
                  "middle_name": {
                    "type": "string",
                    "description": "일부 국가 서비스(AUS, NZL 등)에서 사용되는 중간 이름입니다."
                  },
                  "full_name": {
                    "type": "string",
                    "description": "성명 — 일부 서비스에서는 이름/성 대신 이를 허용합니다(예: 고유 문자 체계 이름을 일치시키는 CHN 서비스)."
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "description": "생년월일, `YYYY-MM-DD`입니다. 많은 서비스에서 필수 항목입니다.",
                    "example": "1980-01-01"
                  },
                  "personal_number": {
                    "type": "string",
                    "description": "정부 발급 고유 개인 식별자입니다. 다음 국가에서 사용됩니다: CHL(RUT), COL(Cédula), CRI, DOM, ECU, ESP(DNI/NIE), MEX(CURP), PAN(Cédula), PER(DNI), URY. 대신 `identification_number`를 사용하는 것을 고려하십시오."
                  },
                  "tax_number": {
                    "type": "string",
                    "description": "납세자 번호입니다. 사용 국가: BRA(CPF, 11자리). 대신 `identification_number` 사용을 고려하십시오."
                  },
                  "document_number": {
                    "type": "string",
                    "description": "문서 번호입니다. 다음 국가에서 사용됩니다: ARG (DNI), BOL (CI), GTM (DPI), HND (DNI), PRY (CI), SLV (DUI), VEN (Cédula). 대신 `identification_number` 사용을 고려하세요."
                  },
                  "document_type": {
                    "type": "string",
                    "enum": [
                      "P",
                      "DL",
                      "ID",
                      "RP",
                      "SSC",
                      "HIC",
                      "WP",
                      "TC",
                      "VISA",
                      "PSC",
                      "BC",
                      "OTHER"
                    ],
                    "description": "검증 중인 문서 유형: `P`(여권), `DL`(운전면허증), `ID`(국가 신분증), `RP`(거주 허가증)(추가로 `SSC`, `HIC`, `WP`, `TC`, `VISA`, `PSC`, `BC`, `OTHER`). 일부 서비스(예: ESP)에서 필수입니다."
                  },
                  "expiration_date": {
                    "type": "string",
                    "format": "date",
                    "description": "문서 만료일(`YYYY-MM-DD`)입니다. ESP(스페인) 검증에 필요합니다.",
                    "example": "2030-01-15"
                  },
                  "date_of_issue": {
                    "type": "string",
                    "format": "date",
                    "description": "문서 발급일, `YYYY-MM-DD`(fecha de expedición)입니다. COL(콜롬비아) cédula 검증에 필요합니다.",
                    "example": "2015-06-20"
                  },
                  "nationality": {
                    "type": "string",
                    "description": "ISO 3166-1 alpha-3 형식의 국적입니다. 일부 서비스에서 필수입니다."
                  },
                  "gender": {
                    "type": "string",
                    "enum": [
                      "M",
                      "F",
                      "X"
                    ],
                    "description": "성별: `M`, `F` 또는 `X`(기타/알 수 없음). 아르헨티나 RENAPER 검증(`arg_renaper`) 시 필수입니다."
                  },
                  "address": {
                    "description": "거주지 주소입니다. 구조화된 객체 `{\"street_1\":\"123 Main St\",\"street_2\":\"Apt 4B\",\"city\":\"Springfield\",\"region\":\"IL\",\"postal_code\":\"62701\",\"country\":\"US\"}` 형식을 권장하지만, 완전한 단일 라인 문자열도 허용됩니다. 주소 검증 서비스에 필수입니다. 서비스에 주소 요구사항이 정의되어 있는 경우 누락된 구성 요소가 있으면 `address_fields_required_by`와 함께 `400`이 반환됩니다.",
                    "oneOf": [
                      {
                        "type": "object",
                        "properties": {
                          "street_1": {
                            "type": "string"
                          },
                          "street_2": {
                            "type": "string"
                          },
                          "city": {
                            "type": "string"
                          },
                          "region": {
                            "type": "string"
                          },
                          "postal_code": {
                            "type": "string"
                          },
                          "country": {
                            "type": "string"
                          }
                        }
                      },
                      {
                        "type": "string",
                        "description": "한 줄로 작성된 전체 주소(레거시)입니다."
                      }
                    ]
                  },
                  "address_element_1": {
                    "type": "string",
                    "description": "도로명 번호 및 유형을 포함한 도로명 주소입니다. 생략 시 `address`에서 파생됩니다."
                  },
                  "address_element_2": {
                    "type": "string",
                    "description": "아파트, 동/호수, 건물, 층 또는 추가 주소 라인입니다. 명시적으로 보유한 경우에만 전송하십시오."
                  },
                  "address_element_3": {
                    "type": "string",
                    "description": "시, 교외, 구, 지역 또는 동입니다. 생략된 경우 `address`에서 파생됩니다."
                  },
                  "address_element_4": {
                    "type": "string",
                    "description": "주, 도, 지역 또는 시/군/구입니다. 생략된 경우 `address`에서 파생됩니다."
                  },
                  "address_element_5": {
                    "type": "string",
                    "description": "우편번호입니다. `postal_code`도 별칭으로 허용됩니다."
                  },
                  "postal_code": {
                    "type": "string",
                    "description": "주소 기반 서비스를 위한 우편번호(`address_element_5`의 별칭)입니다."
                  },
                  "driver_license_number": {
                    "type": "string",
                    "description": "정부 문서 검증 서비스(AUS, NZL, IND)용 운전면허증 번호입니다."
                  },
                  "driver_license_card_number": {
                    "type": "string",
                    "description": "면허증 번호와 별도로 요구되는 경우 실물 운전면허증 카드 번호(AUS)."
                  },
                  "driver_license_state": {
                    "type": "string",
                    "description": "운전면허증 발급 주 또는 테리토리(AUS)입니다."
                  },
                  "driver_license_version": {
                    "type": "string",
                    "description": "운전면허증 버전 코드(NZL)입니다."
                  },
                  "passport_number": {
                    "type": "string",
                    "description": "정부 여권 검증 서비스(AUS, NZL, IND, CHN)용 여권 번호입니다."
                  },
                  "passport_expiration_date": {
                    "type": "string",
                    "format": "date",
                    "description": "여권 검증 서비스를 위한 여권 만료일(`YYYY-MM-DD`)입니다."
                  },
                  "passport_file_number": {
                    "type": "string",
                    "description": "여권 파일 번호(IND)입니다."
                  },
                  "passport_issue_country": {
                    "type": "string",
                    "description": "여권 인증 서비스용 여권 발급 국가(ISO 3166-1 alpha-3)입니다."
                  },
                  "medicare_card_number": {
                    "type": "string",
                    "description": "Medicare 카드 번호(AUS)."
                  },
                  "immi_card_number": {
                    "type": "string",
                    "description": "호주 ImmiCard 번호입니다."
                  },
                  "immi_card_expiry_date": {
                    "type": "string",
                    "format": "date",
                    "description": "호주 ImmiCard 만료일입니다."
                  },
                  "citizenship_certificate_number": {
                    "type": "string",
                    "description": "시민권 증명서 번호(AUS)입니다."
                  },
                  "birth_registration_number": {
                    "type": "string",
                    "description": "출생증명서 등록번호(호주)."
                  },
                  "birth_registration_date": {
                    "type": "string",
                    "format": "date",
                    "description": "출생증명서 등록일(호주)."
                  },
                  "birth_registration_state": {
                    "type": "string",
                    "description": "출생증명서 등록 주/지역(호주)."
                  },
                  "marriage_certificate_number": {
                    "type": "string",
                    "description": "혼인 증명서 번호(AUS)."
                  },
                  "change_of_name_certificate_number": {
                    "type": "string",
                    "description": "개명 증명서 번호(호주)."
                  },
                  "first_partner_name": {
                    "type": "string",
                    "description": "결혼 증명서상의 배우자 이름(호주)입니다."
                  },
                  "last_partner_name": {
                    "type": "string",
                    "description": "결혼 증명서(AUS)에 기재된 배우자의 성입니다."
                  },
                  "voter_id": {
                    "type": "string",
                    "description": "유권자 등록번호(IND EPIC, IRL)입니다."
                  },
                  "epic_card": {
                    "type": "string",
                    "description": "인도 EPIC 유권자 카드 번호."
                  },
                  "pan": {
                    "type": "string",
                    "description": "인도 PAN(영구 계좌 번호)."
                  },
                  "national_id": {
                    "type": "string",
                    "description": "국가 신분증 번호(CHN, MYS, KEN, KHM, NGA, ZAF, …)."
                  },
                  "cic": {
                    "type": "string",
                    "description": "멕시코 INE/IFE 신분증 식별 코드(CIC, 9자리)입니다. 멕시코 INE 신분증 유효성 서비스(`mex_ine_vigencia`)에서 사용됩니다."
                  },
                  "identificador_ciudadano": {
                    "type": "string",
                    "description": "멕시코 INE 시민 식별자(Identificador del Ciudadano, 9자리)입니다. `mex_ine_vigencia`에서 최신 INE 모델(E/F/G/H)의 `cic`와 함께 사용됩니다."
                  },
                  "ocr": {
                    "type": "string",
                    "description": "멕시코 INE OCR 번호(13자리, 카드 뒷면)입니다. `mex_ine_vigencia`에서 모델 D의 `cic`와 함께 사용됩니다."
                  },
                  "voter_number": {
                    "type": "string",
                    "description": "멕시코 INE 유권자 식별 번호(Clave de Elector, 18자)입니다. `mex_ine_vigencia`에서 기존 IFE 모델(A/B/C)의 `emission_number`와 함께 사용됩니다."
                  },
                  "emission_number": {
                    "type": "string",
                    "description": "멕시코 INE 발급 번호(Número de Emisión)입니다. `mex_ine_vigencia`에서 기존 IFE 모델(A/B/C)의 `voter_number`와 함께 사용됩니다."
                  },
                  "bvn": {
                    "type": "string",
                    "description": "나이지리아 은행 검증 번호입니다."
                  },
                  "bank_card_number": {
                    "type": "string",
                    "description": "은행 카드 번호입니다(중국 은행 카드 인증)."
                  },
                  "company_registration_number": {
                    "type": "string",
                    "description": "법인 등기부에서 발급한 기업 등록번호입니다. 예를 들어 브라질의 CNPJ(예: `11222333000181`), 남아프리카공화국의 등록번호(예: `1936/007721/06`) 등이 있습니다. 법인 등기부 및 기업 이사 조회 서비스(`bra_company_registry`, `bra_company_directors`, `zaf_company_registry`, `zaf_company_directors`)에서 필수입니다."
                  },
                  "company_name": {
                    "type": "string",
                    "description": "등록부 항목과 대조 확인된 등록 회사명입니다. `zaf_company_registry`의 경우 선택 사항입니다."
                  },
                  "initials": {
                    "type": "string",
                    "description": "문서에 인쇄된 해당 인물의 이니셜입니다. `zaf_drivers_license`에는 필수이며, `zaf_bank_account_holder`에서는 허용됩니다."
                  },
                  "licence_number": {
                    "type": "string",
                    "description": "`zaf_drivers_license`의 카드에 인쇄된 운전면허증 번호입니다. 생략 시 `document_number`가 사용됩니다."
                  },
                  "refugee_file_number": {
                    "type": "string",
                    "description": "남아프리카공화국 내무부에서 발급한 난민 파일 번호입니다. `zaf_refugee`에 필수입니다."
                  },
                  "bank_name": {
                    "type": "string",
                    "description": "계좌를 보유한 은행의 이름입니다. `zaf_bank_account_holder`에 필수입니다."
                  },
                  "bank_account_number": {
                    "type": "string",
                    "description": "은행 계좌번호입니다. `zaf_bank_account_holder`에 필수이며, `zaf_fraud_prevention`에서 허용됩니다."
                  },
                  "account_type": {
                    "type": "string",
                    "description": "`zaf_bank_account_holder`의 은행 계좌 유형: `current`, `savings`, `transmission`, `subscriptionShare` 또는 `notKnown`(대소문자 구분 없음). 다른 모든 값은 `400`을 반환합니다. 유형을 모르는 경우 생략하십시오. 이 경우 계좌 유형 교차 검증은 확인되지 않음으로 보고됩니다."
                  },
                  "phone_number": {
                    "type": "string",
                    "description": "연락 가능 여부를 교차 확인하는 서비스(`zaf_bank_account_holder`, `zaf_fraud_prevention`, `zaf_refugee`)를 위한 연락처 휴대폰 번호입니다."
                  },
                  "right_thumb": {
                    "type": "string",
                    "description": "`zaf_dha_fingerprint_match`를 위한 Base64 인코딩된 오른손 엄지 지문으로, `left_thumb`와 함께 전송하거나 단독으로 전송합니다."
                  },
                  "left_thumb": {
                    "type": "string",
                    "description": "`zaf_dha_fingerprint_match`를 위한 Base64 인코딩된 왼손 엄지 지문으로, `right_thumb`와 함께 전송하거나 단독으로 전송합니다."
                  },
                  "score_level": {
                    "type": "integer",
                    "description": "`zaf_criminal_face_screening`의 최소 생체 인식 점수 등급입니다. 기본값은 `3`입니다."
                  },
                  "max_matches": {
                    "type": "integer",
                    "description": "`zaf_criminal_face_screening`이 반환하는 최대 후보 일치 항목 수입니다. 기본값은 `1`입니다."
                  },
                  "vehicle_register_number": {
                    "type": "string",
                    "description": "차량 등록번호. `zaf_vehicle_ownership`에서 `vehicle_licence_plate` 및 `vin`과 함께 필수입니다."
                  },
                  "vehicle_licence_plate": {
                    "type": "string",
                    "description": "차량 번호판 번호. `zaf_vehicle_ownership`에서 `vehicle_register_number` 및 `vin`과 함께 필수입니다."
                  },
                  "vin": {
                    "type": "string",
                    "description": "차대번호(VIN 또는 섀시 번호). `zaf_vehicle_ownership`에서 `vehicle_register_number` 및 `vehicle_licence_plate`와 함께 필수입니다."
                  },
                  "ssn": {
                    "type": "string",
                    "description": "사회보장번호(미국)."
                  },
                  "phone": {
                    "type": "string",
                    "description": "전화번호 인증 서비스를 위한 전화번호입니다."
                  },
                  "landline": {
                    "type": "string",
                    "description": "전화번호 인증 서비스용 유선 전화번호입니다."
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "신원 인증 서비스에 사용할 이메일 주소입니다."
                  },
                  "country_of_residence": {
                    "type": "string",
                    "description": "거주 국가의 ISO 3166-1 alpha-2 코드입니다. 글로벌 신원 보강 서비스(예: `glb_identity_enrichment`)에서 조회를 세부 조정하는 데 사용됩니다.",
                    "example": "US"
                  },
                  "partial_match_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "NO_ACTION",
                    "description": "`partial_match`가 `database_validation.status`에 적용하는 영향입니다. 기본값은 `NO_ACTION`입니다(상태는 경고와 함께 `Approved`로 유지됨)."
                  },
                  "no_match_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "`no_match`가 `database_validation.status`에 적용하는 영향입니다. 기본값은 `DECLINE`입니다."
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "검증을 세션으로 유지합니다(콘솔 표시, 결정 endpoint, `status.updated` webhook). 또한 `validations` 응답 형태를 변경합니다: `true`(기본값)인 경우 서비스별 객체, `false`인 경우 병합된 필드 맵."
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "검증 대상 사용자에 대한 귀하의 식별자입니다. 세션에 저장되며 그대로 다시 반환됩니다."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "요청과 함께 저장되고 그대로 반환되는 자유 형식 JSON입니다."
                  },
                  "selfie": {
                    "type": "string",
                    "format": "binary",
                    "description": "아르헨티나 RENAPER(`arg_renaper`) 및 파나마 SIB(`pan_cedula_sib`, `pan_cedula_sib_plus`) 등 생체 검증 서비스용 셀피 이미지(`jpg`, `jpeg`, `png`, `webp`, 최대 2MB — 이미지는 등기부 업로드 전 약 1.5MB로 압축됨)입니다. 선택한 서비스에서 필수 필드로 나열된 경우 항상 필요합니다. `multipart/form-data`를 통해서만 사용할 수 있습니다."
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/database-validation/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"issuing_state\": \"BRA\",\n    \"services\": [\"bra_cpf\"],\n    \"identification_number\": \"12345678900\",\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"date_of_birth\": \"1980-01-01\",\n    \"vendor_data\": \"user-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.database_validation.validate(\n    issuing_state=\"BRA\",\n    services=[\"bra_cpf\"],\n    identification_number=\"12345678900\",\n    first_name=\"John\",\n    last_name=\"Doe\",\n    date_of_birth=\"1980-01-01\",\n    vendor_data=\"user-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.databaseValidation.validate({\n  issuing_state: \"BRA\",\n  services: [\"bra_cpf\"],\n  identification_number: \"12345678900\",\n  first_name: \"John\",\n  last_name: \"Doe\",\n  date_of_birth: \"1980-01-01\",\n  vendor_data: \"user-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.DatabaseValidation.Validate(ctx, didit.DatabaseValidationValidateParams{\n\tIssuingState:         \"BRA\",\n\tServices:             didit.Some([]string{\"bra_cpf\"}),\n\tIdentificationNumber: didit.String(\"12345678900\"),\n\tFirstName:            didit.String(\"John\"),\n\tLastName:             didit.String(\"Doe\"),\n\tDateOfBirth:          didit.String(\"1980-01-01\"),\n\tVendorData:           didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.DatabaseValidationValidateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.databaseValidation().validate(DatabaseValidationValidateParams.builder()\n        .issuingState(\"BRA\")\n        .services(List.of(\"bra_cpf\"))\n        .identificationNumber(\"12345678900\")\n        .firstName(\"John\")\n        .lastName(\"Doe\")\n        .dateOfBirth(LocalDate.parse(\"1980-01-01\"))\n        .vendorData(\"user-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->databaseValidation->validate([\n    'issuing_state' => 'BRA',\n    'services' => ['bra_cpf'],\n    'identification_number' => '12345678900',\n    'first_name' => 'John',\n    'last_name' => 'Doe',\n    'date_of_birth' => '1980-01-01',\n    'vendor_data' => 'user-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.database_validation.validate(\n  issuing_state: \"BRA\",\n  services: [\"bra_cpf\"],\n  identification_number: \"12345678900\",\n  first_name: \"John\",\n  last_name: \"Doe\",\n  date_of_birth: \"1980-01-01\",\n  vendor_data: \"user-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.DatabaseValidation.ValidateAsync(new DatabaseValidationValidateParams\n{\n    IssuingState = \"BRA\",\n    Services = new string[] { \"bra_cpf\" },\n    IdentificationNumber = \"12345678900\",\n    FirstName = \"John\",\n    LastName = \"Doe\",\n    DateOfBirth = \"1980-01-01\",\n    VendorData = \"user-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "검증 완료 — 선택한 서비스 중 최소 하나가 사용 가능한 결과를 반환했습니다. 종합 결과는 `database_validation.match_type`, 서비스별 필드 비교 및 `outcome_code`s는 `validations`, 실패한 서비스는 `errors`(있는 경우)를 확인하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "`save_api_request=true`일 때 유지된 세션 ID(`GET /v3/session/{sessionId}/decision/`와 함께 사용 가능), 그렇지 않으면 임시 상관관계 UUID입니다."
                    },
                    "database_validation": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined",
                            "In Review"
                          ],
                          "description": "전체 `match_type`이 `DECLINE` 작업을 트리거하는 경우 `Declined`(`no_match_action`의 기본값은 `DECLINE`, `partial_match_action`의 기본값은 `NO_ACTION`), 유효한 비교를 생성한 서비스가 없는 경우(예: 선택된 유일한 서비스가 `REGISTRY_UNAVAILABLE` 또는 `INCONCLUSIVE`를 반환한 경우) `In Review`, 그렇지 않은 경우 `Approved`. 여러 서비스를 선택한 요청은 한 서비스에서 일치하여 `Approved`되는 동시에 다른 서비스를 사용할 수 없었을 수 있으므로 `errors` 및 서비스별 `outcome_code`도 확인하십시오."
                        },
                        "issuing_state": {
                          "type": "string",
                          "description": "검증 기준이 된 ISO 3166-1 alpha-3 국가의 에코 값입니다.",
                          "example": "BRA"
                        },
                        "validation_type": {
                          "type": "string",
                          "enum": [
                            "one_by_one",
                            "two_by_two"
                          ],
                          "description": "결과에서 도출됨: 2개 이상의 서로 다른 서비스에서 완전 일치(식별 번호 일치, 성명과 생년월일 동시 일치, 또는 모순 없는 주소 일치)를 생성한 경우 `two_by_two`, 그렇지 않은 경우 `one_by_one`입니다. (동일한 이름의 요청 필드는 지원 중단되었으며 무시됩니다.)"
                        },
                        "screened_data": {
                          "type": "object",
                          "description": "선택한 서비스로 전송된 입력 필드의 에코 값입니다(날짜는 `YYYY-MM-DD` 형식으로 정규화되며, `selfie`는 전송된 경우 사전 서명된 URL로 반환되고, 동의를 받은 경우 `consent_obtained: true`가 추가됨)."
                        },
                        "match_type": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "full_match",
                            "partial_match",
                            "no_match"
                          ],
                          "description": "필드 수준 비교를 통해 서비스 전반에서 집계된 전체 결과: `full_match`가 하나라도 있으면 → `full_match`, 그렇지 않고 `partial_match`가 하나라도 있으면 → `partial_match`, 그 외에는 `no_match`입니다. 생체 범죄 스크리닝과 같은 결과 전용 서비스는 `null`을 반환할 수 있으므로, 각 `validations` 항목의 `outcome_code`를 확인하십시오."
                        },
                        "validations": {
                          "description": "형태는 `save_api_request`에 따라 달라집니다. **`true`(기본값):** 서비스별 객체 배열(`service_id`, `service_name`, `validation`, `outcome_code`, `outcome_detail`, `source_data`)입니다. **`false`:** 모든 서비스의 필드 수준 결과를 병합한 단일 플랫 객체(`{\"full_name\": \"full_match\", ...}`)입니다.",
                          "oneOf": [
                            {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "description": "서비스별 검증 결과입니다(`save_api_request=true`일 때 반환되며 기본값임).",
                                "properties": {
                                  "service_id": {
                                    "type": "string",
                                    "description": "이 결과를 생성한 서비스의 카탈로그 id(예: `bra_cpf`).",
                                    "example": "bra_cpf"
                                  },
                                  "service_name": {
                                    "type": "string",
                                    "description": "서비스의 사람이 읽기 쉬운 카탈로그 이름입니다.",
                                    "example": "Brazil - CPF status check"
                                  },
                                  "validation": {
                                    "type": "object",
                                    "description": "입력값과 등기부 기록 간의 필드별 비교입니다. 키는 표준 필드 이름(`full_name`, `date_of_birth`, `identification_number`, `address`, …)이며, 값은 `full_match`, `partial_match` 또는 `no_match`입니다.",
                                    "additionalProperties": {
                                      "type": "string",
                                      "enum": [
                                        "full_match",
                                        "partial_match",
                                        "no_match"
                                      ]
                                    }
                                  },
                                  "outcome_code": {
                                    "type": "string",
                                    "enum": [
                                      "MATCH",
                                      "PARTIAL_MATCH",
                                      "NO_MATCH",
                                      "DOCUMENT_NOT_FOUND",
                                      "INVALID_DOCUMENT_FORMAT",
                                      "INVALID_INPUT",
                                      "MINOR_BLOCKED",
                                      "DECEASED",
                                      "BIOMETRIC_NO_MATCH",
                                      "BIOMETRIC_IMAGE_UNUSABLE",
                                      "INCONCLUSIVE",
                                      "DOCUMENT_SUPERSEDED",
                                      "REGISTRY_UNAVAILABLE",
                                      "REGISTRY_ERROR"
                                    ],
                                    "description": "등록부 조회의 벤더 중립적 결과입니다. `MATCH`/`PARTIAL_MATCH`/`NO_MATCH`는 비교 결과를 나타냅니다. `DOCUMENT_NOT_FOUND`는 식별자가 등록부에 없음을 의미합니다. `INCONCLUSIVE`는 등록소에서 어느 쪽으로도 확인할 수 없음을 의미합니다(검토로 라우팅됨 — 불일치가 아님). `BIOMETRIC_NO_MATCH`는 명확한 얼굴 불일치인 반면 `BIOMETRIC_IMAGE_UNUSABLE`은 기술적인 이미지 문제입니다(셀피 재촬영 필요). `DECEASED`/`MINOR_BLOCKED`는 등록소 정책에 따른 결과입니다. `DOCUMENT_SUPERSEDED`는 신원은 일치하지만 제출된 문서의 판본이 기록과 일치하지 않음(더 최신 판본이 발급됨)을 의미합니다. `INVALID_DOCUMENT_FORMAT`/`INVALID_INPUT`은 등록소 자체가 전송된 데이터를 거부했음을 의미합니다. `REGISTRY_UNAVAILABLE`/`REGISTRY_ERROR`는 상위 시스템 오류를 나타냅니다."
                                  },
                                  "outcome_detail": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "결과 코드를 뒷받침하는 원시 업스트림 상태 세부 정보(예: HTTP 또는 등기부 상태 코드)입니다."
                                  },
                                  "source_data": {
                                    "type": "object",
                                    "nullable": true,
                                    "description": "표준 필드 이름(`identification_number`, `first_name`, `last_name`, `date_of_birth` 및 등기부 고유 플래그)을 사용하여 정제 및 정규화된 등기부 기록 보기입니다. 이미지 필드가 있는 경우 사전 서명된 URL로 반환됩니다."
                                  }
                                }
                              }
                            },
                            {
                              "type": "object",
                              "additionalProperties": {
                                "type": "string",
                                "enum": [
                                  "full_match",
                                  "partial_match",
                                  "no_match"
                                ]
                              },
                              "description": "병합된 필드 수준 결과(무상태 `save_api_request=false` 형태)입니다."
                            }
                          ]
                        },
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "feature": {
                                "type": "string",
                                "description": "경고를 발생시킨 기능입니다."
                              },
                              "risk": {
                                "type": "string",
                                "description": "기계 판독 가능한 위험 식별자입니다."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "description": "가능한 경우 제공되는 경고의 추가 컨텍스트입니다."
                              },
                              "log_type": {
                                "type": "string",
                                "description": "`warning`, `information` 또는 `error` — 위험이 결과에 미친 영향입니다."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "사람이 읽을 수 있는 한 줄 요약입니다."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "사람이 읽을 수 있는 전체 설명입니다."
                              }
                            }
                          },
                          "description": "해당하는 경우 `DATABASE_VALIDATION_NO_MATCH` 또는 `DATABASE_VALIDATION_PARTIAL_MATCH`, 완전히 일치하는 경우 비어 있음."
                        },
                        "errors": {
                          "type": "array",
                          "description": "선택한 서비스 중 일부(전체는 아님)가 실패한 경우에만 표시됩니다. 각 항목에는 `service_id`, `code`, `message`, `retryable`이 포함됩니다. 여기에 보고된 서비스는 `validations` 및 `services_used`에서 제외되며 결제되지 않습니다. 이 배열이 해당 서비스가 표시되는 유일한 위치이므로 `status`가 `Approved`인 경우에도 확인하십시오.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "service_id": {
                                "type": "string"
                              },
                              "code": {
                                "type": "string",
                                "example": "empty_provider_response"
                              },
                              "message": {
                                "type": "string"
                              },
                              "retryable": {
                                "type": "boolean",
                                "description": "서비스에서 응답을 생성하지 못하여 나중에 재시도하면 성공할 수 있는 경우 `true`입니다. 소스가 전송받은 데이터를 거부하여 입력을 먼저 수정해야 하는 경우에는 `false`입니다.",
                                "example": true
                              }
                            }
                          }
                        },
                        "services_used": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "청구 가능한 결과를 반환한 서비스의 카탈로그 id 목록. **요청에서 `services`를 명시적으로 보낸 경우에만 표시됩니다.**"
                        },
                        "match_score": {
                          "type": "number",
                          "description": "전체 일치(식별 번호, 성명 + 생년월일 조합 또는 모순 없는 주소 기준)를 생성한 시도된 서비스의 비율(0.0–1.0)입니다. **요청 시 `services`를 명시적으로 전송한 경우에만 표시됩니다.**"
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "전송한 `vendor_data`의 에코 값입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "description": "전송한 `metadata`의 에코 값입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "Full match (Approved)": {
                    "summary": "기본값 save_api_request=true — 서비스별 `validations` 객체",
                    "value": {
                      "request_id": "7f9a1c0e-1f2b-4f6e-9d3a-2b1c0e7f9a1c",
                      "database_validation": {
                        "status": "Approved",
                        "issuing_state": "BRA",
                        "validation_type": "one_by_one",
                        "screened_data": {
                          "tax_number": "12345678900",
                          "first_name": "John",
                          "last_name": "Doe",
                          "date_of_birth": "1980-01-01"
                        },
                        "match_type": "full_match",
                        "validations": [
                          {
                            "validation": {
                              "full_name": "full_match",
                              "date_of_birth": "full_match",
                              "identification_number": "full_match"
                            },
                            "outcome_code": "MATCH",
                            "outcome_detail": "200",
                            "service_id": "bra_cpf",
                            "service_name": "Brazil - CPF status check",
                            "source_data": {
                              "identification_number": "12345678900",
                              "first_name": "JOHN",
                              "last_name": "DOE",
                              "date_of_birth": "1980-01-01",
                              "lgpd_minor": false,
                              "minor_under_16": false,
                              "minor_under_18": false
                            }
                          }
                        ],
                        "warnings": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:30:00.000000+00:00"
                    }
                  },
                  "Explicit services (extended shape)": {
                    "summary": "요청에서 `services` 전송됨 — 응답에 `services_used` 및 `match_score` 추가됨",
                    "value": {
                      "request_id": "b3e7c1a2-9d4f-4f0b-8a6c-5e2d1f0a9b3e",
                      "database_validation": {
                        "status": "Approved",
                        "issuing_state": "BRA",
                        "validation_type": "one_by_one",
                        "screened_data": {
                          "tax_number": "12345678900",
                          "first_name": "John",
                          "last_name": "Doe",
                          "date_of_birth": "1980-01-01"
                        },
                        "match_type": "full_match",
                        "validations": [
                          {
                            "validation": {
                              "full_name": "full_match",
                              "date_of_birth": "full_match",
                              "identification_number": "full_match"
                            },
                            "outcome_code": "MATCH",
                            "outcome_detail": "200",
                            "service_id": "bra_cpf",
                            "service_name": "Brazil - CPF status check",
                            "source_data": {
                              "identification_number": "12345678900",
                              "first_name": "JOHN",
                              "last_name": "DOE",
                              "date_of_birth": "1980-01-01",
                              "lgpd_minor": false,
                              "minor_under_16": false,
                              "minor_under_18": false
                            }
                          }
                        ],
                        "warnings": [],
                        "services_used": [
                          "bra_cpf"
                        ],
                        "match_score": 1.0
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:30:00.000000+00:00"
                    }
                  },
                  "No match (Declined)": {
                    "summary": "법인 등기부 기록이 일치하지 않음 — 기본값 `no_match_action=DECLINE`",
                    "value": {
                      "request_id": "0a1b2c3d-4e5f-6789-abcd-ef0123456789",
                      "database_validation": {
                        "status": "Declined",
                        "issuing_state": "BRA",
                        "validation_type": "one_by_one",
                        "screened_data": {
                          "tax_number": "12345678900",
                          "first_name": "John",
                          "last_name": "Doe",
                          "date_of_birth": "1980-01-01"
                        },
                        "match_type": "no_match",
                        "validations": [
                          {
                            "validation": {
                              "full_name": "no_match",
                              "date_of_birth": "no_match",
                              "identification_number": "no_match"
                            },
                            "outcome_code": "NO_MATCH",
                            "outcome_detail": "200",
                            "service_id": "bra_cpf",
                            "service_name": "Brazil - CPF status check",
                            "source_data": {
                              "identification_number": "00987654321",
                              "first_name": "TOTALLY",
                              "last_name": "DIFFERENT NAME",
                              "date_of_birth": "1999-01-01",
                              "lgpd_minor": false,
                              "minor_under_16": false,
                              "minor_under_18": false
                            }
                          }
                        ],
                        "warnings": [
                          {
                            "feature": "DATABASE_VALIDATION",
                            "risk": "DATABASE_VALIDATION_NO_MATCH",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Database validation no match",
                            "long_description": "The system identified a no match in the database validation, requiring further investigation."
                          }
                        ]
                      },
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-06-11T10:31:00.000000+00:00"
                    }
                  },
                  "Stateless (save_api_request=false)": {
                    "summary": "`validations`는 병합된 필드 맵으로 압축되며, 아무것도 저장되지 않습니다.",
                    "value": {
                      "request_id": "c4d5e6f7-8901-2345-6789-abcdef012345",
                      "database_validation": {
                        "status": "Approved",
                        "issuing_state": "BRA",
                        "validation_type": "one_by_one",
                        "screened_data": {
                          "tax_number": "12345678900",
                          "first_name": "John",
                          "last_name": "Doe",
                          "date_of_birth": "1980-01-01"
                        },
                        "match_type": "full_match",
                        "validations": {
                          "full_name": "full_match",
                          "date_of_birth": "full_match",
                          "identification_number": "full_match"
                        },
                        "warnings": []
                      },
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-06-11T10:32:00.000000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 오류 - 결제되지 않습니다. 외부 호출이 발생하기 전에 사전 점검(preflight) 필드 오류가 발생합니다. 응답하지 않은 모든 시도에서 입력을 명시적으로 거부하는 경우, 응답에는 대신 `code: provider_rejected_input` 및 `retryable: false`가 포함된 `validation_errors`가 포함됩니다. 다시 시도하기 전에 입력을 수정하십시오. 필드 수준 문제는 DRF의 표준 엔벨로프를 사용합니다. 카탈로그 문제는 `services` 배열(해당하는 경우 `requires_onboarding` 또는 `services_requiring_consent` 추가)을 반환합니다. 누락된 필드 오류에는 누락된 각 필드를 이를 요구하는 서비스에 매핑하는 `fields_required_by`가 포함됩니다. 하나 이상의 추가 식별자가 필요한 서비스(예: 이름만으로는 검증할 수 없는 `usa_states_credit_bureau`)는 각 서비스를 최소 하나 이상 존재해야 하는 필드에 매핑하는 `any_field_required_by`를 반환합니다. 서비스별로 확인된 형식 문제는 `invalid_fields_by_service`를 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid issuing_state": {
                    "summary": "지원되지 않는 국가 — 메시지에 모든 유효한 alpha-3 코드가 나열됩니다",
                    "value": {
                      "error": [
                        "Invalid issuing state. Valid options are: ARE, ARG, AUS, AUT, BEL, BGD, BOL, BRA, CAN, CHE, CHL, CHN, CIV, COL, CRI, CZE, DEU, DNK, DOM, ECU, ESP, FIN, FRA, GBR, GHA, GLB, GRC, GTM, HKG, HND, IDN, IND, IRL, ITA, KEN, KHM, MAR, MEX, MYS, NGA, NLD, NOR, NZL, OMN, PAN, PER, PHL, POL, PRT, PRY, QAT, SGP, SLV, SVK, SWE, THA, UGA, URY, USA, VEN, ZAF, ZMB, ZWE"
                      ]
                    }
                  },
                  "Missing required fields": {
                    "summary": "선택한 서비스 전반의 필수 필드 합집합(범용 필드 힌트 포함)",
                    "value": {
                      "error": [
                        "Missing required fields: tax_number (or use 'identification_number' which maps to 'tax_number' for BRA)"
                      ],
                      "fields_required_by": {
                        "tax_number": [
                          "bra_cpf"
                        ]
                      }
                    }
                  },
                  "Unknown service id": {
                    "summary": "`services`에 카탈로그에 없는 ID가 포함되어 있음",
                    "value": {
                      "services": [
                        "Unknown service_id(s): ['bogus_service']"
                      ]
                    }
                  },
                  "Service not live for country": {
                    "summary": "`services`에 다른 국가의 서비스(또는 스텁 항목)가 지정되어 있음",
                    "value": {
                      "services": [
                        "Services not currently live for PER: ['bra_cpf']. Available services: ['per_dni', 'per_residential', 'per_tax_registration']"
                      ]
                    }
                  },
                  "Service requires onboarding": {
                    "summary": "서비스가 존재하지만 조직에 아직 활성화되지 않았습니다",
                    "value": {
                      "services": [
                        "Services require onboarding before they can be enabled for AUS: ['aus_australia_driver_licence']. Contact Didit support to activate them."
                      ],
                      "requires_onboarding": [
                        "aus_australia_driver_licence"
                      ]
                    }
                  },
                  "Consent missing": {
                    "summary": "선택한 서비스에 requires_consent=true 플래그가 지정되어 있으나 `consent`가 `true`가 아닙니다.",
                    "value": {
                      "consent": [
                        "Explicit end-user consent is required for these database validation services: ['chn_national_id']. Send `consent=true`."
                      ],
                      "services_requiring_consent": [
                        "chn_national_id"
                      ]
                    }
                  },
                  "Country format rule violation": {
                    "summary": "식별자가 해당 국가의 형식 규칙(길이/숫자/정규식)을 충족하지 못함",
                    "value": {
                      "tax_number": [
                        "Invalid tax number for BRA: Brazilian CPF (exactly 11 digits). Must be exactly 11 characters long (got 10)."
                      ]
                    }
                  },
                  "Service-specific format violation": {
                    "summary": "필드가 선택한 서비스 자체의 형식 요구사항을 충족하지 않습니다",
                    "value": {
                      "error": [
                        "One or more fields do not match the format required by the selected service."
                      ],
                      "invalid_fields_by_service": {
                        "chn_national_id": [
                          "national_id_format"
                        ]
                      }
                    }
                  },
                  "Input refused by every attempt": {
                    "summary": "재시도하기 전에 입력을 수정하세요",
                    "value": {
                      "error": "The source refused to run this query with the supplied input.",
                      "validation_errors": [
                        {
                          "service_id": "bra_cpf",
                          "code": "provider_rejected_input",
                          "message": "The source refused to run this query with the supplied input.",
                          "retryable": false
                        }
                      ]
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "error": {
                      "description": "요청 수준의 설명 또는 사전 점검 필드 오류입니다.",
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      ]
                    },
                    "validation_errors": {
                      "type": "array",
                      "description": "응답되지 않은 모든 시도가 사전 검사 후 입력을 거부했을 때 표시됩니다.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "service_id": {
                            "type": "string"
                          },
                          "code": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "retryable": {
                            "type": "boolean",
                            "description": "나중에 재시도하여 이 서비스 장애를 해결할 수 있는지 여부입니다. False는 제공된 입력을 먼저 수정해야 함을 의미합니다."
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었거나 호출한 조직의 잔액이 호출 비용을 충당할 수 없을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 키가 누락된 경우 `{\"detail\": ...}`과 함께 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 크레딧이 부족한 경우 어떠한 스크리닝이나 제공업체 호출도 진행되기 전에 `{\"error\": ...}`과 함께 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 호출 비용을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "선택한 서비스 중 사용 가능한 결과를 반환한 서비스가 없습니다. 재시도하기 전에 각 validation_errors 항목을 확인하십시오. HTTP 502만으로는 일시적 장애 여부를 판단할 수 없습니다. retryable: true인 empty_provider_response는 기본 제공자 거부 후 대체 제공자 사용 불가 등 사용 불가하거나 설명되지 않은 결과를 나타냅니다. 레거시 provider_invalid_input 및 provider_validation_error 항목은 대신 수정된 입력이 필요하며 retryable이 생략될 수 있습니다. 청구되는 금액은 없습니다. save_api_request=true인 경우, 실패한 시도는 상태가 Not Finished인 세션으로 기록됩니다. 부분 실패는 database_validation.errors와 함께 200을 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validation_errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "service_id": {
                            "type": "string"
                          },
                          "code": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "retryable": {
                            "type": "boolean",
                            "description": "나중에 재시도하여 이 서비스 장애를 해결할 수 있는지 여부입니다. False는 제공된 입력을 먼저 수정해야 함을 의미합니다."
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Provider returned no result": {
                    "summary": "선택한 모든 서비스 실패",
                    "value": {
                      "error": "Database validation could not be performed. The external validation service did not return a result. Please try again later.",
                      "validation_errors": [
                        {
                          "service_id": "bra_cpf",
                          "code": "empty_provider_response",
                          "message": "The provider did not return a database validation result.",
                          "retryable": true
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/phone/send/": {
      "post": {
        "summary": "전화번호 코드 전송",
        "description": "WhatsApp, SMS 또는 기타 지원되는 채널을 통해 전화번호로 일회용 비밀번호(OTP)를 전송한 후, [`POST /v3/phone/check/`](/ko/standalone-apis/phone-check)를 호출하여 이를 검증합니다.\n\n**전송 및 확인 작동 방식.** 인증 상태는 애플리케이션과 E.164 형식의 `phone_number`를 키로 식별됩니다. 확인 호출에는 `request_id`가 사용되지 않습니다. 새로 전송할 때마다 **5분** 동안 유효한 대기 중인 인증이 생성됩니다. 유효 시간이 만료되기 전에 동일한 번호와 사용자가 수신한 코드로 확인 호출을 실행하세요. 인증이 대기 중인 상태에서 동일한 번호로 전송을 다시 호출하면 해당 인증에 대한 코드가 재전송됩니다(`status: \"Retry\"`, 동일한 `request_id`). 이러한 재시도는 최대 1회까지 연결되며(총 2회 전송), 추가로 전송하면 새 `request_id`로 새로운 인증이 시작됩니다. 5분의 유효 시간은 최초 전송 시점부터 측정되며 재시도로 인해 연장되지 않습니다.\n\n**전송 채널.** `options.preferred_channel`로 채널을 선택합니다(기본값은 `whatsapp`이며, `sms`, `telegram`, `voice`, `rcs`, `viber`, `zalo`도 지원됨). 수신 국가 또는 번호에서 기본 설정 채널을 사용할 수 없는 경우 전송은 자동으로 SMS로 대체됩니다. 이때 전송은 여전히 `Success`를 반환하며, 실제로 사용된 채널은 확인 응답(`phone.verification_method` 및 `lifecycle` 이벤트)에 보고됩니다.\n\n**브랜딩.** SMS 코드는 추가 비용 없이 Business Console에서 설정한 애플리케이션의 SMS 발신자 이름을 사용합니다. 특정 코드에 다른 발신자 이름을 표시하려면 `options.sms_sender_name`을 전달하거나, 발신자 이름이 설정되지 않았을 때 화이트 라벨 공개 이름으로 대체하려면 `options.use_white_label_customization: true`를 전달하세요. WhatsApp 코드는 고정된 메시지를 사용합니다. Business Console에서 자체 WhatsApp Business 번호를 연결하면 비즈니스 이름과 번호로 코드를 전송할 수 있으며, Didit 수수료만 청구됩니다.\n\n**전송 상태.** `Success` — 새 인증을 위해 OTP가 전송됨, `Retry` — 대기 중인 인증을 위해 OTP가 재전송됨, `Blocked` — 부정행위 방지 계층에서 전송을 거부함(`reason` 참조. 예: `repeated_attempts`, `suspicious`, `spam`). `Blocked` 전송은 고위험 경고와 함께 인증을 즉시 `Declined`로 완료하므로, 후속 확인 호출 시 `Expired or Not Found`가 반환됩니다.\n\n**결제.** 가격은 수신 국가와 메시지를 실제로 전송한 채널에 따라 달라집니다([전화번호 인증 요금](/ko/getting-started/phone-verification-pricing) 참조). `Blocked` 전송만 무료가 보장됩니다. 그 외 청구되지 않은 모든 전송 시도는 전송이 확인되지 않았거나 전송 제공업체에서 메시지 전송 불가로 보고한 경우라도 인증 완료 또는 만료 시점에 요금이 부과됩니다. 확인 호출은 항상 무료입니다. 악용 방지 조치로, 조직의 첫 충전이 완료될 때까지 전화번호 인증이 비활성화됩니다(`403`).\n\n**세션 지속성.** 모든 새 인증은 API 유형 세션으로 저장됩니다. `request_id`는 `GET /v3/session/{sessionId}/decision/`에 전달할 수 있는 실제 세션 ID이며, 해당 인증은 Business Console에 표시되고 진행 상황에 따라 `status.updated` webhook이 트리거됩니다.\n\n**샌드박스.** 샌드박스 API 키는 전송 및 결제를 건너뜁니다. 요청 검증(형식이 잘못된 입력은 여전히 `400` 반환) 후 endpoint는 임의의 `request_id`가 포함된 정적 `Success` payload를 반환합니다. 메시지는 전송되지 않으며 어떤 데이터도 저장되지 않습니다. 샌드박스 확인 시에는 코드 `123456`을 사용하세요.\n\n**인증.** `x-api-key` 헤더에 애플리케이션의 API 키를 전송하세요. 자격 증명이 누락되었거나 유효하지 않으면 `403`(`{\"detail\": \"You do not have permission to perform this action.\"}`)이 반환됩니다. 이 API는 `401`을 반환하지 않습니다.\n\n**속도 제한.** 모든 POST/PATCH/DELETE endpoint에 걸쳐 API 키당 분당 300회의 공유 쓰기 요청 한도가 적용되며, 추가로 전화번호당 시간당 4회의 악용 방지 전송 한도가 적용됩니다. 둘 중 하나라도 초과하면 `429`가 반환됩니다.",
        "operationId": "post_v3phone_send",
        "x-didit-sdk": {
          "resource": "phone",
          "method": "send_code",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/phone/send/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"phone_number\": \"+14155552671\",\n    \"options\": {\n      \"code_size\": 6,\n      \"preferred_channel\": \"whatsapp\",\n      \"locale\": \"en-US\"\n    },\n    \"vendor_data\": \"user-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.phone.send_code(\n    phone_number=\"+14155552671\",\n    options={\n        \"locale\": \"en-US\",\n        \"preferred_channel\": \"whatsapp\",\n    },\n    vendor_data=\"user-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.phone.sendCode({\n  phone_number: \"+14155552671\",\n  options: {\n    locale: \"en-US\",\n    preferred_channel: \"whatsapp\",\n  },\n  vendor_data: \"user-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Phone.SendCode(ctx, didit.PhoneSendCodeParams{\n\tPhoneNumber: \"+14155552671\",\n\tOptions: didit.Some(didit.PhoneSendCodeParamsOptions{\n\t\tLocale:           didit.String(\"en-US\"),\n\t\tPreferredChannel: didit.Some(didit.PhoneSendCodeParamsOptionsPreferredChannel(\"whatsapp\")),\n\t}),\n\tVendorData: didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.PhoneSendCodeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.phone().sendCode(PhoneSendCodeParams.builder()\n        .phoneNumber(\"+14155552671\")\n        .options(PhoneSendCodeParams.Options.builder()\n                .locale(\"en-US\")\n                .preferredChannel(PhoneSendCodeParams.Options.PreferredChannel.of(\"whatsapp\"))\n                .build())\n        .vendorData(\"user-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->phone->sendCode([\n    'phone_number' => '+14155552671',\n    'options' => [\n        'locale' => 'en-US',\n        'preferred_channel' => 'whatsapp',\n    ],\n    'vendor_data' => 'user-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.phone.send_code(\n  phone_number: \"+14155552671\",\n  options: {\n    locale: \"en-US\",\n    preferred_channel: \"whatsapp\",\n  },\n  vendor_data: \"user-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Phone.SendCodeAsync(new PhoneSendCodeParams\n{\n    PhoneNumber = \"+14155552671\",\n    Options = new PhoneSendCodeParamsOptions\n    {\n        Locale = \"en-US\",\n        PreferredChannel = new PhoneSendCodeParamsOptionsPreferredChannel(\"whatsapp\"),\n    },\n    VendorData = \"user-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "phone_number": {
                    "type": "string",
                    "maxLength": 20,
                    "description": "E.164 형식의 수취인 전화번호입니다. 앞자리에 `+`와 국가 코드가 포함됩니다(예: `+14155552671`). 번호는 검증 후 E.164 형식으로 정규화되며, 구문 분석할 수 없거나 유효하지 않은 번호는 `phone_number` 필드 오류와 함께 `400`을 반환합니다.",
                    "example": "+14155552671"
                  },
                  "options": {
                    "type": "object",
                    "description": "OTP 전송 옵션입니다. 모든 필드는 선택 사항입니다.",
                    "properties": {
                      "code_size": {
                        "type": "integer",
                        "minimum": 4,
                        "maximum": 8,
                        "default": 6,
                        "description": "OTP의 자릿수입니다."
                      },
                      "locale": {
                        "type": "string",
                        "maxLength": 5,
                        "pattern": "^[a-z]{2,3}(-[A-Z]{2,3})?$",
                        "description": "인증 메시지를 현지화하는 데 사용되는 BCP-47 로캘입니다(예: `en-US`, `fr`, `es`). 잘못된 형식은 `400`을 반환합니다.",
                        "example": "en-US"
                      },
                      "preferred_channel": {
                        "type": "string",
                        "enum": [
                          "whatsapp",
                          "sms",
                          "telegram",
                          "voice",
                          "rcs",
                          "viber",
                          "zalo"
                        ],
                        "default": "whatsapp",
                        "description": "선호하는 전송 채널입니다. 대상 국가 또는 번호에서 해당 채널을 사용할 수 없는 경우 메시지는 자동으로 SMS로 대체되며, 발송은 계속 `Success`로 보고됩니다."
                      },
                      "use_white_label_customization": {
                        "type": "boolean",
                        "default": false,
                        "description": "When `true`, the send is white-labelled: if your application has no SMS sender name, the SMS names your white-label public name instead (\"Acme Bank의 인증 코드는 123456입니다\"). Your SMS sender name, when set, is used with or without this flag. Applies to SMS messages, including an SMS fallback from another channel; WhatsApp codes are sent with a fixed message and are not branded. Defaults to `false`."
                      },
                      "sms_sender_name": {
                        "type": "string",
                        "nullable": true,
                        "maxLength": 30,
                        "example": "Acme Bank",
                        "description": "애플리케이션의 SMS 발신자 이름 대신 이 코드의 SMS에 표시되는 이름(\"123456 is your verification code for Acme Bank\")입니다. 무료입니다. 1~30자: 문자, 숫자, 공백 및 ' & - !만 허용되며, 숫자로만 구성될 수 없고, 단어 사이에 단일 공백만 허용됩니다. 그 외의 값은 `400`을 반환하며 코드가 전송되지 않습니다. 생략되거나 `null` 또는 빈 값인 경우 애플리케이션의 SMS 발신자 이름이 사용됩니다. 각 애플리케이션은 하루(UTC)에 최대 2개의 새 이름을 사용하기 시작할 수 있으며, 이를 초과하면 애플리케이션 이름으로 코드가 전송됩니다. 다른 채널의 SMS 폴백을 포함한 SMS 메시지에 적용되며, WhatsApp 코드는 브랜드가 지정되지 않습니다.",
                        "pattern": "^$|^(?![\\d ]+$)[\\p{L}\\p{N}'&!-]+( [\\p{L}\\p{N}'&!-]+)*$"
                      }
                    }
                  },
                  "signals": {
                    "type": "object",
                    "description": "최종 사용자에 대한 선택적 기기 및 네트워크 신호로, 어뷰징 또는 자동화된 트래픽 감지를 개선하기 위해 사기 방지 계층으로 전달됩니다. 모든 필드는 선택 사항입니다.",
                    "properties": {
                      "ip": {
                        "type": "string",
                        "description": "최종 사용자 기기의 주소입니다. IPv4 또는 IPv6입니다.",
                        "example": "192.0.2.1"
                      },
                      "device_id": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "최종 사용자 기기의 고유 식별자입니다. Android: `ANDROID_ID`, iOS: `identifierForVendor`.",
                        "example": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2"
                      },
                      "device_platform": {
                        "type": "string",
                        "enum": [
                          "android",
                          "ios",
                          "ipados",
                          "tvos",
                          "web"
                        ],
                        "description": "최종 사용자 기기의 플랫폼입니다."
                      },
                      "device_model": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "최종 사용자 기기의 모델입니다.",
                        "example": "iPhone17,2"
                      },
                      "os_version": {
                        "type": "string",
                        "maxLength": 64,
                        "description": "최종 사용자 기기의 운영체제 버전입니다.",
                        "example": "18.0.1"
                      },
                      "app_version": {
                        "type": "string",
                        "maxLength": 64,
                        "description": "애플리케이션의 버전입니다.",
                        "example": "1.2.34"
                      },
                      "user_agent": {
                        "type": "string",
                        "maxLength": 512,
                        "description": "최종 사용자의 브라우저 또는 앱의 사용자 에이전트입니다.",
                        "example": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1"
                      }
                    }
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "세션에 유지되고 전송 응답, 일치 확인 응답, webhook 및 Business Console에 그대로 반환되는 선택적 호출자 제어 식별자(내부 사용자 ID, 이메일, UUID 등)입니다. Didit의 `request_id`를 사용자 레코드와 연결하는 데 사용하십시오."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "세션에 유지되고 전송 응답, 일치 확인 응답, webhook 및 Business Console에 다시 반환되는 선택적 자유 형식 JSON 객체입니다."
                  }
                },
                "required": [
                  "phone_number"
                ]
              },
              "examples": {
                "WhatsApp (default)": {
                  "summary": "WhatsApp을 통한 6자리 OTP(SMS로 자동 대체)",
                  "value": {
                    "phone_number": "+14155552671",
                    "options": {
                      "preferred_channel": "whatsapp",
                      "locale": "en-US"
                    },
                    "vendor_data": "user-1234"
                  }
                },
                "SMS with custom code length": {
                  "summary": "4자리 코드로 SMS 전송 강제",
                  "value": {
                    "phone_number": "+34699999999",
                    "options": {
                      "preferred_channel": "sms",
                      "code_size": 4,
                      "locale": "es"
                    }
                  }
                },
                "With fraud signals": {
                  "summary": "기기 신호를 전달하여 사기 방지 스크리닝을 강화합니다.",
                  "value": {
                    "phone_number": "+14155552671",
                    "signals": {
                      "ip": "192.0.2.1",
                      "device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2",
                      "device_platform": "ios",
                      "device_model": "iPhone17,2",
                      "os_version": "18.0.1",
                      "app_version": "1.2.34"
                    },
                    "vendor_data": "user-1234"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "전송이 확인되었습니다. `status`를 확인하십시오. `Success` 및 `Retry`는 코드가 발송 중임을 의미하며, `Blocked`는 사기 방지 계층에서 거부되어 인증이 이미 `Declined`로 완료되었음을 의미합니다. `request_id`는 유지되는 세션 ID입니다(`Retry` 시 동일한 ID).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneVerificationSendResponse"
                },
                "examples": {
                  "Success": {
                    "summary": "새 인증을 위해 전송된 OTP",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Success",
                      "reason": null,
                      "vendor_data": "user-1234",
                      "metadata": null
                    }
                  },
                  "Retry": {
                    "summary": "5분 기간 내 동일한 번호로 두 번째 발송 — 동일한 request_id",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Retry",
                      "reason": null,
                      "vendor_data": "user-1234",
                      "metadata": null
                    }
                  },
                  "Blocked": {
                    "summary": "사기 방지로 거부됨 — 인증이 '거부됨' 상태로 종료되었으며, 청구되지 않음",
                    "value": {
                      "request_id": "0d8af1f4-0c43-46d7-b75c-6e4e22c0a7b3",
                      "status": "Blocked",
                      "reason": "repeated_attempts",
                      "vendor_data": "user-1234",
                      "metadata": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 형식이 잘못된 입력은 DRF의 필드 오류 봉투(문제가 있는 필드당 메시지 배열 1개, 옵션 오류의 경우 `options` 아래에 중첩됨)를 반환합니다. 파싱은 되지만 전송 시점에 거부된 번호(도달할 수 없거나 단축 코드 등 자격이 없는 회선 유형)는 대신 `{\"detail\": ...}` 봉투를 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid phone number (field error)": {
                    "summary": "유효한 E.164 번호가 아닙니다",
                    "value": {
                      "phone_number": [
                        "Invalid phone number provided."
                      ]
                    }
                  },
                  "Missing phone number": {
                    "summary": "body에 `phone_number`가 포함되지 않음",
                    "value": {
                      "phone_number": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid options": {
                    "summary": "범위를 벗어난 `code_size`, 잘못된 형식의 `locale`, 알 수 없는 `preferred_channel`",
                    "value": {
                      "options": {
                        "code_size": [
                          "Ensure this value is less than or equal to 8."
                        ],
                        "locale": [
                          "Ensure this field has no more than 5 characters."
                        ],
                        "preferred_channel": [
                          "\"carrier_pigeon\" is not a valid choice."
                        ]
                      }
                    }
                  },
                  "Number rejected at send time": {
                    "summary": "유효한 E.164 형식이지만 해당 번호로 OTP를 수신할 수 없습니다.",
                    "value": {
                      "detail": "Invalid phone number provided."
                    }
                  },
                  "Ineligible line type": {
                    "summary": "회선 유형이 OTP를 수신할 수 없음(예: 단축 번호)",
                    "value": {
                      "detail": "Invalid phone line type provided."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었을 때 반환됩니다(`{\"detail\": ...}`). 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 또한 발송 전에 조직이 충전한 적이 없거나(어뷰징 방지 게이트) 잔액이 대상의 발송 가격을 충당할 수 없을 때도 반환됩니다(`{\"error\": ...}`).",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Top-up required": {
                    "summary": "조직의 첫 충전 전까지 전화번호 인증이 비활성화 상태로 유지됨",
                    "value": {
                      "detail": "To protect against abuse, phone verification is disabled until your first top-up."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 전송 가격을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 또한 상위 시스템에서 전화번호당 시간당 4회의 인증 시도로 어뷰징 방지 상한이 적용됩니다. 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다. 참고: `X-RateLimit-*`/`Retry-After` 헤더는 분당 300회 쓰기 제한으로 인한 429 응답에만 함께 제공되며, 번호당 상한으로 인한 429 응답에는 속도 제한 헤더가 포함되지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Per-number cap": {
                    "summary": "지난 1시간 동안 동일한 번호로 4회를 초과하는 인증 시도 발생",
                    "value": {
                      "detail": "Maximum verification attempts reached for this phone number. Only 4 authentication attempts are allowed per hour. Try again later or use a different number."
                    }
                  },
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "전화번호 인증 공급자를 일시적으로 사용할 수 없습니다(5xx 응답, 시간 초과 또는 내장 재시도 후에도 지속된 연결 실패). 다시 시도해도 안전하며, 비용이 청구되지 않고 시도 횟수도 차감되지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Provider outage": {
                    "summary": "공급자가 발송 요청에 응답하지 않았습니다",
                    "value": {
                      "detail": "Phone verification is temporarily unavailable. Please try again shortly.",
                      "code": "phone_provider_unavailable"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "알려진 제공업체 중단이 아닌 인증 생성 중 예기치 않은 오류가 발생했습니다. 안전하게 재시도할 수 있습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Provider error": {
                    "summary": "OTP 전송을 시작할 수 없습니다",
                    "value": {
                      "detail": "Error creating phone verification"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/phone/check/": {
      "post": {
        "summary": "전화번호 코드 확인",
        "description": "[`POST /v3/phone/send/`](/ko/standalone-apis/phone-send)로 전송된 OTP를 검증하고 최종 인증 결과와 전화번호 인텔리전스(통신사명 및 회선 유형, 가상(VoIP) 및 일회용 플래그, 세션 전반에서 해당 번호의 중복 사용 여부)를 가져옵니다.\n\n**확인이 인증을 찾는 방식.** 매칭은 애플리케이션 및 E.164 `phone_number`를 기반으로 이루어지며, `request_id`는 입력값이 아닙니다. 최근 **5분** 이내에 생성된 가장 최근의 대기 중인 인증이 확인됩니다. 해당하는 인증이 없는 경우(전송된 적 없음, 이미 완료됨 또는 5분 초과) endpoint는 `200`과 함께 `status: \"Expired or Not Found\"`를 반환합니다.\n\n**시도 한도.** 각 인증당 **3회의 코드 시도**가 허용됩니다. 처음 두 번 잘못된 코드를 입력하면 남은 시도 횟수 및 `phone: null`과 함께 `status: \"Failed\"`가 반환됩니다. 세 번째로 잘못된 코드를 입력하면 `VERIFICATION_CODE_ATTEMPTS_EXCEEDED` 경고와 함께 인증이 `Declined`로 최종 확정되며 전체 전화번호 보고서가 반환됩니다.\n\n**결과.** `Approved` — 올바른 코드이며 거부 위험 없음. `Declined` — 최종 확정: 코드는 올바르지만 거부 위험이 일치함(아래의 `DECLINE` 작업, 차단 목록에 등록되었거나 고위험 번호), 또는 시도 한도가 소진됨. `Failed` — 잘못된 코드이며 잔여 시도 횟수가 있음. `Expired or Not Found` — 확인할 항목 없음. `Approved`/`Declined`의 경우 `request_id`는 전송 시의 `request_id`(세션 ID)와 동일하며 `phone`에 전체 보고서(`carrier`, `is_virtual`, `is_disposable`, `warnings`, `lifecycle`, `matches`)가 포함됩니다. `Failed` 및 `Expired or Not Found`의 경우 `request_id`는 일회성 임의 UUID입니다.\n\n**위험 작업.** `duplicated_phone_number_action`, `disposable_number_action`, `voip_number_action`은 올바른 코드 입력 시 해당 위험이 감지되었을 때 수행할 작업을 결정합니다. `DECLINE`은 최종 상태를 `Declined`로 변경합니다. `NO_ACTION`(기본값)은 상태에 영향을 주지 않고 `phone.warnings`에 위험을 기록합니다.\n\n**결제.** 확인은 무료이며, 전송 측에서 전송에 대해 요금이 청구됩니다([전화번호 인증 요금](/ko/getting-started/phone-verification-pricing) 참조).\n\n**세션 영속성.** 완료된 확인은 전송 시 생성된 세션을 업데이트하고(Business Console에서 확인 가능, `GET /v3/session/{sessionId}/decision/`을 통해 조회 가능) `status.updated` webhook을 트리거합니다.\n\n**샌드박스.** 샌드박스 API 키는 모든 처리를 건너뜁니다. 올바른 형식의 코드(`123456`을 포함한 4~8자리 숫자)는 간소화된 평면 `phone` 객체(`status`, `phone_number`, `country_code`, `carrier_name`, `line_type`, `flags`)가 포함된 정적 `Approved` payload를 반환합니다. 형식이 잘못된 입력은 여전히 `400`을 반환합니다. 어떤 항목도 영구 저장되지 않습니다.\n\n**인증.** `x-api-key` 헤더에 애플리케이션의 API 키를 전송하십시오. 자격 증명이 누락되었거나 유효하지 않으면 `403`(`{\"detail\": \"You do not have permission to perform this action.\"}`)이 반환됩니다. 이 API는 `401`을 절대 반환하지 않습니다.\n\n**속도 제한.** API 키당 분당 300개 요청의 쓰기 한도가 공유되며, 번호당 시간당 4회 시도의 업스트림 어뷰징 방지 한도가 추가로 적용됩니다. 둘 중 하나라도 초과하면 `429`가 반환됩니다.\n\n**소셜 풋프린트.** `enable_social`을 `true`로 설정하면 `phone_social` 블록이 추가됩니다. 여기에는 해당 번호가 등록된 온라인 플랫폼 목록, 카테고리별 건수 및 제공되는 프로필 세부 정보가 포함됩니다. `profiles_registered: 0`은 플랫폼을 확인했으나 해당 번호가 어떤 플랫폼에서도 발견되지 않았음을 의미하며, 이는 유효하고 요금이 청구되는 응답입니다. 부가 기능을 요청하지 않았거나 확인을 완료할 수 없는 경우에는 해당 블록이 표시되지 않으며 요금도 청구되지 않습니다. 결제 시 이 endpoint 자체 가격에 요청당 `phone_social` 1단위가 추가됩니다.",
        "operationId": "post_v3phone_check",
        "x-didit-sdk": {
          "resource": "phone",
          "method": "check_code",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/phone/check/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"phone_number\": \"+14155552671\",\n    \"code\": \"123456\",\n    \"voip_number_action\": \"DECLINE\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.phone.check_code(\n    phone_number=\"+14155552671\",\n    code=\"123456\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.phone.checkCode({\n  phone_number: \"+14155552671\",\n  code: \"123456\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Phone.CheckCode(ctx, didit.PhoneCheckCodeParams{\n\tPhoneNumber: \"+14155552671\",\n\tCode:        \"123456\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.PhoneCheckCodeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.phone().checkCode(PhoneCheckCodeParams.builder()\n        .phoneNumber(\"+14155552671\")\n        .code(\"123456\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->phone->checkCode([\n    'phone_number' => '+14155552671',\n    'code' => '123456',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.phone.check_code(\n  phone_number: \"+14155552671\",\n  code: \"123456\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Phone.CheckCodeAsync(new PhoneCheckCodeParams\n{\n    PhoneNumber = \"+14155552671\",\n    Code = \"123456\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "phone_number": {
                    "type": "string",
                    "maxLength": 20,
                    "description": "일치하는 [`POST /v3/phone/send/`](/ko/standalone-apis/phone-send) 호출에 사용된 것과 동일한 E.164 형식의 전화번호입니다. 이를 통해 검증과 전송이 연결됩니다.",
                    "example": "+14155552671"
                  },
                  "code": {
                    "type": "string",
                    "minLength": 4,
                    "maxLength": 8,
                    "pattern": "^[0-9]{4,8}$",
                    "description": "최종 사용자가 수신한 OTP입니다. 4~8자리 숫자여야 하며, 그 외의 경우 시도 횟수를 차감하지 않고 `400`을 반환합니다. 형식은 올바르지만 잘못된 코드는 `200`과 함께 `status: \"Failed\"`를 반환하고 3회의 시도 횟수 중 1회를 소진합니다.",
                    "example": "123456"
                  },
                  "duplicated_phone_number_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "동일한 번호가 애플리케이션의 다른 사용자(다른 `vendor_data`)에 의해 이미 사용되었을 때 수행할 작업입니다. `DECLINE`은 최종 `status`를 `Declined`로 변경하며, `NO_ACTION`은 위험을 `phone.warnings`에 기록하고 `phone.matches`를 채웁니다."
                  },
                  "disposable_number_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "통신사 조회를 통해 해당 번호가 일회용/임시 번호로 확인되었을 때(`phone.is_disposable`) 수행할 작업입니다. `DECLINE`은 최종 `status`를 `Declined`로 변경하고, `NO_ACTION`은 해당 위험을 `phone.warnings`에 기록합니다."
                  },
                  "voip_number_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "통신사 조회에서 `voip`, `isp` 또는 `vpn`과 같은 가상 회선 유형으로 보고되었을 때(`phone.is_virtual`) 수행할 작업입니다. `DECLINE`은 최종 `status`를 `Declined`로 변경하고, `NO_ACTION`은 해당 위험을 `phone.warnings`에 기록합니다."
                  },
                  "enable_enrichment": {
                    "type": "boolean",
                    "default": false,
                    "description": "`true`인 경우 해당 번호에 대한 전화번호 인텔리전스(위험 점수, 회선 유형, 최근 통신사 변경 여부 및 신뢰 지수)도 실행합니다. 이 endpoint의 자체 가격 외에 요청당 하나의 `phone_intelligence_api` 단위(정가 기준 $0.05)로 청구됩니다. 잔액이 이를 충당하지 못하면 요청은 `403`을 반환합니다.",
                    "example": false
                  },
                  "phone_intelligence_score_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "전화번호 인텔리전스 위험 점수가 임계값을 초과할 때 수행할 작업입니다. `DECLINE`은 최종 `status`를 `Declined`로 변경하며, `NO_ACTION`은 거부하지 않고 신호를 기록합니다. `enable_enrichment`가 `true`일 때만 적용됩니다."
                  },
                  "phone_type_risk_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "전화번호가 고위험 회선 유형일 때 수행할 작업입니다. `DECLINE`은 최종 `status`를 `Declined`로 변경하며, `NO_ACTION`은 거부하지 않고 신호를 기록합니다. `enable_enrichment`가 `true`일 때만 적용됩니다."
                  },
                  "recent_port_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "전화번호가 최근 다른 통신사로 번호 이동되었을 때 수행할 작업입니다. `DECLINE`은 최종 `status`를 `Declined`로 변경하며, `NO_ACTION`은 거부하지 않고 신호를 기록합니다. `enable_enrichment`가 `true`일 때만 적용됩니다."
                  },
                  "low_phone_trust_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "전화번호 인텔리전스 신뢰 지수가 임계값 이하일 때 수행할 작업입니다. `DECLINE`은 최종 `status`를 `Declined`로 변경하며, `NO_ACTION`은 거부하지 않고 신호를 기록합니다. `enable_enrichment`가 `true`일 때만 적용됩니다."
                  },
                  "enable_social": {
                    "type": "boolean",
                    "default": false,
                    "description": "true인 경우, 전화번호의 소셜 발자국(등록된 메시징, 소셜, 전자상거래 및 전문 플랫폼)도 조회합니다. 이 endpoint 자체의 가격 외에 요청당 `phone_social` 1단위로 청구됩니다.",
                    "example": true
                  },
                  "phone_no_social_presence_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "소셜 풋프린트 검사 결과 지원하는 플랫폼 중 어느 곳에도 해당 번호가 등록되어 있지 않을 때 수행할 작업입니다. 이 endpoint에서는 NO_ACTION 및 DECLINE만 허용되며, 동일한 이름의 워크플로 구성 키에서는 REVIEW를 사용할 수 있습니다."
                  }
                },
                "required": [
                  "phone_number",
                  "code"
                ]
              },
              "examples": {
                "Default": {
                  "summary": "모든 위험을 기록하지만 자동으로 거부하지는 않음",
                  "value": {
                    "phone_number": "+14155552671",
                    "code": "123456"
                  }
                },
                "Strict risk policy": {
                  "summary": "VoIP 및 일회용 전화번호 자동 거부",
                  "value": {
                    "phone_number": "+14155552671",
                    "code": "123456",
                    "voip_number_action": "DECLINE",
                    "disposable_number_action": "DECLINE"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "확인 완료 — 잘못된 코드 및 누락된 인증도 `200`을 반환하므로 HTTP 코드가 아닌 `status`를 확인하십시오. `phone`은 최종 결과(`Approved`/`Declined`)에서만 채워지며, `Failed`에서는 `null`, `Expired or Not Found`에서는 제외됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneVerificationCheckResponse"
                },
                "examples": {
                  "Approved": {
                    "summary": "올바른 코드 — 통신사, 라이프사이클 및 일치 항목이 포함된 전체 전화번호 보고서",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Approved",
                      "message": "The verification code is correct.",
                      "phone": {
                        "status": "Approved",
                        "phone_number_prefix": "+1",
                        "phone_number": "4155552671",
                        "full_number": "+14155552671",
                        "country_code": "US",
                        "country_name": "United States",
                        "carrier": {
                          "name": "AT&T",
                          "type": "mobile"
                        },
                        "is_disposable": false,
                        "is_virtual": false,
                        "verification_method": "whatsapp",
                        "verification_attempts": 1,
                        "verified_at": "2026-06-12T01:24:47.311323Z",
                        "warnings": [],
                        "lifecycle": [
                          {
                            "type": "PHONE_VERIFICATION_MESSAGE_SENT",
                            "timestamp": "2026-06-12T01:23:39.580554+00:00",
                            "details": {
                              "status": "Success",
                              "reason": null,
                              "channel": "whatsapp",
                              "actual_channel": "whatsapp"
                            },
                            "fee": 0.0509
                          },
                          {
                            "type": "PHONE_DELIVERY_DELIVERED",
                            "timestamp": "2026-06-12T01:23:43.118220+00:00",
                            "details": {
                              "channel": "whatsapp",
                              "status": "delivered"
                            },
                            "fee": 0
                          },
                          {
                            "type": "VALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:47.311201+00:00",
                            "details": {
                              "code_tried": "123456",
                              "status": "Approved"
                            },
                            "fee": 0
                          },
                          {
                            "type": "PHONE_VERIFICATION_APPROVED",
                            "timestamp": "2026-06-12T01:24:47.384292+00:00",
                            "details": null,
                            "fee": 0
                          }
                        ],
                        "matches": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.401719+00:00"
                    }
                  },
                  "Failed (attempts remaining)": {
                    "summary": "잘못된 코드 — 사용자가 재시도할 수 있습니다. 여기서 request_id는 일회용 UUID입니다.",
                    "value": {
                      "request_id": "11111111-2222-3333-4444-555555555555",
                      "status": "Failed",
                      "message": "The verification code is incorrect. Attempts remaining: 2",
                      "phone": null,
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:21.512340+00:00"
                    }
                  },
                  "Declined (max attempts)": {
                    "summary": "세 번째 잘못된 코드 — 인증이 거부됨으로 최종 처리됨",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Declined",
                      "message": "The verification code is incorrect. Maximum attempts reached.",
                      "phone": {
                        "status": "Declined",
                        "phone_number_prefix": "+1",
                        "phone_number": "4155552671",
                        "full_number": "+14155552671",
                        "country_code": "US",
                        "country_name": "United States",
                        "carrier": {
                          "name": "AT&T",
                          "type": "mobile"
                        },
                        "is_disposable": false,
                        "is_virtual": false,
                        "verification_method": "whatsapp",
                        "verification_attempts": 1,
                        "verified_at": null,
                        "warnings": [
                          {
                            "feature": "PHONE",
                            "risk": "VERIFICATION_CODE_ATTEMPTS_EXCEEDED",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Verification code attempts exceeded",
                            "long_description": "The system detected that the phone number has exceeded the maximum number of verification code attempts."
                          }
                        ],
                        "lifecycle": [
                          {
                            "type": "PHONE_VERIFICATION_MESSAGE_SENT",
                            "timestamp": "2026-06-12T01:23:39.580554+00:00",
                            "details": {
                              "status": "Success",
                              "reason": null,
                              "channel": "whatsapp",
                              "actual_channel": "whatsapp"
                            },
                            "fee": 0.0509
                          },
                          {
                            "type": "INVALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:01.118220+00:00",
                            "details": {
                              "code_tried": "111111",
                              "status": "Failed"
                            },
                            "fee": 0
                          },
                          {
                            "type": "INVALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:21.512340+00:00",
                            "details": {
                              "code_tried": "222222",
                              "status": "Failed"
                            },
                            "fee": 0
                          },
                          {
                            "type": "INVALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:47.311201+00:00",
                            "details": {
                              "code_tried": "333333",
                              "status": "Failed"
                            },
                            "fee": 0
                          },
                          {
                            "type": "PHONE_VERIFICATION_DECLINED",
                            "timestamp": "2026-06-12T01:24:47.384292+00:00",
                            "details": {
                              "reason": "VERIFICATION_CODE_ATTEMPTS_EXCEEDED"
                            },
                            "fee": 0
                          }
                        ],
                        "matches": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.401719+00:00"
                    }
                  },
                  "Declined (risk policy)": {
                    "summary": "올바른 코드이지만 VoIP 회선이며 voip_number_action=DECLINE으로 설정됨",
                    "value": {
                      "request_id": "7f1c9d2e-44a1-4b6e-9a3e-5b8e6f1c2d3a",
                      "status": "Declined",
                      "message": "The verification code is correct.",
                      "phone": {
                        "status": "Declined",
                        "phone_number_prefix": "+1",
                        "phone_number": "5005550006",
                        "full_number": "+15005550006",
                        "country_code": "US",
                        "country_name": "United States",
                        "carrier": {
                          "name": "CLEC LLC",
                          "type": "voip"
                        },
                        "is_disposable": false,
                        "is_virtual": true,
                        "verification_method": "sms",
                        "verification_attempts": 1,
                        "verified_at": "2026-06-12T01:24:47.311323Z",
                        "warnings": [
                          {
                            "feature": "PHONE",
                            "risk": "VOIP_NUMBER_DETECTED",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "VoIP number detected",
                            "long_description": "The system detected that the phone number is a VoIP number, which is not allowed."
                          }
                        ],
                        "lifecycle": [
                          {
                            "type": "PHONE_VERIFICATION_MESSAGE_SENT",
                            "timestamp": "2026-06-12T01:23:39.580554+00:00",
                            "details": {
                              "status": "Success",
                              "reason": null,
                              "channel": "whatsapp",
                              "actual_channel": "sms"
                            },
                            "fee": 0.0509
                          },
                          {
                            "type": "VALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:47.311201+00:00",
                            "details": {
                              "code_tried": "123456",
                              "status": "Approved"
                            },
                            "fee": 0
                          },
                          {
                            "type": "PHONE_VERIFICATION_DECLINED",
                            "timestamp": "2026-06-12T01:24:47.384292+00:00",
                            "details": {
                              "reason": "VOIP_NUMBER_DETECTED"
                            },
                            "fee": 0
                          }
                        ],
                        "matches": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.401719+00:00"
                    }
                  },
                  "Expired or Not Found": {
                    "summary": "최근 5분 이내에 이 번호에 대한 대기 중인 인증이 없습니다",
                    "value": {
                      "request_id": "69cc35c6-280a-47a6-ab8c-4f32abc02ed0",
                      "status": "Expired or Not Found",
                      "message": "No pending phone verification found in the last 5 minutes.",
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.311323+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 오류 — DRF의 필드 오류 엔벨로프: 문제가 있는 필드당 하나의 메시지 배열.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid code format": {
                    "summary": "`code`가 4~8자리 숫자가 아닙니다",
                    "value": {
                      "code": [
                        "Invalid code format. Enter 4 to 8 numeric digits."
                      ]
                    }
                  },
                  "Invalid phone number": {
                    "summary": "`phone_number`가 유효한 E.164 형식이 아님",
                    "value": {
                      "phone_number": [
                        "Invalid phone number provided."
                      ]
                    }
                  },
                  "Invalid action": {
                    "summary": "위험 작업에는 NO_ACTION 또는 DECLINE만 허용됩니다",
                    "value": {
                      "voip_number_action": [
                        "\"REVIEW\" is not a valid choice."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 확인은 무료이므로 크레딧 확인이 수행되지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 또한 상위 시스템에서 전화번호당 시간당 4회의 인증 시도로 어뷰징 방지 상한이 적용됩니다. 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다. 참고: `X-RateLimit-*`/`Retry-After` 헤더는 분당 300회 쓰기 제한으로 인한 429 응답에만 함께 제공되며, 번호당 상한으로 인한 429 응답에는 속도 제한 헤더가 포함되지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Per-number cap": {
                    "summary": "지난 1시간 동안 동일한 번호로 4회를 초과하는 인증 시도 발생",
                    "value": {
                      "detail": "Maximum verification attempts reached for this phone number. Only 4 authentication attempts are allowed per hour. Try again later or use a different number."
                    }
                  },
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "전화번호 인증 공급자를 일시적으로 사용할 수 없습니다(5xx 응답, 시간 초과 또는 내장 재시도 후에도 지속된 연결 실패). 다시 시도해도 안전하며, 시도 가능 횟수가 차감되지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Provider outage": {
                    "summary": "공급자가 확인 요청에 응답하지 않았습니다",
                    "value": {
                      "detail": "Phone verification is temporarily unavailable. Please try again shortly.",
                      "code": "phone_provider_unavailable"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "알려진 제공업체 중단이 아닌 업스트림 코드 검증 중 예기치 않은 오류가 발생했습니다. 안전하게 재시도할 수 있으며, 시도 횟수는 완료된 확인에 대해서만 차감됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Provider error": {
                    "summary": "코드 확인을 완료할 수 없습니다",
                    "value": {
                      "detail": "Error checking phone verification"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/bank/account-check/": {
      "post": {
        "summary": "은행 계좌 확인",
        "description": "자금을 송금하기 전에 은행 계좌가 지정한 개인 또는 기업의 소유인지 확인합니다. 세션이나 로그인이 필요하지 않습니다. 이름과 계좌를 전송하고 결과를 확인하면 됩니다. 백엔드에서 실행되는 은행 확인 단계의 [계좌 확인](/ko/core-technology/bank-verification/account-check)입니다.\n\n**전송하는 데이터.** 계좌의 `country`(ISO 3166-1 alpha-3), 해당 국가의 표기 방식에 따른 `account`, 그리고 `holder` 이름(개인의 경우 `full_name`, 기업의 경우 `business_name`)입니다. 기업 이름은 기업 계좌를 확인합니다.\n\n**반환되는 결과.** `result`는 `match`, `close_match`, `no_match` 또는 `cannot_verify`입니다. `close_match`의 경우 은행에서 반환했을 때 `holder_name`은 은행에 등록된 해당 계좌의 예금주명입니다. `account`는 마지막 4자리를 제외하고 마스킹되어 반환됩니다.\n\n**결제.** 은행이 응답한 각 확인은 결과와 관계없이 해당 계좌 국가의 계좌 확인 가격으로 1회 청구됩니다. `no_match`, 존재하지 않는 계좌, `cannot_verify`도 청구 대상입니다. 오류로 응답된 요청은 청구되지 않습니다.\n\n**모든 요청은 새로운 확인입니다.** 멱등성 키가 없으며 확인 내역을 다시 조회하는 endpoint도 없으므로, 재시도된 요청은 다시 실행되고 다시 청구됩니다. 응답을 저장하십시오.\n\n**샌드박스.** 샘플 계좌 세부 정보와 함께 샌드박스 API 키를 사용하십시오. 샌드박스 키는 은행을 호출하지 않으며 비용이 청구되지 않습니다. IBAN의 마지막 4자리(IBAN이 없으면 계좌 번호의 마지막 4자리)에 따라 응답이 결정됩니다. `0001`은 `holder_name`이 포함된 `close_match`, `0002`는 예금주명이 없는 `close_match`, `0003` 및 `0006`은 `no_match`, `0004`는 `cannot_verify`, `0005`는 `503`, `0009`는 `400`입니다. 그 외의 다른 끝자리는 `match`입니다.\n\n**API 키.** 스코프가 지정된 API 키에는 세션에 대한 쓰기 권한이 필요합니다.",
        "operationId": "post_v3_bank_account_check",
        "tags": [
          "Standalone APIs"
        ],
        "x-didit-sdk": {
          "resource": "bank",
          "method": "account_check",
          "auth": "api_key",
          "server": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BankAccountCheckRequest"
              },
              "examples": {
                "Person, Nigeria": {
                  "summary": "개인 성명과 대조 검증된 은행 코드 및 계좌번호",
                  "value": {
                    "country": "NGA",
                    "account": {
                      "bank_code": "000014",
                      "account_number": "0123450001"
                    },
                    "holder": {
                      "full_name": "Maria Oliveira"
                    },
                    "vendor_data": "payout_20481"
                  }
                },
                "Company, Nigeria": {
                  "summary": "기업명과 대조 검증된 은행 코드 및 계좌번호",
                  "value": {
                    "country": "NGA",
                    "account": {
                      "bank_code": "000014",
                      "account_number": "0123456789"
                    },
                    "holder": {
                      "business_name": "Northwind Trading Ltd"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "은행이 응답했습니다. 결과와 관계없이 확인 비용이 청구됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckResponse"
                },
                "examples": {
                  "Close match": {
                    "summary": "은행이 유사한 이름으로 계좌를 보유하고 있습니다",
                    "value": {
                      "request_id": "c2f4a9e0-7b1d-4c3a-9e55-1d0a6b8f2a47",
                      "result": "close_match",
                      "holder_name": "MARIA R OLIVEIRA",
                      "account": "****0001",
                      "vendor_data": "payout_20481",
                      "created_at": "2026-10-21T14:32:08Z"
                    }
                  },
                  "Match": {
                    "summary": "은행이 전송된 이름으로 계좌를 보유하고 있습니다",
                    "value": {
                      "request_id": "5b0e2d7c-41a8-4f6e-9c3b-8e7d1a2f6c90",
                      "result": "match",
                      "holder_name": null,
                      "account": "****6789",
                      "vendor_data": null,
                      "created_at": "2026-10-21T14:35:41Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "보낸 내용 그대로 거부되었으며 요금이 청구되지 않았습니다. `field`는 수정해야 할 본문 필드를 나타내고, `reason`은 호스팅 계정 양식에 표시되는 것과 동일한 이유를 설명합니다. 처음 거부된 필드만 보고됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckError"
                },
                "examples": {
                  "Missing field": {
                    "summary": "해당 국가의 확인에는 은행 코드가 필요합니다",
                    "value": {
                      "detail": "The bank code is not valid (required).",
                      "code": "invalid_account_input",
                      "field": "account.bank_code",
                      "reason": "required"
                    }
                  },
                  "Invalid IBAN": {
                    "summary": "해당 국가에 맞지 않는 IBAN 길이입니다",
                    "value": {
                      "detail": "The iban is not valid (length).",
                      "code": "invalid_account_input",
                      "field": "account.iban",
                      "reason": "length"
                    }
                  },
                  "Refused by the bank": {
                    "summary": "은행이 전송된 계좌를 거부했습니다",
                    "value": {
                      "detail": "The account was refused as typed (rejected).",
                      "code": "invalid_account_input",
                      "field": "account.account_number",
                      "reason": "rejected"
                    }
                  },
                  "No name": {
                    "summary": "`holder`에 `full_name`과 `business_name`이 모두 없습니다.",
                    "value": {
                      "detail": "Send full_name for a person or business_name for a company.",
                      "code": "invalid_account_input",
                      "field": "holder",
                      "reason": "required"
                    }
                  },
                  "Consent required": {
                    "summary": "해당 국가의 계좌 확인에는 계좌 소유자의 동의가 필요합니다",
                    "value": {
                      "detail": "Account checks in this country need the account holder's explicit consent. Ask for it, then send `consent=true`.",
                      "code": "invalid_account_input",
                      "field": "consent",
                      "reason": "required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckError"
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "검사 비용을 결제할 수 없어 실행되지 않았습니다. 잔액을 충전한 후 다시 전송하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckError"
                },
                "examples": {
                  "Out of credit": {
                    "summary": "잔액이 1회의 확인 비용을 충당할 수 없습니다",
                    "value": {
                      "detail": "You don't have enough credits to perform this request. Please top up at https://business.didit.me",
                      "code": "insufficient_credits"
                    }
                  },
                  "Not in your contract": {
                    "summary": "계약에 Account check API에 대한 가격이 설정되어 있지 않습니다",
                    "value": {
                      "detail": "Your contract does not price the Account check API. Contact your account manager.",
                      "code": "contract_rate_missing"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` 헤더 또는 전달자 토큰이 누락되었거나 유효하지 않으며, 요청이 키의 IP 목록 외부 주소에서 발생했거나, 범위가 지정된 키에 세션 쓰기 권한이 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckError"
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "유효한 API 키 또는 token이 없음",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "No sessions write": {
                    "summary": "세션에 대한 쓰기 권한이 없는 범위 한정 키",
                    "value": {
                      "detail": "This API key has no write access to sessions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "아직 이 계좌를 지원하는 계좌 확인이 없으므로 확인되거나 청구된 내용이 없습니다. `country_not_covered`: 해당 국가 또는 해당 국가의 계좌 유형(개인 또는 기업)을 지원하지 않습니다. `bank_not_covered`: 해당 은행을 지원하지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckError"
                },
                "examples": {
                  "Country not covered": {
                    "summary": "해당 국가를 지원하는 계좌 확인이 없습니다",
                    "value": {
                      "detail": "No account check serves this country yet.",
                      "code": "country_not_covered"
                    }
                  },
                  "Bank not covered": {
                    "summary": "해당 계좌의 은행을 지원하는 계좌 확인이 없습니다",
                    "value": {
                      "detail": "No account check serves this account's bank yet.",
                      "code": "bank_not_covered"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "503": {
            "description": "은행이 응답할 수 없었습니다. 확인되거나 청구된 내역이 없습니다. 나중에 확인을 다시 보내십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckError"
                },
                "examples": {
                  "Unavailable": {
                    "summary": "은행이 응답하지 않았습니다",
                    "value": {
                      "detail": "The account check is temporarily unavailable and this request was not charged. Please try again.",
                      "code": "account_check_unavailable"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/bank/account-check/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"country\": \"NGA\",\n    \"account\": {\"bank_code\": \"000014\", \"account_number\": \"0123450001\"},\n    \"holder\": {\"full_name\": \"Maria Oliveira\"},\n    \"vendor_data\": \"payout_20481\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.bank.account_check(\n    country=\"NGA\",\n    account={\n        \"account_number\": \"0123450001\",\n        \"bank_code\": \"000014\",\n    },\n    holder={\n        \"full_name\": \"Maria Oliveira\",\n    },\n    vendor_data=\"payout_20481\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.bank.accountCheck({\n  country: \"NGA\",\n  account: {\n    account_number: \"0123450001\",\n    bank_code: \"000014\",\n  },\n  holder: {\n    full_name: \"Maria Oliveira\",\n  },\n  vendor_data: \"payout_20481\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Bank.AccountCheck(ctx, didit.BankAccountCheckRequest{\n\tCountry: \"NGA\",\n\tAccount: didit.BankAccountCheckRequestAccount{\n\t\tAccountNumber: didit.String(\"0123450001\"),\n\t\tBankCode:      didit.String(\"000014\"),\n\t},\n\tHolder: didit.BankAccountCheckHolder{\n\t\tFullName: didit.String(\"Maria Oliveira\"),\n\t},\n\tVendorData: didit.String(\"payout_20481\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BankAccountCheckHolder;\nimport me.didit.types.BankAccountCheckPersonHolder;\nimport me.didit.types.BankAccountCheckRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.bank().accountCheck(BankAccountCheckRequest.builder()\n        .country(\"NGA\")\n        .account(BankAccountCheckRequest.Account.builder()\n                .accountNumber(\"0123450001\")\n                .bankCode(\"000014\")\n                .build())\n        .holder(BankAccountCheckHolder.ofBankAccountCheckPersonHolder(BankAccountCheckPersonHolder.builder()\n                .fullName(\"Maria Oliveira\")\n                .build()))\n        .vendorData(\"payout_20481\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->bank->accountCheck([\n    'country' => 'NGA',\n    'account' => [\n        'account_number' => '0123450001',\n        'bank_code' => '000014',\n    ],\n    'holder' => [\n        'full_name' => 'Maria Oliveira',\n    ],\n    'vendor_data' => 'payout_20481',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.bank.account_check(\n  country: \"NGA\",\n  account: {\n    account_number: \"0123450001\",\n    bank_code: \"000014\",\n  },\n  holder: {\n    full_name: \"Maria Oliveira\",\n  },\n  vendor_data: \"payout_20481\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Bank.AccountCheckAsync(new BankAccountCheckRequest\n{\n    Country = \"NGA\",\n    Account = new()\n    {\n        AccountNumber = \"0123450001\",\n        BankCode = \"000014\",\n    },\n    Holder = new()\n    {\n        FullName = \"Maria Oliveira\",\n    },\n    VendorData = \"payout_20481\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/email/send/": {
      "post": {
        "summary": "이메일 코드 전송",
        "description": "이메일 주소로 일회용 코드(OTP)를 전송한 다음, [`POST /v3/email/check/`](/ko/standalone-apis/email-check)를 통해 확인합니다.\n\n**전송과 확인의 연계 방식.** 인증 상태는 애플리케이션 및 `email` 주소를 키로 관리되며, 확인 호출에는 `request_id`가 전달되지 않습니다. 새로 전송할 때마다 **5분** 동안 유효한 대기 상태의 인증이 생성됩니다. 유효 시간이 만료되기 전에 동일한 주소 및 사용자가 수신한 코드로 확인을 호출하십시오. 인증이 대기 중인 상태에서 동일한 주소로 전송을 다시 호출하면 해당 인증에 대한 새 코드가 생성되며(`status: \"Retry\"`, 동일한 `request_id`), 이전 코드는 더 이상 작동하지 않습니다. 이 방식으로 최대 1회의 재시도가 연결되며(총 2회 전송), 추가로 전송하면 새 `request_id`를 가진 새로운 인증이 시작됩니다. 5분의 유효 시간은 첫 번째 전송 시점부터 측정되며 재시도로 연장되지 않습니다.\n\n**전송 가능 여부 사전 확인.** 전송이 이루어지기 전에 해당 주소의 구문 및 DNS/MX 검증이 진행됩니다. 메일을 수신할 수 없는 주소는 `status: \"Undeliverable\"` 및 `reason: \"email_can_not_be_delivered\"`와 함께 `200`을 반환합니다. 이메일은 전송되지 않고 결제도 청구되지 않으며, 인증은 즉시 `Declined`로 완료 처리됩니다(이후 확인을 호출하면 `Expired or Not Found`가 반환됨). 주소 외의 원인으로 전송에 실패한 경우(이메일을 전송을 위해 인계하지 못한 경우) 대신 `503`이 반환됩니다. 코드가 전송되지 않고 요금도 청구되지 않으며, 인증은 열린 상태로 유지되므로 동일한 요청을 다시 시도할 수 있습니다.\n\n**코드 형식 및 브랜딩.** 코드는 4~8자(`options.code_size`, 기본값 6)이며 기본적으로 숫자입니다. 대문자와 숫자를 사용하려면 `options.alphanumeric_code: true`로 설정하십시오(확인 시 대소문자를 구분하지 않고 비교함). 이메일 템플릿은 `options.locale`(54개 지원 언어)을 통해 현지화되며, `options.use_white_label_customization`을 통해 애플리케이션의 화이트 라벨 브랜딩을 적용할 수 있습니다.\n\n**결제.** 성공한 전송(`status: \"Success\"`) 건당 1개의 이메일 인증 API 크레딧이 전송 시점에 청구됩니다. `Retry` 및 `Undeliverable` 전송은 무료이며, 확인 또한 무료입니다.\n\n**세션 지속성.** 모든 새로운 인증은 API 유형 세션으로 유지됩니다. `request_id`는 `GET /v3/session/{sessionId}/decision/`에 전달할 수 있는 실제 세션 ID이며, 인증 내역은 Business Console에 표시되고 진행 상황에 따라 `status.updated` webhook이 발생합니다.\n\n**샌드박스.** 샌드박스 API 키는 전송 및 결제를 건너뜁니다. 요청 유효성 검사(형식이 잘못된 입력은 여전히 `400` 반환) 후 endpoint는 임의의 `request_id`가 포함된 정적 `Success` payload를 반환합니다. 이메일은 전송되지 않으며 아무것도 저장되지 않습니다. 샌드박스 확인에는 코드 `123456`을 사용하십시오.\n\n**인증.** `x-api-key` 헤더에 애플리케이션의 API 키를 전달하십시오. 자격 증명이 누락되었거나 유효하지 않은 경우 `403`(`{\"detail\": \"You do not have permission to perform this action.\"}`)이 반환됩니다. 이 API는 `401`을 반환하지 않습니다.\n\n**속도 제한.** 모든 POST/PATCH/DELETE endpoint에 걸쳐 API 키당 분당 300개의 쓰기 요청 한도가 공유되며, 이를 초과하면 `429`가 반환됩니다.",
        "operationId": "post_v3email_send",
        "x-didit-sdk": {
          "resource": "email",
          "method": "send_code",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/email/send/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"email\": \"alice@example.com\",\n    \"options\": { \"code_size\": 6, \"locale\": \"en\" },\n    \"vendor_data\": \"user-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.email.send_code(\n    email=\"alice@example.com\",\n    options={\n        \"locale\": \"en\",\n    },\n    vendor_data=\"user-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.email.sendCode({\n  email: \"alice@example.com\",\n  options: {\n    locale: \"en\",\n  },\n  vendor_data: \"user-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Email.SendCode(ctx, didit.EmailSendCodeParams{\n\tEmail: \"alice@example.com\",\n\tOptions: didit.Some(didit.EmailSendCodeParamsOptions{\n\t\tLocale: didit.Some(didit.EmailSendCodeParamsOptionsLocale(\"en\")),\n\t}),\n\tVendorData: didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.EmailSendCodeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.email().sendCode(EmailSendCodeParams.builder()\n        .email(\"alice@example.com\")\n        .options(EmailSendCodeParams.Options.builder()\n                .locale(EmailSendCodeParams.Options.Locale.of(\"en\"))\n                .build())\n        .vendorData(\"user-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->email->sendCode([\n    'email' => 'alice@example.com',\n    'options' => [\n        'locale' => 'en',\n    ],\n    'vendor_data' => 'user-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.email.send_code(\n  email: \"alice@example.com\",\n  options: {\n    locale: \"en\",\n  },\n  vendor_data: \"user-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Email.SendCodeAsync(new EmailSendCodeParams\n{\n    Email = \"alice@example.com\",\n    Options = new EmailSendCodeParamsOptions\n    {\n        Locale = new EmailSendCodeParamsOptionsLocale(\"en\"),\n    },\n    VendorData = \"user-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "수취인 이메일 주소입니다. 형식이 잘못된 주소는 `400`을 반환합니다. 문법적으로는 유효하지만 메일을 수신할 수 없는 주소(DNS/MX 검증 실패)는 `status: \"Undeliverable\"`과 함께 `200`을 반환합니다.",
                    "example": "alice@example.com"
                  },
                  "options": {
                    "type": "object",
                    "description": "OTP 형식, 현지화 및 브랜딩 옵션입니다. 모든 필드는 선택 사항입니다.",
                    "properties": {
                      "code_size": {
                        "type": "integer",
                        "minimum": 4,
                        "maximum": 8,
                        "default": 6,
                        "description": "OTP의 문자 수입니다(기본적으로 숫자이며, `alphanumeric_code`가 `true`인 경우 대문자 및 숫자입니다)."
                      },
                      "alphanumeric_code": {
                        "type": "boolean",
                        "default": false,
                        "description": "`true`인 경우 OTP가 숫자만으로 구성되는 대신 대문자 `A–Z`와 숫자 `0–9`로 구성됩니다. `/v3/email/check/` 비교는 대소문자를 구분하지 않습니다."
                      },
                      "locale": {
                        "type": "string",
                        "maxLength": 5,
                        "enum": [
                          "en",
                          "ar",
                          "bn",
                          "bg",
                          "bs",
                          "ca",
                          "cs",
                          "da",
                          "de",
                          "el",
                          "es",
                          "et",
                          "fa",
                          "fi",
                          "fr",
                          "he",
                          "hi",
                          "hr",
                          "hu",
                          "hy",
                          "id",
                          "it",
                          "ja",
                          "ka",
                          "kk",
                          "ko",
                          "ky",
                          "lt",
                          "lv",
                          "cnr",
                          "mk",
                          "mn",
                          "ms",
                          "nl",
                          "no",
                          "pl",
                          "pt-BR",
                          "pt",
                          "ro",
                          "ru",
                          "sk",
                          "sl",
                          "so",
                          "sq",
                          "sr",
                          "sv",
                          "th",
                          "tr",
                          "uk",
                          "uz",
                          "vi",
                          "zh-CN",
                          "zh-TW",
                          "zh"
                        ],
                        "description": "OTP 이메일 템플릿의 언어입니다. 기본값은 `en`입니다. 지원되지 않는 값은 지원되는 모든 로캘을 나열하는 `400`을 반환합니다.",
                        "example": "en"
                      },
                      "use_white_label_customization": {
                        "type": "boolean",
                        "default": false,
                        "description": "`true`인 경우 OTP 이메일에 기본 Didit 템플릿 대신 애플리케이션의 화이트 라벨 맞춤 설정(로고, 색상, 발신자 브랜딩)이 사용됩니다."
                      }
                    }
                  },
                  "signals": {
                    "type": "object",
                    "description": "최종 사용자에 대한 선택적 기기 및 네트워크 신호로, 어뷰징 또는 자동화된 트래픽 감지를 개선하기 위해 사기 방지 계층으로 전달됩니다. 모든 필드는 선택 사항입니다.",
                    "properties": {
                      "ip": {
                        "type": "string",
                        "description": "최종 사용자 기기의 주소입니다. IPv4 또는 IPv6입니다.",
                        "example": "192.0.2.1"
                      },
                      "device_id": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "최종 사용자 기기의 고유 식별자입니다. Android: `ANDROID_ID`, iOS: `identifierForVendor`.",
                        "example": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2"
                      },
                      "device_platform": {
                        "type": "string",
                        "enum": [
                          "android",
                          "ios",
                          "ipados",
                          "tvos",
                          "web"
                        ],
                        "description": "최종 사용자 기기의 플랫폼입니다."
                      },
                      "device_model": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "최종 사용자 기기의 모델입니다.",
                        "example": "iPhone17,2"
                      },
                      "os_version": {
                        "type": "string",
                        "maxLength": 64,
                        "description": "최종 사용자 기기의 운영체제 버전입니다.",
                        "example": "18.0.1"
                      },
                      "app_version": {
                        "type": "string",
                        "maxLength": 64,
                        "description": "애플리케이션의 버전입니다.",
                        "example": "1.2.34"
                      },
                      "user_agent": {
                        "type": "string",
                        "maxLength": 512,
                        "description": "최종 사용자의 브라우저 또는 앱의 사용자 에이전트입니다.",
                        "example": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1"
                      }
                    }
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "세션에 유지되고 전송 응답, 일치 확인 응답, webhook 및 Business Console에 그대로 반환되는 선택적 호출자 제어 식별자(내부 사용자 ID, 이메일, UUID 등)입니다. Didit의 `request_id`를 사용자 레코드와 연결하는 데 사용하십시오."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "세션에 유지되고 전송 응답, 일치 확인 응답, webhook 및 Business Console에 다시 반환되는 선택적 자유 형식 JSON 객체입니다."
                  }
                },
                "required": [
                  "email"
                ]
              },
              "examples": {
                "Numeric 6-digit code": {
                  "summary": "기본값 — 영어로 된 6자리 숫자 코드",
                  "value": {
                    "email": "alice@example.com",
                    "options": {
                      "locale": "en"
                    },
                    "vendor_data": "user-1234"
                  }
                },
                "Alphanumeric 8-character code": {
                  "summary": "대문자 영문 + 숫자, 스페인 템플릿",
                  "value": {
                    "email": "bob@example.com",
                    "options": {
                      "code_size": 8,
                      "alphanumeric_code": true,
                      "locale": "es"
                    }
                  }
                },
                "White-label branding": {
                  "summary": "애플리케이션의 화이트 라벨 맞춤 설정을 적용하여 OTP 이메일을 전송합니다.",
                  "value": {
                    "email": "carol@example.com",
                    "options": {
                      "locale": "en",
                      "use_white_label_customization": true
                    },
                    "vendor_data": "user-5678"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "전송이 확인되었습니다. `status`를 확인하십시오. `Success` 및 `Retry`는 코드가 발송 중임을 의미하며, `Undeliverable`은 해당 주소로 메일을 받을 수 없어 인증이 이미 `Declined`로 완료되었음을 의미합니다. `request_id`는 유지되는 세션 ID입니다(`Retry` 시 동일한 ID).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailVerificationSendResponse"
                },
                "examples": {
                  "Success": {
                    "summary": "새 인증을 위해 이메일로 전송된 OTP(과금됨)",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Success",
                      "reason": null,
                      "vendor_data": "user-1234",
                      "metadata": null
                    }
                  },
                  "Retry": {
                    "summary": "5분 기간 내 두 번째 발송 — 새로운 코드, 동일한 request_id, 무료",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Retry",
                      "reason": null,
                      "vendor_data": "user-1234",
                      "metadata": null
                    }
                  },
                  "Undeliverable": {
                    "summary": "주소가 DNS/MX 유효성 검사에 실패함 — 인증이 거부됨으로 최종 처리되었으며 요금이 청구되지 않음",
                    "value": {
                      "request_id": "cb1a5011-344d-444d-bdce-218904745d7f",
                      "status": "Undeliverable",
                      "reason": "email_can_not_be_delivered",
                      "vendor_data": "user-1234",
                      "metadata": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 오류 — DRF의 필드 오류 엔벨로프: 문제가 있는 필드당 하나의 메시지 배열, 옵션 오류의 경우 `options` 아래에 중첩됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid email": {
                    "summary": "잘못된 형식의 이메일 주소",
                    "value": {
                      "email": [
                        "Enter a valid email address."
                      ]
                    }
                  },
                  "Unsupported locale": {
                    "summary": "`options.locale`이 지원되는 집합을 벗어남",
                    "value": {
                      "options": {
                        "locale": [
                          "Invalid locale. Supported locales are en, ar, bn, bg, bs, ca, cs, da, de, el, es, et, fa, fi, fr, he, hi, hr, hu, hy, id, it, ja, ka, kk, ko, ky, lt, lv, cnr, mk, mn, ms, nl, no, pl, pt-BR, pt, ro, ru, sk, sl, so, sq, sr, sv, th, tr, uk, uz, vi, zh-CN, zh-TW, zh."
                        ]
                      }
                    }
                  },
                  "Code size out of range": {
                    "summary": "`options.code_size`가 4–8 범위를 벗어남",
                    "value": {
                      "options": {
                        "code_size": [
                          "Ensure this value is less than or equal to 8."
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었을 때 반환됩니다(`{\"detail\": ...}`). 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 또한 발송 전에 조직의 잔액이 이메일 인증 API 크레딧 1건을 충당할 수 없을 때도 반환됩니다(`{\"error\": ...}`).",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 전송 가격을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "이메일 주소와 무관한 이유(이메일 제공업체 연결 불가, 시간 초과 또는 전송 자체 거부)로 이메일을 전송할 수 없었습니다. 따라서 코드가 전송되지 않았으며 결제나 전송 시도 횟수로 집계되지 않았습니다. 동일한 요청을 다시 시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Email delivery unavailable": {
                    "summary": "1회 자동 재시도 후 이메일 제공업체 오류가 발생했습니다.",
                    "value": {
                      "detail": "Email delivery is temporarily unavailable. Please try again."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/email/check/": {
      "post": {
        "summary": "이메일 코드 확인",
        "description": "[`POST /v3/email/send/`](/ko/standalone-apis/email-send)로 전송된 OTP를 검증하고 최종 인증 결과와 이메일 인텔리전스를 확인합니다: 전송 가능 여부, 유출 노출 여부(유출 인텔리전스 데이터베이스의 `is_breached` 및 `breaches` 목록), 일회용 제공업체 감지, 세션 전반에 걸친 주소 중복 사용.\n\n**검사 대상 인증을 찾는 방법.** 매칭은 애플리케이션과 `email` 주소를 기준으로 수행되며, `request_id`는 입력 파라미터가 아닙니다. 지난 **5분** 이내에 생성된 가장 최근의 대기 중인 인증을 확인합니다. 해당 건이 없는 경우(전송된 적 없음, 이미 완료됨, 전송 시점에 전송 불가능했음, 또는 5분이 지남) endpoint는 `status: \"Expired or Not Found\"`와 함께 `200`을 반환합니다.\n\n**시도 가능 횟수.** 각 인증마다 **3회의 코드 입력 시도**가 허용됩니다. 처음 두 번 잘못된 코드를 입력하면 남은 시도 횟수 및 `email: null`과 함께 `status: \"Failed\"`가 반환됩니다. 세 번째로 잘못된 코드를 입력하면 `EMAIL_CODE_ATTEMPTS_EXCEEDED` 경고와 함께 인증이 `Declined`로 최종 처리되고 전체 이메일 보고서가 반환됩니다. 코드는 대소문자를 구분하지 않고 비교되며(`alphanumeric_code` 전송에 해당), 가장 최근에 전송된 코드만 유효합니다.\n\n**결과.** `Approved` — 올바른 코드이며 거부 위험이 없음. `Declined` — 최종 거부: 코드는 올바르지만 거부 위험 항목에 매칭됨(아래의 `DECLINE` 작업, 차단 목록에 등록된 주소, 또는 완료 시점에 전송 불가로 확인된 주소), 또는 시도 횟수를 모두 소진함. `Failed` — 잘못된 코드, 잔여 시도 횟수 있음. `Expired or Not Found` — 확인할 항목 없음. `Approved`/`Declined` 시 `request_id`는 전송 요청의 `request_id`(세션 ID)와 동일하며 `email`에는 전체 보고서(`is_breached`, `breaches`, `is_disposable`, `is_undeliverable`, `warnings`, `lifecycle`, `matches`)가 포함됩니다. `Failed` 및 `Expired or Not Found` 시 `request_id`는 일회성 무작위 UUID입니다.\n\n**위험 작업.** `duplicated_email_action`, `breached_email_action`, `disposable_email_action`은 올바른 코드가 입력되었을 때 해당 위험이 감지되는 경우의 처리 방식을 결정합니다. `DECLINE`은 최종 상태를 `Declined`로 변경합니다. `NO_ACTION`(기본값)은 상태에 영향을 주지 않고 `email.warnings`에 위험 항목을 기록합니다.\n\n**결제.** 검사는 무료입니다 — 크레딧은 성공적인 전송 시 소진됩니다.\n\n**세션 유지.** 완료된 검사는 전송 시 생성된 세션을 업데이트하고(Business Console에서 확인 가능하며 `GET /v3/session/{sessionId}/decision/`을 통해 조회 가능), `status.updated` webhook을 호출합니다.\n\n**샌드박스.** 샌드박스 API 키는 모든 처리를 건너뜁니다. 올바른 형식의 모든 코드(`123456` 포함)에 대해 간소화된 `email` 객체(`status`, `email`, `is_breached`, `is_disposable`, `is_undeliverable`)가 포함된 정적 `Approved` payload를 반환합니다. 형식이 잘못된 입력은 여전히 `400`을 반환합니다. 아무것도 저장되지 않습니다.\n\n**인증.** `x-api-key` 헤더에 애플리케이션의 API 키를 포함합니다. 인증 자격 증명이 누락되었거나 유효하지 않은 경우 `403`(`{\"detail\": \"You do not have permission to perform this action.\"}`)을 반환합니다 — 이 API는 `401`을 반환하지 않습니다.\n\n**속도 제한.** 모든 POST/PATCH/DELETE endpoint에 걸쳐 API 키당 분당 300건의 쓰기 요청 한도가 공유됩니다. 이를 초과하면 `429`가 반환됩니다.\n\n**소셜 풋프린트.** `enable_social`을 `true`로 설정하면 `email_social` 블록이 추가됩니다. 여기에는 이 주소가 등록된 온라인 플랫폼 정보, 카테고리별 건수 및 확인 가능한 프로필 세부 정보가 포함됩니다. `profiles_registered: 0`은 플랫폼을 확인했으나 주소가 등록된 곳을 찾지 못했음을 의미하며, 이는 유효하고 요금이 청구되는 응답입니다. 부가 기능을 요청하지 않았거나 검사를 완료할 수 없는 경우에는 이 블록이 포함되지 않으며, 이 경우 요금이 청구되지 않습니다. 결제 시 이 endpoint 자체의 가격에 요청당 1개의 `email_social` 단위가 추가됩니다.",
        "operationId": "post_v3email_check",
        "x-didit-sdk": {
          "resource": "email",
          "method": "check_code",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/email/check/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"email\": \"alice@example.com\",\n    \"code\": \"123456\",\n    \"disposable_email_action\": \"DECLINE\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.email.check_code(\n    email=\"alice@example.com\",\n    code=\"123456\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.email.checkCode({\n  email: \"alice@example.com\",\n  code: \"123456\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Email.CheckCode(ctx, didit.EmailCheckCodeParams{\n\tEmail: \"alice@example.com\",\n\tCode:  \"123456\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.EmailCheckCodeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.email().checkCode(EmailCheckCodeParams.builder()\n        .email(\"alice@example.com\")\n        .code(\"123456\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->email->checkCode([\n    'email' => 'alice@example.com',\n    'code' => '123456',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.email.check_code(\n  email: \"alice@example.com\",\n  code: \"123456\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Email.CheckCodeAsync(new EmailCheckCodeParams\n{\n    Email = \"alice@example.com\",\n    Code = \"123456\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "일치하는 [`POST /v3/email/send/`](/ko/standalone-apis/email-send) 호출에 사용된 것과 동일한 이메일 주소입니다. 이를 통해 검증과 전송이 연결됩니다.",
                    "example": "alice@example.com"
                  },
                  "code": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "최종 사용자가 수신한 OTP: 4~8자리 숫자이거나, 발송 시 `alphanumeric_code: true`를 사용한 경우 4~8자리 문자/숫자입니다. 비교 시 대소문자를 구분하지 않습니다.",
                    "example": "123456"
                  },
                  "duplicated_email_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "동일한 주소가 애플리케이션의 다른 사용자(다른 `vendor_data`)에 의해 이미 사용되고 승인되었을 때 수행할 작업입니다(이전에 승인된 인증만 계산됨). `DECLINE`은 최종 `status`를 `Declined`로 변경하며, `NO_ACTION`은 위험을 `email.warnings`에 기록하고 `email.matches`를 채웁니다."
                  },
                  "breached_email_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "알려진 데이터 유출 사고에 해당 주소가 포함되어 있을 때(`email.is_breached`) 수행할 작업입니다. `DECLINE`은 최종 `status`를 `Declined`로 변경하고, `NO_ACTION`은 해당 위험을 `email.warnings`에 기록합니다."
                  },
                  "disposable_email_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "도메인이 일회용/임시 이메일 제공업체에 속할 때 수행할 작업입니다 (`email.is_disposable`). `DECLINE`은 최종 `status`를 `Declined`로 변경하며, `NO_ACTION`은 위험을 `email.warnings`에 기록합니다."
                  },
                  "enable_enrichment": {
                    "type": "boolean",
                    "default": false,
                    "description": "`true`인 경우 해당 주소에 대한 이메일 인텔리전스(위험 점수 및 유출 이력)도 실행합니다. 이 endpoint의 자체 가격 외에 요청당 하나의 `email_intelligence_api` 단위(정가 기준 $0.05)로 청구됩니다. 잔액이 이를 충당하지 못하면 요청은 `403`을 반환합니다.",
                    "example": false
                  },
                  "email_intelligence_score_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "이메일 인텔리전스 위험 점수가 임계값을 초과할 때 수행할 작업입니다. `DECLINE`은 최종 `status`를 `Declined`로 변경하며, `NO_ACTION`은 거부하지 않고 신호를 기록합니다. `enable_enrichment`가 `true`일 때만 적용됩니다."
                  },
                  "recent_email_breach_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "주소가 최근 알려진 데이터 침해에 포함된 경우의 작업입니다. `DECLINE`은 최종 `status`를 `Declined`로 변경합니다. `NO_ACTION`은 거부하지 않고 신호를 기록합니다. `enable_enrichment`가 `true`일 때만 적용됩니다."
                  },
                  "frequent_email_breach_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "주소가 알려진 다수의 데이터 침해에 포함된 경우의 작업입니다. `DECLINE`은 최종 `status`를 `Declined`로 변경합니다. `NO_ACTION`은 거부하지 않고 신호를 기록합니다. `enable_enrichment`가 `true`일 때만 적용됩니다."
                  },
                  "enable_social": {
                    "type": "boolean",
                    "default": false,
                    "description": "true인 경우, 주소의 소셜 발자국(등록된 이메일, 소셜, 전문, 전자상거래 및 엔터테인먼트 플랫폼)도 조회합니다. 이 endpoint 자체의 가격 외에 요청당 `email_social` 1단위로 청구됩니다.",
                    "example": true
                  },
                  "email_no_social_presence_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "소셜 풋프린트 검사 결과 지원하는 플랫폼 중 어느 곳에도 해당 주소가 등록되어 있지 않을 때 수행할 작업입니다. 이 endpoint에서는 NO_ACTION 및 DECLINE만 허용되며, 동일한 이름의 워크플로 구성 키에서는 REVIEW를 사용할 수 있습니다."
                  }
                },
                "required": [
                  "email",
                  "code"
                ]
              },
              "examples": {
                "Default": {
                  "summary": "모든 위험을 기록하지만 자동으로 거부하지는 않음",
                  "value": {
                    "email": "alice@example.com",
                    "code": "123456"
                  }
                },
                "Strict risk policy": {
                  "summary": "일회용 및 유출된 편지함 자동 거부",
                  "value": {
                    "email": "alice@example.com",
                    "code": "123456",
                    "disposable_email_action": "DECLINE",
                    "breached_email_action": "DECLINE"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "확인 완료 — 잘못된 코드 및 누락된 인증도 `200`을 반환하므로 HTTP 코드가 아닌 `status`를 확인하십시오. `email`은 최종 결과(`Approved`/`Declined`)에서만 채워지며, `Failed`에서는 `null`, `Expired or Not Found`에서는 제외됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailVerificationCheckResponse"
                },
                "examples": {
                  "Approved": {
                    "summary": "올바른 코드 — 이상 없는 주소, 전체 이메일 보고서",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Approved",
                      "message": "The verification code is correct.",
                      "email": {
                        "status": "Approved",
                        "email": "alice@example.com",
                        "is_breached": false,
                        "breaches": [],
                        "is_disposable": false,
                        "is_undeliverable": false,
                        "verification_attempts": 1,
                        "verified_at": "2026-06-12T01:24:47.311323Z",
                        "warnings": [],
                        "lifecycle": [
                          {
                            "type": "EMAIL_VERIFICATION_MESSAGE_SENT",
                            "timestamp": "2026-06-12T01:23:39.580554+00:00",
                            "details": {
                              "status": "Success",
                              "reason": null
                            },
                            "fee": 0.02
                          },
                          {
                            "type": "VALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:47.311201+00:00",
                            "details": {
                              "code_tried": "123456",
                              "status": "Approved"
                            },
                            "fee": 0
                          },
                          {
                            "type": "EMAIL_VERIFICATION_APPROVED",
                            "timestamp": "2026-06-12T01:24:47.384292+00:00",
                            "details": null,
                            "fee": 0
                          }
                        ],
                        "matches": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.401719+00:00"
                    }
                  },
                  "Approved with breach exposure": {
                    "summary": "올바른 코드이며 유출에 노출된 사실이 경고로 기록됨(breached_email_action=NO_ACTION)",
                    "value": {
                      "request_id": "3a1f2b6c-9d4e-4f7a-8b2c-1e5d6f7a8b9c",
                      "status": "Approved",
                      "message": "The verification code is correct.",
                      "email": {
                        "status": "Approved",
                        "email": "bob@example.com",
                        "is_breached": true,
                        "breaches": [
                          {
                            "name": "ExampleApp",
                            "domain": "exampleapp.com",
                            "breach_date": "2019-03-21",
                            "breach_emails_count": 763117,
                            "description": "In March 2019, the social platform ExampleApp suffered a data breach that exposed email addresses and passwords.",
                            "logo_path": "https://<media-host>/logos/ExampleApp.png",
                            "data_classes": [
                              "email_addresses",
                              "passwords"
                            ],
                            "is_verified": true
                          }
                        ],
                        "is_disposable": false,
                        "is_undeliverable": false,
                        "verification_attempts": 1,
                        "verified_at": "2026-06-12T01:24:47.311323Z",
                        "warnings": [
                          {
                            "feature": "EMAIL",
                            "risk": "BREACHED_EMAIL_DETECTED",
                            "additional_data": null,
                            "log_type": "information",
                            "short_description": "Breached email detected",
                            "long_description": "This email address was found in one or more known data breaches."
                          }
                        ],
                        "lifecycle": [
                          {
                            "type": "EMAIL_VERIFICATION_MESSAGE_SENT",
                            "timestamp": "2026-06-12T01:23:39.580554+00:00",
                            "details": {
                              "status": "Success",
                              "reason": null
                            },
                            "fee": 0.02
                          },
                          {
                            "type": "VALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:47.311201+00:00",
                            "details": {
                              "code_tried": "835126",
                              "status": "Approved"
                            },
                            "fee": 0
                          },
                          {
                            "type": "EMAIL_VERIFICATION_APPROVED",
                            "timestamp": "2026-06-12T01:24:47.384292+00:00",
                            "details": null,
                            "fee": 0
                          }
                        ],
                        "matches": []
                      },
                      "vendor_data": "user-5678",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.401719+00:00"
                    }
                  },
                  "Failed (attempts remaining)": {
                    "summary": "잘못된 코드 — 사용자가 재시도할 수 있습니다. 여기서 request_id는 일회용 UUID입니다.",
                    "value": {
                      "request_id": "11111111-2222-3333-4444-555555555555",
                      "status": "Failed",
                      "message": "The verification code is incorrect. Attempts remaining: 2",
                      "email": null,
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:21.512340+00:00"
                    }
                  },
                  "Declined (risk policy)": {
                    "summary": "올바른 코드이지만 일회용 주소이며 disposable_email_action=DECLINE으로 설정됨",
                    "value": {
                      "request_id": "8c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                      "status": "Declined",
                      "message": "The verification code is correct.",
                      "email": {
                        "status": "Declined",
                        "email": "tempuser42@mailinator.com",
                        "is_breached": false,
                        "breaches": [],
                        "is_disposable": true,
                        "is_undeliverable": false,
                        "verification_attempts": 1,
                        "verified_at": "2026-06-12T01:24:47.311323Z",
                        "warnings": [
                          {
                            "feature": "EMAIL",
                            "risk": "DISPOSABLE_EMAIL_DETECTED",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Disposable email detected",
                            "long_description": "The system detected that the email is disposable, which is not allowed."
                          }
                        ],
                        "lifecycle": [
                          {
                            "type": "EMAIL_VERIFICATION_MESSAGE_SENT",
                            "timestamp": "2026-06-12T01:23:39.580554+00:00",
                            "details": {
                              "status": "Success",
                              "reason": null
                            },
                            "fee": 0.02
                          },
                          {
                            "type": "VALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:47.311201+00:00",
                            "details": {
                              "code_tried": "123456",
                              "status": "Approved"
                            },
                            "fee": 0
                          },
                          {
                            "type": "EMAIL_VERIFICATION_DECLINED",
                            "timestamp": "2026-06-12T01:24:47.384292+00:00",
                            "details": {
                              "reason": "DISPOSABLE_EMAIL_DETECTED"
                            },
                            "fee": 0
                          }
                        ],
                        "matches": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.401719+00:00"
                    }
                  },
                  "Expired or Not Found": {
                    "summary": "지난 5분 동안 이 주소에 대해 대기 중인 인증이 없습니다",
                    "value": {
                      "request_id": "88808a77-06e9-4cb0-85f5-9c052ddfd987",
                      "status": "Expired or Not Found",
                      "message": "No pending email verification found in the last 5 minutes.",
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:59.887904+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 오류 — DRF의 필드 오류 엔벨로프: 문제가 있는 필드당 하나의 메시지 배열.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid email": {
                    "summary": "잘못된 형식의 이메일 주소",
                    "value": {
                      "email": [
                        "Enter a valid email address."
                      ]
                    }
                  },
                  "Missing code": {
                    "summary": "본문에 `code`가 포함되지 않았습니다",
                    "value": {
                      "code": [
                        "This field is required."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 확인은 무료이므로 크레딧 확인이 수행되지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/workflows/": {
      "get": {
        "summary": "워크플로 목록 조회",
        "description": "워크플로 목록을 최신순으로 limit/offset 페이지네이션 응답 형식(`{count, next, previous, results}`, 기본 페이지 크기 50)으로 조회합니다. 각 행은 하나의 버전입니다. `workflow_id`는 고정 그룹 ID이며 새 세션은 최신 `published` 버전을 사용합니다.",
        "operationId": "list_workflows",
        "x-didit-sdk": {
          "resource": "workflows",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Workflows"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50
            },
            "description": "페이지 크기(페이지당 워크플로 수)입니다."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "반환되는 첫 번째 워크플로 전에 건너뛸 행 수입니다."
          }
        ],
        "responses": {
          "200": {
            "description": "`created_at` 내림차순으로 정렬되어 페이지네이션 엔벨로프에 래핑된 워크플로 페이지 하나입니다. `results`의 각 항목은 `WorkflowListItem`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "해당 애플리케이션의 총 워크플로 버전 수입니다."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "다음 페이지의 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "이전 페이지의 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WorkflowListItem"
                      }
                    }
                  }
                },
                "examples": {
                  "Two workflows": {
                    "summary": "기본 KYC 워크플로 및 초안 KYC + AML 워크플로",
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "a1b2c3d4-5678-90ab-cdef-111111111111",
                          "workflow_id": "a1b2c3d4-5678-90ab-cdef-111111111111",
                          "workflow_label": "Standard KYC",
                          "workflow_type": "kyc",
                          "is_default": true,
                          "is_archived": false,
                          "is_white_label_enabled": false,
                          "total_price": 0.15,
                          "min_price": 0.15,
                          "max_price": 0.15,
                          "features": "OCR + LIVENESS + FACE_MATCH",
                          "is_simple_workflow": true,
                          "is_editable": false,
                          "workflow_url": "https://verify.didit.me/u/_yljPOx8RWG3UAz5ZRQGVQ",
                          "max_retry_attempts": 3,
                          "retry_window_days": 7,
                          "session_expiration_time": 604800,
                          "version": 2,
                          "status": "published",
                          "has_draft": false,
                          "created_by": {
                            "name": "Alex Mateo",
                            "email": "alex@example.com",
                            "type": "user"
                          },
                          "updated_at": "2026-04-12T10:30:00Z"
                        },
                        {
                          "uuid": "b2c3d4e5-6789-01bc-defa-222222222222",
                          "workflow_id": "b2c3d4e5-6789-01bc-defa-222222222222",
                          "workflow_label": "Full Verification + AML",
                          "workflow_type": "kyc",
                          "is_default": false,
                          "is_archived": false,
                          "is_white_label_enabled": false,
                          "total_price": 0.25,
                          "min_price": 0.25,
                          "max_price": 0.25,
                          "features": "OCR + LIVENESS + FACE_MATCH + AML",
                          "is_simple_workflow": true,
                          "is_editable": true,
                          "workflow_url": "https://verify.didit.me/u/Aq3kPOx8RWG3UAz5ZRQGVQ",
                          "max_retry_attempts": 3,
                          "retry_window_days": 7,
                          "session_expiration_time": 604800,
                          "version": 1,
                          "status": "draft",
                          "has_draft": true,
                          "created_by": null,
                          "updated_at": "2026-04-15T18:05:21Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나, 형식이 잘못되었거나, 만료되었거나, 다른 애플리케이션에 속해 있습니다. 본문: `{\"detail\": \"You do not have permission to perform this action.\"}`. [Auth API](/ko/auth-api/get-credentials)를 통해 토큰을 갱신하고 다시 시도해 주세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. 지수 백오프로 재시도하고 `Retry-After` 헤더가 있는 경우 이를 준수하세요."
          },
          "500": {
            "description": "목록을 생성하는 동안 예기치 않은 서버 오류가 발생했습니다. 요청을 안전하게 재시도할 수 있습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET 'https://verification.didit.me/v3/workflows/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Accept: application/json'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.workflows.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.workflows.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Workflows.ListAutoPaging(ctx, didit.WorkflowsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.workflows().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->workflows->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.workflows.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Workflows.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "summary": "워크플로 생성",
        "description": "단순한 워크플로를 생성합니다. `features`를 실행 순서대로 전송하십시오(순서 지정 규칙 적용). 기본값은 `published` v1입니다. 본문에는 `SimpleWorkflowRequest`에 나열된 필드만 허용됩니다. 다른 모든 키(`workflow_type` 포함)는 400으로 거부됩니다. 멱등성이 없습니다. 각 호출은 새 워크플로를 생성합니다. 애플리케이션당 최대 50개의 워크플로를 지원합니다.",
        "operationId": "create_workflow",
        "x-didit-sdk": {
          "resource": "workflows",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Workflows"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimpleWorkflowRequest"
              },
              "examples": {
                "Simple KYC": {
                  "summary": "신분증 인증, 라이브니스 감지 및 얼굴 대조 선형 워크플로",
                  "value": {
                    "workflow_label": "Standard KYC",
                    "features": [
                      {
                        "feature": "OCR",
                        "config": {
                          "duplicated_user_action": "review"
                        }
                      },
                      {
                        "feature": "LIVENESS",
                        "config": {
                          "face_liveness_method": "passive"
                        }
                      },
                      {
                        "feature": "FACE_MATCH",
                        "config": {
                          "face_match_score_decline_threshold": 40,
                          "face_match_score_review_threshold": 60
                        }
                      }
                    ]
                  }
                },
                "KYC + AML": {
                  "summary": "신분증 인증 후 AML 실행",
                  "value": {
                    "workflow_label": "KYC with AML",
                    "features": [
                      {
                        "feature": "OCR"
                      },
                      {
                        "feature": "AML",
                        "config": {
                          "aml_score_review_threshold": 70,
                          "aml_score_approve_threshold": 30
                        }
                      }
                    ]
                  }
                },
                "Questionnaire workflow": {
                  "summary": "POST /v3/questionnaires/로 생성된 설문지 실행",
                  "value": {
                    "workflow_label": "Source of Funds",
                    "features": [
                      {
                        "feature": "QUESTIONNAIRE",
                        "config": {
                          "questionnaire_uuid": "11111111-2222-3333-4444-555555555555",
                          "review_questionnaire_manually": true
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "워크플로가 생성되었습니다. 응답 본문은 축약된 목록 항목이 아닌, 전체 워크플로 구성(`GET /v3/workflows/{settings_uuid}/`에서 반환되는 동일한 원시 `VerificationSettings` 직렬화 형태: 모든 기능 토글, 임계값, 작업 및 생성된 `workflow_graph`를 포함한 약 190개 필드)입니다. 나중에 세션 생성 호출에서 참조할 수 있도록 `uuid`(`workflow_id`로도 제공됨)를 저장하십시오. 참고: `features`는 `\" + \"`로 연결된 문자열이며 가격은 JSON 숫자입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowDetail"
                },
                "examples": {
                  "Created (abbreviated)": {
                    "summary": "전체 구성 객체의 주요 필드",
                    "value": {
                      "uuid": "c3d4e5f6-7890-12cd-ef34-333333333333",
                      "workflow_id": "c3d4e5f6-7890-12cd-ef34-333333333333",
                      "workflow_label": "Standard KYC",
                      "workflow_type": null,
                      "is_default": false,
                      "is_archived": false,
                      "total_price": 0.15,
                      "min_price": 0.15,
                      "max_price": 0.15,
                      "features": "OCR + LIVENESS + FACE_MATCH",
                      "is_simple_workflow": false,
                      "is_editable": false,
                      "workflow_url": "https://verify.didit.me/u/w9TkPOx8RWG3UAz5ZRQGVQ",
                      "workflow_graph": {
                        "start_node": "ocr",
                        "nodes": "... one node per feature plus a final status node ..."
                      },
                      "max_retry_attempts": 3,
                      "retry_window_days": 7,
                      "session_expiration_time": 604800,
                      "version": 1,
                      "status": "published",
                      "published_at": "2026-05-17T10:30:00Z",
                      "created_at": "2026-05-17T10:30:00Z",
                      "updated_at": "2026-05-17T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 일반적인 원인: 허용된 화이트리스트 외의 최상위 키(예: `workflow_type`), 알 수 없는 `feature` 값, 종속성보다 앞에 배치된 기능(예: `OCR` 앞에 `FACE_MATCH`), 첫 번째 단계로 사용된 수동적 기능(`AML`, `IP_ANALYSIS`, `DATABASE_VALIDATION`, `KYB_KEY_PEOPLE`), 해당 애플리케이션에 존재하지 않는 `config.questionnaire_uuid`를 가진 `QUESTIONNAIRE` 기능, 서명할 문서 없이 프로덕션에 배포되는 `SIGNATURE` 기능, Advanced(AES)를 사용할 수 없는 상태에서 `signature_level: \"aes\"`로 설정된 `SIGNATURE` 기능(`aes_not_available`, 워크플로의 `signature_availability` 참조), 또는 범위를 벗어난 임계값입니다. 본문은 DRF 유효성 검사 오류 객체이며, 키는 필드 이름이고 값은 사람이 읽을 수 있는 메시지 배열입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Advanced (AES) not available": {
                    "value": {
                      "features": {
                        "signature_level": [
                          "Node 'signature': Advanced (AES) is not available yet (aes_not_available)."
                        ]
                      }
                    }
                  },
                  "Signature step with no document": {
                    "value": {
                      "features": {
                        "non_field_errors": [
                          "Node 'signature': Add a document to sign, or let each session bring its own."
                        ]
                      }
                    }
                  },
                  "Missing feature": {
                    "value": {
                      "features": [
                        "At least one feature is required."
                      ]
                    }
                  },
                  "Unknown top-level field": {
                    "value": {
                      "workflow_type": [
                        "The v3 workflow API only accepts `workflow_label`, `is_default`, `status`, `features`, `is_white_label_enabled`, `is_desktop_allowed`, `max_retry_attempts`, `retry_window_days`, `session_expiration_time`, `face_liveness_max_attempts`, `face_match_max_attempts`."
                      ]
                    }
                  },
                  "Unknown feature": {
                    "value": {
                      "features": [
                        "Invalid feature 'FOO'. Allowed values: AGE_ESTIMATION, AML, DATABASE_VALIDATION, EMAIL_VERIFICATION, FACE_MATCH, IP_ANALYSIS, KYB_DOCUMENTS, KYB_KEY_PEOPLE, KYB_REGISTRY, LIVENESS, NFC, OCR, PHONE_VERIFICATION, PROOF_OF_ADDRESS, QUESTIONNAIRE."
                      ]
                    }
                  },
                  "Ordering": {
                    "value": {
                      "features": [
                        "Feature 'FACE_MATCH' must appear after one of: OCR."
                      ]
                    }
                  },
                  "Questionnaire not found": {
                    "value": {
                      "features": "Questionnaire '11111111-2222-3333-4444-555555555555' was not found for this application. Create the questionnaire first, then use its questionnaire_id."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나, 형식이 잘못되었거나, 만료되었거나, 다른 애플리케이션으로 스코프가 지정되었습니다. [Auth API](/ko/auth-api/get-credentials)를 통해 갱신하고 다시 시도해 주세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "지원되지 않는 미디어 유형입니다. `Content-Type: application/json`으로 설정하고 JSON 본문을 전송하십시오."
          },
          "429": {
            "description": "속도 제한을 초과했습니다. 지수 백오프로 재시도하세요."
          },
          "500": {
            "description": "워크플로를 생성하는 동안 예기치 않은 서버 오류가 발생했습니다. 안전하게 재시도할 수 있습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/workflows/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"workflow_label\": \"Standard KYC\",\n    \"features\": [\n      {\"feature\": \"OCR\"},\n      {\"feature\": \"LIVENESS\", \"config\": {\"face_liveness_method\": \"passive\"}},\n      {\"feature\": \"FACE_MATCH\", \"config\": {\"face_match_score_decline_threshold\": 40, \"face_match_score_review_threshold\": 60}}\n    ]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.workflows.create(\n    workflow_label=\"Standard KYC\",\n    features=[{\n        \"feature\": \"OCR\",\n        \"config\": {\"duplicated_user_action\": \"review\"},\n    }, {\n        \"feature\": \"LIVENESS\",\n        \"config\": {\"face_liveness_method\": \"passive\"},\n    }, {\n        \"feature\": \"FACE_MATCH\",\n        \"config\": {\"face_match_score_decline_threshold\": 40, \"face_match_score_review_threshold\": 60},\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.workflows.create({\n  workflow_label: \"Standard KYC\",\n  features: [{\n    feature: \"OCR\",\n    config: { duplicated_user_action: \"review\" },\n  }, {\n    feature: \"LIVENESS\",\n    config: { face_liveness_method: \"passive\" },\n  }, {\n    feature: \"FACE_MATCH\",\n    config: { face_match_score_decline_threshold: 40, face_match_score_review_threshold: 60 },\n  }],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Workflows.Create(ctx, didit.SimpleWorkflowRequest{\n\tWorkflowLabel: didit.String(\"Standard KYC\"),\n\tFeatures: []didit.SimpleWorkflowFeature{{\n\t\tFeature: \"OCR\",\n\t\tConfig:  didit.Some(map[string]any{\"duplicated_user_action\": \"review\"}),\n\t}, {\n\t\tFeature: \"LIVENESS\",\n\t\tConfig:  didit.Some(map[string]any{\"face_liveness_method\": \"passive\"}),\n\t}, {\n\t\tFeature: \"FACE_MATCH\",\n\t\tConfig:  didit.Some(map[string]any{\"face_match_score_decline_threshold\": 40, \"face_match_score_review_threshold\": 60}),\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SimpleWorkflowFeature;\nimport me.didit.types.SimpleWorkflowRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.workflows().create(SimpleWorkflowRequest.builder()\n        .workflowLabel(\"Standard KYC\")\n        .features(List.of(\n                SimpleWorkflowFeature.builder()\n                        .feature(SimpleWorkflowFeature.Feature.of(\"OCR\"))\n                        .config(Map.of(\"duplicated_user_action\", \"review\"))\n                        .build(),\n                SimpleWorkflowFeature.builder()\n                        .feature(SimpleWorkflowFeature.Feature.of(\"LIVENESS\"))\n                        .config(Map.of(\"face_liveness_method\", \"passive\"))\n                        .build(),\n                SimpleWorkflowFeature.builder()\n                        .feature(SimpleWorkflowFeature.Feature.of(\"FACE_MATCH\"))\n                        .config(Map.of(\"face_match_score_decline_threshold\", 40, \"face_match_score_review_threshold\", 60))\n                        .build()))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->workflows->create([\n    'workflow_label' => 'Standard KYC',\n    'features' => [[\n        'feature' => 'OCR',\n        'config' => ['duplicated_user_action' => 'review'],\n    ], [\n        'feature' => 'LIVENESS',\n        'config' => ['face_liveness_method' => 'passive'],\n    ], [\n        'feature' => 'FACE_MATCH',\n        'config' => ['face_match_score_decline_threshold' => 40, 'face_match_score_review_threshold' => 60],\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.workflows.create(\n  workflow_label: \"Standard KYC\",\n  features: [{\n    feature: \"OCR\",\n    config: { duplicated_user_action: \"review\" },\n  }, {\n    feature: \"LIVENESS\",\n    config: { face_liveness_method: \"passive\" },\n  }, {\n    feature: \"FACE_MATCH\",\n    config: { face_match_score_decline_threshold: 40, face_match_score_review_threshold: 60 },\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Workflows.CreateAsync(new SimpleWorkflowRequest\n{\n    WorkflowLabel = \"Standard KYC\",\n    Features = new SimpleWorkflowFeature[]\n    {\n        new()\n        {\n            Feature = \"OCR\",\n            Config = new Dictionary<string, object> { [\"duplicated_user_action\"] = \"review\" },\n        },\n        new()\n        {\n            Feature = \"LIVENESS\",\n            Config = new Dictionary<string, object> { [\"face_liveness_method\"] = \"passive\" },\n        },\n        new()\n        {\n            Feature = \"FACE_MATCH\",\n            Config = new Dictionary<string, object> { [\"face_match_score_decline_threshold\"] = 40, [\"face_match_score_review_threshold\"] = 60 },\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/workflows/{settings_uuid}/": {
      "get": {
        "summary": "워크플로 가져오기",
        "description": "`settings_uuid`로 특정 워크플로 버전의 전체 구성(기능 토글, 임계값, 허용된 문서, 그래프, 재시도 정책, 콜백 및 요금)을 가져옵니다.",
        "operationId": "get_workflow",
        "x-didit-sdk": {
          "resource": "workflows",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Workflows"
        ],
        "parameters": [
          {
            "name": "settings_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "워크플로의 버전별 UUID입니다(목록 endpoint에서 반환되는 `uuid` 값). 워크플로의 각 버전에는 자체 `settings_uuid`가 있습니다."
          }
        ],
        "responses": {
          "200": {
            "description": "전체 워크플로 구성입니다. 형태는 원시 `VerificationSettings` 직렬화 결과(~190개 필드: 모든 기능 토글, 임계값, 경고 작업, 허용 문서 구성, `workflow_graph`, 재시도 정책, 콜백 및 요금)입니다. 아래 예시는 축약되었습니다. 참고: `features`는 `\" + \"`로 연결된 문자열(예: `\"OCR + LIVENESS\"`)이고, 가격은 JSON 숫자이며, `is_editable`은 `draft` 버전에 대해서만 `true`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowDetail"
                },
                "examples": {
                  "KYC workflow with face match (abbreviated)": {
                    "value": {
                      "uuid": "a1b2c3d4-5678-90ab-cdef-111111111111",
                      "workflow_id": "a1b2c3d4-5678-90ab-cdef-111111111111",
                      "workflow_label": "Standard KYC",
                      "workflow_type": "kyc",
                      "is_default": true,
                      "is_archived": false,
                      "is_liveness_enabled": true,
                      "face_liveness_method": "passive",
                      "face_liveness_score_decline_threshold": 50,
                      "face_liveness_score_review_threshold": 70,
                      "is_face_match_enabled": true,
                      "face_match_score_decline_threshold": 40,
                      "face_match_score_review_threshold": 60,
                      "is_aml_enabled": false,
                      "is_phone_verification_enabled": false,
                      "is_email_verification_enabled": false,
                      "is_database_validation_enabled": false,
                      "is_ip_analysis_enabled": false,
                      "is_nfc_enabled": false,
                      "duplicated_user_action": "no_action",
                      "documents_allowed": {
                        "ESP": {
                          "P": {
                            "sides": 1,
                            "enabled": 1,
                            "subtypes": [
                              "EPASSPORT",
                              "PASSPORT_GENERIC"
                            ],
                            "preferred_characters": "latin",
                            "expiration_check_mode": "strict"
                          }
                        }
                      },
                      "max_retry_attempts": 3,
                      "retry_window_days": 7,
                      "session_expiration_time": 604800,
                      "version": 2,
                      "status": "published",
                      "published_at": "2026-04-12T10:30:00Z",
                      "is_simple_workflow": false,
                      "is_editable": false,
                      "workflow_url": "https://verify.didit.me/u/_yljPOx8RWG3UAz5ZRQGVQ",
                      "total_price": 0.15,
                      "min_price": 0.15,
                      "max_price": 0.15,
                      "features": "OCR + LIVENESS + FACE_MATCH",
                      "created_at": "2025-01-15T10:30:00Z",
                      "updated_at": "2026-04-12T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나, 형식이 잘못되었거나, 만료되었거나, 다른 애플리케이션으로 범위가 지정되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "인증된 애플리케이션에 이 `settings_uuid`를 가진 워크플로가 존재하지 않습니다. UUID가 잘못되었거나 다른 애플리케이션에 속해 있습니다. Didit은 애플리케이션 간 레코드 존재 여부 유출을 방지하기 위해 두 경우를 의도적으로 구분하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. 지수 백오프로 재시도하세요."
          },
          "500": {
            "description": "예기치 않은 서버 오류가 발생했습니다. 안전하게 재시도할 수 있습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET 'https://verification.didit.me/v3/workflows/a1b2c3d4-5678-90ab-cdef-111111111111/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.workflows.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.workflows.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Workflows.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.workflows().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->workflows->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.workflows.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Workflows.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "patch": {
        "summary": "워크플로 업데이트",
        "description": "워크플로를 업데이트합니다. 버전 관리는 전송하는 `status` 필드와 해당 버전의 현재 상태에 따라 달라집니다. (1) **게시된(published)** 버전에 `status` 없음 → 게시된 버전이 해당 위치에서 직접 업데이트됨(동일한 `uuid`, 동일한 `version`); (2) **임시 저장(draft)** 버전에 `status` 없음 → 임시 저장 버전이 업데이트되고 즉시 게시됨; (3) **게시된** 버전에 `status: \"published\"` 지정 → 동일한 `workflow_id` 아래에 새로운 게시 버전이 생성되어(새 `uuid`, `version` + 1) 반환되며 그룹의 기존 임시 저장 버전은 삭제됨; (4) `status: \"draft\"`는 임시 저장 상태를 유지하지만(자동 저장), 이미 게시된 버전에서는 400 오류와 함께 거부됨(`\"Cannot revert a published version to draft.\"`). 본문은 생성 시와 동일하게 엄격한 필드 허용 목록을 적용하므로 알 수 없는 키는 400 오류로 거부됩니다.",
        "operationId": "update_workflow",
        "x-didit-sdk": {
          "resource": "workflows",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Workflows"
        ],
        "parameters": [
          {
            "name": "settings_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "업데이트할 워크플로의 버전별 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimpleWorkflowUpdateRequest"
              },
              "examples": {
                "Replace features": {
                  "summary": "원하는 전체 기능 순서를 전송합니다",
                  "value": {
                    "features": [
                      {
                        "feature": "OCR"
                      },
                      {
                        "feature": "AML"
                      }
                    ]
                  }
                },
                "Rename": {
                  "summary": "워크플로 이름 바꾸기",
                  "value": {
                    "workflow_label": "Premium KYC"
                  }
                },
                "Set as default": {
                  "summary": "이 워크플로를 애플리케이션의 기본값으로 설정",
                  "value": {
                    "is_default": true
                  }
                },
                "Update config": {
                  "summary": "기능 설정 변경",
                  "value": {
                    "features": [
                      {
                        "feature": "OCR"
                      },
                      {
                        "feature": "LIVENESS",
                        "config": {
                          "face_liveness_method": "passive"
                        }
                      }
                    ]
                  }
                },
                "Publish a draft": {
                  "summary": "초안을 게시 상태로 승격",
                  "value": {
                    "status": "published"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "워크플로가 업데이트되었습니다. 본문은 결과 버전의 전체 구성입니다(`GET /v3/workflows/{settings_uuid}/`와 동일한 원시 `VerificationSettings` 형태). 업데이트로 인해 새 버전이 생성된 경우(게시된 행에 `status: \"published\"` 전송), 반환된 `uuid` 및 `version`은 패치한 항목과 다릅니다. 후속 호출에는 반환된 `uuid`를 사용하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowDetail"
                }
              }
            }
          },
          "400": {
            "description": "검증 오류 — 허용 목록(whitelist) 외의 최상위 키, 알 수 없는 기능, 유효하지 않은 순서, 범위를 벗어난 임계값, 존재하지 않는 설문지 참조, 서명할 문서 없이 프로덕션에 배포되려는 `SIGNATURE` 기능, Advanced(AES)를 사용할 수 없는 상태에서 `signature_level: \"aes\"`로 설정된 새로운 `SIGNATURE` 기능(`aes_not_available`, 워크플로의 `signature_availability` 참조. 이미 `aes`를 저장하고 있는 단계는 유지됨), 또는 게시된 버전에 대해 전송된 `status: \"draft\"`(`\"Cannot revert a published version to draft.\"`). 응답 본문은 필드 이름을 키로 하는 DRF 검증 오류입니다."
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "인증된 애플리케이션에 이 `settings_uuid`를 가진 워크플로가 존재하지 않습니다."
          },
          "415": {
            "description": "지원되지 않는 미디어 유형입니다. `Content-Type: application/json`으로 설정하십시오."
          },
          "429": {
            "description": "속도 제한을 초과했습니다. 지수 백오프로 재시도하세요."
          },
          "500": {
            "description": "예기치 않은 서버 오류가 발생했습니다. 안전하게 재시도할 수 있습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/workflows/a1b2c3d4-5678-90ab-cdef-111111111111/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"workflow_label\": \"Premium KYC\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.workflows.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    features=[{\n        \"feature\": \"OCR\",\n    }, {\n        \"feature\": \"AML\",\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.workflows.update(\"11111111-2222-3333-4444-555555555555\", {\n  features: [{\n    feature: \"OCR\",\n  }, {\n    feature: \"AML\",\n  }],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Workflows.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SimpleWorkflowUpdateRequest{\n\tFeatures: didit.Some([]didit.SimpleWorkflowFeature{{\n\t\tFeature: \"OCR\",\n\t}, {\n\t\tFeature: \"AML\",\n\t}}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SimpleWorkflowFeature;\nimport me.didit.types.SimpleWorkflowUpdateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.workflows().update(\"11111111-2222-3333-4444-555555555555\", SimpleWorkflowUpdateRequest.builder()\n        .features(List.of(\n                SimpleWorkflowFeature.builder()\n                        .feature(SimpleWorkflowFeature.Feature.of(\"OCR\"))\n                        .build(),\n                SimpleWorkflowFeature.builder()\n                        .feature(SimpleWorkflowFeature.Feature.of(\"AML\"))\n                        .build()))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->workflows->update('11111111-2222-3333-4444-555555555555', [\n    'features' => [[\n        'feature' => 'OCR',\n    ], [\n        'feature' => 'AML',\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.workflows.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  features: [{\n    feature: \"OCR\",\n  }, {\n    feature: \"AML\",\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Workflows.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new SimpleWorkflowUpdateRequest\n{\n    Features = new SimpleWorkflowFeature[]\n    {\n        new()\n        {\n            Feature = \"OCR\",\n        },\n        new()\n        {\n            Feature = \"AML\",\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "summary": "워크플로 삭제",
        "description": "워크플로 버전 하나를 영구적으로 삭제합니다(실행 취소 불가). 기존 세션은 인증 결과를 유지하지만 워크플로 참조는 초기화됩니다. 동일한 `workflow_id` 그룹의 다른 버전은 삭제되지 않습니다.",
        "operationId": "delete_workflow",
        "x-didit-sdk": {
          "resource": "workflows",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Workflows"
        ],
        "parameters": [
          {
            "name": "settings_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "삭제할 워크플로의 버전별 UUID입니다."
          }
        ],
        "responses": {
          "204": {
            "description": "워크플로가 삭제되었습니다. 응답 본문은 비어 있습니다."
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "인증된 애플리케이션에 이 `settings_uuid`를 가진 워크플로가 존재하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. 지수 백오프로 재시도하세요."
          },
          "500": {
            "description": "예기치 않은 서버 오류가 발생했습니다. 안전하게 재시도할 수 있습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/workflows/a1b2c3d4-5678-90ab-cdef-111111111111/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.workflows.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.workflows.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Workflows.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.workflows().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->workflows->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.workflows.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Workflows.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ]
      }
    },
    "/v3/questionnaires/": {
      "get": {
        "summary": "설문지 목록 조회",
        "description": "설문지 목록을 최신순으로 limit/offset 페이지네이션 응답 형식(`{count, next, previous, results}`, 기본 페이지 크기 50)으로 조회합니다. 각 행은 하나의 버전입니다. `questionnaire_group_id`는 최신 `published` 버전으로 확인되는 고정 그룹 ID입니다.",
        "operationId": "list_questionnaires",
        "x-didit-sdk": {
          "resource": "questionnaires",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Questionnaires"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50
            },
            "description": "페이지 크기(페이지당 설문지 수)입니다."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "반환되는 첫 번째 설문지 전에 건너뛸 행 수입니다."
          }
        ],
        "responses": {
          "200": {
            "description": "`created_at` 내림차순으로 정렬되어 페이지네이션 엔벨로프에 래핑된 설문지 페이지 하나입니다. `results`의 각 항목은 `QuestionnaireListItem`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "해당 애플리케이션의 총 설문지 버전 수입니다."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "다음 페이지의 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "이전 페이지의 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/QuestionnaireListItem"
                      }
                    }
                  }
                },
                "examples": {
                  "One questionnaire": {
                    "summary": "간단한 이중 언어 설문지",
                    "value": {
                      "count": 1,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "11111111-2222-3333-4444-555555555555",
                          "title": "KYC Questionnaire",
                          "description": "Additional verification questions",
                          "languages": [
                            "en",
                            "es"
                          ],
                          "default_language": "en",
                          "is_active": true,
                          "is_simple_questionnaire": true,
                          "created_at": "2026-04-23T09:55:00Z",
                          "updated_at": "2026-04-23T10:00:00Z",
                          "question_types": [
                            "SHORT_TEXT",
                            "MULTIPLE_CHOICE",
                            "FILE_UPLOAD"
                          ],
                          "workflow_names": [],
                          "questionnaire_group_id": "11111111-2222-3333-4444-555555555555",
                          "version": 1,
                          "status": "published",
                          "published_at": "2026-04-23T10:00:00Z",
                          "is_editable": false
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나, 형식이 잘못되었거나, 만료되었거나, 다른 애플리케이션으로 범위가 지정되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. 지수 백오프로 재시도하세요."
          },
          "500": {
            "description": "목록을 생성하는 동안 예기치 않은 서버 오류가 발생했습니다. 안전하게 재시도할 수 있습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET 'https://verification.didit.me/v3/questionnaires/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.questionnaires.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.questionnaires.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Questionnaires.ListAutoPaging(ctx, didit.QuestionnairesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.questionnaires().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->questionnaires->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.questionnaires.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Questionnaires.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "summary": "설문지 생성",
        "description": "단순한 선형 설문지를 생성합니다. `form_elements`를 표시 순서대로 전송하십시오. 분기 및 반복 가능한 그룹은 콘솔을 사용해야 합니다. 기본값은 `published` v1입니다.",
        "operationId": "create_questionnaire",
        "x-didit-sdk": {
          "resource": "questionnaires",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Questionnaires"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimpleQuestionnaireRequest"
              },
              "examples": {
                "Simple": {
                  "summary": "기본 설문지",
                  "value": {
                    "title": "Customer Onboarding",
                    "description": "Additional information needed for verification",
                    "default_language": "en",
                    "languages": [
                      "en"
                    ],
                    "is_active": true,
                    "form_elements": [
                      {
                        "id": "occupation",
                        "element_type": "short_text",
                        "label": {
                          "en": "What is your occupation?"
                        },
                        "is_required": true,
                        "placeholder": {
                          "en": "Software engineer"
                        }
                      },
                      {
                        "id": "source_of_funds",
                        "element_type": "multiple_choice",
                        "label": {
                          "en": "Source of funds"
                        },
                        "is_required": true,
                        "options": [
                          {
                            "value": "employment",
                            "label": {
                              "en": "Employment"
                            }
                          },
                          {
                            "value": "business",
                            "label": {
                              "en": "Business"
                            }
                          },
                          {
                            "value": "investments",
                            "label": {
                              "en": "Investments"
                            }
                          },
                          {
                            "value": "other",
                            "label": {
                              "en": "Other"
                            }
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "설문지가 생성되었습니다. 응답에는 `questionnaire_id`가 포함됩니다. 워크플로 또는 향후 업데이트/삭제 호출에서 이 설문지를 참조할 수 있도록 저장하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuestionnaireDetail"
                },
                "examples": {
                  "Created": {
                    "value": {
                      "questionnaire_id": "11111111-2222-3333-4444-555555555555",
                      "title": "Customer Onboarding",
                      "description": "Additional information needed for verification",
                      "languages": [
                        "en"
                      ],
                      "default_language": "en",
                      "is_active": true,
                      "is_simple_questionnaire": true,
                      "graph": {
                        "start_node": "occupation",
                        "nodes": {
                          "occupation": {
                            "element_type": "SHORT_TEXT",
                            "is_required": true,
                            "title": {
                              "en": "What is your occupation?"
                            },
                            "next": "source_of_funds"
                          },
                          "source_of_funds": {
                            "element_type": "MULTIPLE_CHOICE",
                            "is_required": true,
                            "title": {
                              "en": "Source of funds"
                            },
                            "choices": [
                              {
                                "value": "employment",
                                "label": {
                                  "en": "Employment"
                                }
                              },
                              {
                                "value": "business",
                                "label": {
                                  "en": "Business"
                                }
                              }
                            ],
                            "next": null
                          }
                        }
                      },
                      "sections": [],
                      "questionnaire_group_id": "11111111-2222-3333-4444-555555555555",
                      "version": 1,
                      "status": "published",
                      "published_at": "2026-04-23T10:00:00Z",
                      "is_editable": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 일반적인 원인: 알 수 없는 `element_type`, `languages` 중 하나에 대한 번역이 누락된 번역 가능 필드, `languages`에 `en` 누락, `default_language`가 `languages`에 없음, `label`이 없는 옵션, `branches`/`required_if`/`repeatable_config`가 포함된 질문(이 endpoint에서는 지원되지 않음), 또는 `form_elements` 대신 원시 `graph` 전송입니다. 본문은 필드 이름을 키로 하는 DRF 유효성 검사 오류입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Graph not accepted": {
                    "value": {
                      "graph": "The v3 questionnaire API only accepts simple `form_elements`, not `graph`."
                    }
                  },
                  "Missing label": {
                    "value": {
                      "form_elements": [
                        {
                          "label": [
                            "This field is required."
                          ]
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나, 형식이 잘못되었거나, 만료되었거나, 다른 애플리케이션으로 범위가 지정되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "지원되지 않는 미디어 유형입니다. `Content-Type: application/json`으로 설정하고 JSON 본문을 전송하십시오."
          },
          "429": {
            "description": "속도 제한을 초과했습니다. 지수 백오프로 재시도하세요."
          },
          "500": {
            "description": "설문지를 생성하는 동안 예기치 않은 서버 오류가 발생했습니다. 안전하게 재시도할 수 있습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/questionnaires/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"title\": \"Customer Onboarding\",\n    \"default_language\": \"en\",\n    \"languages\": [\"en\"],\n    \"form_elements\": [\n      {\n        \"id\": \"occupation\",\n        \"element_type\": \"short_text\",\n        \"label\": {\"en\": \"What is your occupation?\"},\n        \"is_required\": true\n      }\n    ]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.questionnaires.create(\n    title=\"Customer Onboarding\",\n    description=\"Additional information needed for verification\",\n    languages=[\"en\"],\n    default_language=\"en\",\n    is_active=True,\n    form_elements=[{\n        \"id\": \"occupation\",\n        \"element_type\": \"short_text\",\n        \"label\": {\"en\": \"What is your occupation?\"},\n        \"placeholder\": {\"en\": \"Software engineer\"},\n        \"is_required\": True,\n    }, {\n        \"id\": \"source_of_funds\",\n        \"element_type\": \"multiple_choice\",\n        \"label\": {\"en\": \"Source of funds\"},\n        \"is_required\": True,\n        \"options\": [{\n            \"value\": \"employment\",\n            \"label\": {\"en\": \"Employment\"},\n        }, {\n            \"value\": \"business\",\n            \"label\": {\"en\": \"Business\"},\n        }, {\n            \"value\": \"investments\",\n            \"label\": {\"en\": \"Investments\"},\n        }, {\n            \"value\": \"other\",\n            \"label\": {\"en\": \"Other\"},\n        }],\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.questionnaires.create({\n  title: \"Customer Onboarding\",\n  description: \"Additional information needed for verification\",\n  languages: [\"en\"],\n  default_language: \"en\",\n  is_active: true,\n  form_elements: [{\n    id: \"occupation\",\n    element_type: \"short_text\",\n    label: { en: \"What is your occupation?\" },\n    placeholder: { en: \"Software engineer\" },\n    is_required: true,\n  }, {\n    id: \"source_of_funds\",\n    element_type: \"multiple_choice\",\n    label: { en: \"Source of funds\" },\n    is_required: true,\n    options: [{\n      value: \"employment\",\n      label: { en: \"Employment\" },\n    }, {\n      value: \"business\",\n      label: { en: \"Business\" },\n    }, {\n      value: \"investments\",\n      label: { en: \"Investments\" },\n    }, {\n      value: \"other\",\n      label: { en: \"Other\" },\n    }],\n  }],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Questionnaires.Create(ctx, didit.SimpleQuestionnaireRequest{\n\tTitle:           \"Customer Onboarding\",\n\tDescription:     didit.String(\"Additional information needed for verification\"),\n\tLanguages:       []string{\"en\"},\n\tDefaultLanguage: didit.String(\"en\"),\n\tIsActive:        didit.Bool(true),\n\tFormElements: []didit.SimpleQuestionnaireElement{{\n\t\tID:          didit.String(\"occupation\"),\n\t\tElementType: \"short_text\",\n\t\tLabel:       map[string]string{\"en\": \"What is your occupation?\"},\n\t\tPlaceholder: didit.Some(map[string]string{\"en\": \"Software engineer\"}),\n\t\tIsRequired:  didit.Bool(true),\n\t}, {\n\t\tID:          didit.String(\"source_of_funds\"),\n\t\tElementType: \"multiple_choice\",\n\t\tLabel:       map[string]string{\"en\": \"Source of funds\"},\n\t\tIsRequired:  didit.Bool(true),\n\t\tOptions: didit.Some([]didit.SimpleQuestionnaireElementOptions{{\n\t\t\tValue: didit.String(\"employment\"),\n\t\t\tLabel: map[string]string{\"en\": \"Employment\"},\n\t\t}, {\n\t\t\tValue: didit.String(\"business\"),\n\t\t\tLabel: map[string]string{\"en\": \"Business\"},\n\t\t}, {\n\t\t\tValue: didit.String(\"investments\"),\n\t\t\tLabel: map[string]string{\"en\": \"Investments\"},\n\t\t}, {\n\t\t\tValue: didit.String(\"other\"),\n\t\t\tLabel: map[string]string{\"en\": \"Other\"},\n\t\t}}),\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SimpleQuestionnaireElement;\nimport me.didit.types.SimpleQuestionnaireRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.questionnaires().create(SimpleQuestionnaireRequest.builder()\n        .title(\"Customer Onboarding\")\n        .description(\"Additional information needed for verification\")\n        .languages(List.of(\"en\"))\n        .defaultLanguage(\"en\")\n        .isActive(true)\n        .formElements(List.of(\n                SimpleQuestionnaireElement.builder()\n                        .id(\"occupation\")\n                        .elementType(SimpleQuestionnaireElement.ElementType.of(\"short_text\"))\n                        .label(Map.of(\"en\", \"What is your occupation?\"))\n                        .placeholder(Map.of(\"en\", \"Software engineer\"))\n                        .isRequired(true)\n                        .build(),\n                SimpleQuestionnaireElement.builder()\n                        .id(\"source_of_funds\")\n                        .elementType(SimpleQuestionnaireElement.ElementType.of(\"multiple_choice\"))\n                        .label(Map.of(\"en\", \"Source of funds\"))\n                        .isRequired(true)\n                        .options(List.of(\n                                SimpleQuestionnaireElement.Options.builder()\n                                        .value(\"employment\")\n                                        .label(Map.of(\"en\", \"Employment\"))\n                                        .build(),\n                                SimpleQuestionnaireElement.Options.builder()\n                                        .value(\"business\")\n                                        .label(Map.of(\"en\", \"Business\"))\n                                        .build(),\n                                SimpleQuestionnaireElement.Options.builder()\n                                        .value(\"investments\")\n                                        .label(Map.of(\"en\", \"Investments\"))\n                                        .build(),\n                                SimpleQuestionnaireElement.Options.builder()\n                                        .value(\"other\")\n                                        .label(Map.of(\"en\", \"Other\"))\n                                        .build()))\n                        .build()))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->questionnaires->create([\n    'title' => 'Customer Onboarding',\n    'description' => 'Additional information needed for verification',\n    'languages' => ['en'],\n    'default_language' => 'en',\n    'is_active' => true,\n    'form_elements' => [[\n        'id' => 'occupation',\n        'element_type' => 'short_text',\n        'label' => ['en' => 'What is your occupation?'],\n        'placeholder' => ['en' => 'Software engineer'],\n        'is_required' => true,\n    ], [\n        'id' => 'source_of_funds',\n        'element_type' => 'multiple_choice',\n        'label' => ['en' => 'Source of funds'],\n        'is_required' => true,\n        'options' => [[\n            'value' => 'employment',\n            'label' => ['en' => 'Employment'],\n        ], [\n            'value' => 'business',\n            'label' => ['en' => 'Business'],\n        ], [\n            'value' => 'investments',\n            'label' => ['en' => 'Investments'],\n        ], [\n            'value' => 'other',\n            'label' => ['en' => 'Other'],\n        ]],\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.questionnaires.create(\n  title: \"Customer Onboarding\",\n  description: \"Additional information needed for verification\",\n  languages: [\"en\"],\n  default_language: \"en\",\n  is_active: true,\n  form_elements: [{\n    id: \"occupation\",\n    element_type: \"short_text\",\n    label: { en: \"What is your occupation?\" },\n    placeholder: { en: \"Software engineer\" },\n    is_required: true,\n  }, {\n    id: \"source_of_funds\",\n    element_type: \"multiple_choice\",\n    label: { en: \"Source of funds\" },\n    is_required: true,\n    options: [{\n      value: \"employment\",\n      label: { en: \"Employment\" },\n    }, {\n      value: \"business\",\n      label: { en: \"Business\" },\n    }, {\n      value: \"investments\",\n      label: { en: \"Investments\" },\n    }, {\n      value: \"other\",\n      label: { en: \"Other\" },\n    }],\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Questionnaires.CreateAsync(new SimpleQuestionnaireRequest\n{\n    Title = \"Customer Onboarding\",\n    Description = \"Additional information needed for verification\",\n    Languages = new string[] { \"en\" },\n    DefaultLanguage = \"en\",\n    IsActive = true,\n    FormElements = new SimpleQuestionnaireElement[]\n    {\n        new()\n        {\n            Id = \"occupation\",\n            ElementType = \"short_text\",\n            Label = new Dictionary<string, string> { [\"en\"] = \"What is your occupation?\" },\n            Placeholder = new Dictionary<string, string> { [\"en\"] = \"Software engineer\" },\n            IsRequired = true,\n        },\n        new()\n        {\n            Id = \"source_of_funds\",\n            ElementType = \"multiple_choice\",\n            Label = new Dictionary<string, string> { [\"en\"] = \"Source of funds\" },\n            IsRequired = true,\n            Options = new SimpleQuestionnaireElementOptions[]\n            {\n                new()\n                {\n                    Value = \"employment\",\n                    Label = new Dictionary<string, string> { [\"en\"] = \"Employment\" },\n                },\n                new()\n                {\n                    Value = \"business\",\n                    Label = new Dictionary<string, string> { [\"en\"] = \"Business\" },\n                },\n                new()\n                {\n                    Value = \"investments\",\n                    Label = new Dictionary<string, string> { [\"en\"] = \"Investments\" },\n                },\n                new()\n                {\n                    Value = \"other\",\n                    Label = new Dictionary<string, string> { [\"en\"] = \"Other\" },\n                },\n            },\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/questionnaires/{questionnaire_uuid}/": {
      "get": {
        "summary": "설문지 가져오기",
        "description": "`questionnaire_uuid`로 특정 버전에 대한 전체 설문지 세부 정보(제목, `languages`, 표준 `graph`, 파생된 `sections`, 버전 메타데이터)를 가져옵니다.",
        "operationId": "get_questionnaire",
        "x-didit-sdk": {
          "resource": "questionnaires",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Questionnaires"
        ],
        "parameters": [
          {
            "name": "questionnaire_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "설문지의 버전별 UUID입니다(목록 endpoint에서 반환되는 `uuid` 값이며, 상세 endpoint에서는 `questionnaire_id`로도 반환됨)."
          }
        ],
        "responses": {
          "200": {
            "description": "표준 `graph`, 파생된 `sections` 뷰, 버전 메타데이터 및 `is_editable`을 포함한 설문지 전체 세부정보입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuestionnaireDetail"
                },
                "examples": {
                  "Published questionnaire": {
                    "value": {
                      "questionnaire_id": "11111111-2222-3333-4444-555555555555",
                      "title": "Customer Onboarding",
                      "description": "Additional information needed for verification",
                      "languages": [
                        "en"
                      ],
                      "default_language": "en",
                      "is_active": true,
                      "is_simple_questionnaire": true,
                      "graph": {
                        "start_node": "occupation",
                        "nodes": {
                          "occupation": {
                            "element_type": "SHORT_TEXT",
                            "is_required": true,
                            "title": {
                              "en": "What is your occupation?"
                            },
                            "next": "source_of_funds"
                          },
                          "source_of_funds": {
                            "element_type": "MULTIPLE_CHOICE",
                            "is_required": true,
                            "title": {
                              "en": "Source of funds"
                            },
                            "choices": [
                              {
                                "value": "employment",
                                "label": {
                                  "en": "Employment"
                                }
                              },
                              {
                                "value": "business",
                                "label": {
                                  "en": "Business"
                                }
                              }
                            ],
                            "next": null
                          }
                        }
                      },
                      "sections": [
                        {
                          "title": {},
                          "description": {},
                          "items": [
                            {
                              "uuid": "11111111-2222-3333-4444-666666666666",
                              "value": "occupation",
                              "element_type": "SHORT_TEXT",
                              "is_required": true,
                              "title": {
                                "en": "What is your occupation?"
                              }
                            }
                          ]
                        }
                      ],
                      "questionnaire_group_id": "11111111-2222-3333-4444-555555555555",
                      "version": 1,
                      "status": "published",
                      "published_at": "2026-04-23T10:00:00Z",
                      "is_editable": false
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나, 형식이 잘못되었거나, 만료되었거나, 다른 애플리케이션으로 범위가 지정되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "인증된 애플리케이션에 이 `questionnaire_uuid`를 가진 설문지가 존재하지 않습니다. UUID가 잘못되었거나 다른 애플리케이션에 속해 있습니다. API는 두 경우를 의도적으로 구분하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. 지수 백오프로 재시도하세요."
          },
          "500": {
            "description": "예기치 않은 서버 오류가 발생했습니다. 안전하게 재시도할 수 있습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET 'https://verification.didit.me/v3/questionnaires/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.questionnaires.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.questionnaires.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Questionnaires.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.questionnaires().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->questionnaires->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.questionnaires.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Questionnaires.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "patch": {
        "summary": "설문지 업데이트",
        "description": "설문지를 업데이트합니다. 버전 관리는 전송하는 `status` 필드와 해당 버전의 현재 상태에 따라 달라집니다. (1) **게시된(published)** 버전에 `status` 없음 → 게시된 버전이 해당 위치에서 직접 업데이트됨(동일한 `questionnaire_id`, 동일한 `version`); (2) **임시 저장(draft)** 버전에 `status` 없음 → 임시 저장 버전이 업데이트되고 즉시 게시됨; (3) **게시된** 버전에 `status: \"published\"` 지정 → 동일한 `questionnaire_group_id` 아래에 새로운 게시 버전이 생성되어(새 `questionnaire_id`, `version` + 1) 반환되며 그룹의 기존 임시 저장 버전은 삭제됨; (4) `status: \"draft\"`는 임시 저장 상태를 유지하지만(자동 저장), 이미 게시된 버전에서는 400 오류와 함께 거부됨(`\"Cannot revert a published version to draft.\"`).",
        "operationId": "update_questionnaire",
        "x-didit-sdk": {
          "resource": "questionnaires",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Questionnaires"
        ],
        "parameters": [
          {
            "name": "questionnaire_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "업데이트할 설문지의 버전별 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimpleQuestionnaireUpdateRequest"
              },
              "examples": {
                "Rename": {
                  "summary": "설문지 이름 바꾸기",
                  "value": {
                    "title": "Updated Customer Onboarding"
                  }
                },
                "Replace questions": {
                  "summary": "전체 선형 질문 목록 대체",
                  "value": {
                    "form_elements": [
                      {
                        "id": "occupation",
                        "element_type": "short_text",
                        "label": {
                          "en": "What is your occupation?"
                        },
                        "is_required": true
                      },
                      {
                        "id": "source_of_funds",
                        "element_type": "multiple_choice",
                        "label": {
                          "en": "Source of funds"
                        },
                        "options": [
                          {
                            "value": "employment",
                            "label": {
                              "en": "Employment"
                            }
                          },
                          {
                            "value": "business",
                            "label": {
                              "en": "Business"
                            }
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "설문지가 업데이트되었습니다. 본문은 결과 버전의 최신 상태입니다. 제자리에서 업데이트된 버전이거나, 게시된 행에 `status: \"published\"`를 전송했을 때 새로 생성된 게시 버전입니다(이 경우 `questionnaire_id` 및 `version`은 패치한 값과 다릅니다). 응답의 `questionnaire_id`는 버전별 UUID입니다. 안정적인 그룹 식별자가 필요한 경우 `questionnaire_group_id`를 사용하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuestionnaireDetail"
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류 — 알 수 없는 `element_type`, 번역 누락, 지원되지 않는 분기/조건부 필드, `languages`에 `en` 누락, `default_language`가 `languages`에 없음, 레이블이 없는 옵션, 원시 `graph` 전송, 또는 게시된 버전에 `status: \"draft\"` 설정(`\"Cannot revert a published version to draft.\"`). 응답 본문은 필드 이름을 키로 하는 DRF 유효성 검사 오류입니다."
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "인증된 애플리케이션에 이 `questionnaire_uuid`를 가진 설문지가 존재하지 않습니다."
          },
          "415": {
            "description": "지원되지 않는 미디어 유형입니다. `Content-Type: application/json`으로 설정하십시오."
          },
          "429": {
            "description": "속도 제한을 초과했습니다. 지수 백오프로 재시도하세요."
          },
          "500": {
            "description": "예기치 않은 서버 오류가 발생했습니다. 안전하게 재시도할 수 있습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/questionnaires/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"title\": \"Updated Customer Onboarding\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.questionnaires.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    title=\"Updated Customer Onboarding\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.questionnaires.update(\"11111111-2222-3333-4444-555555555555\", {\n  title: \"Updated Customer Onboarding\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Questionnaires.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SimpleQuestionnaireUpdateRequest{\n\tTitle: didit.String(\"Updated Customer Onboarding\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SimpleQuestionnaireUpdateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.questionnaires().update(\"11111111-2222-3333-4444-555555555555\", SimpleQuestionnaireUpdateRequest.builder()\n        .title(\"Updated Customer Onboarding\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->questionnaires->update('11111111-2222-3333-4444-555555555555', [\n    'title' => 'Updated Customer Onboarding',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.questionnaires.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  title: \"Updated Customer Onboarding\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Questionnaires.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new SimpleQuestionnaireUpdateRequest\n{\n    Title = \"Updated Customer Onboarding\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "summary": "설문지 삭제",
        "description": "설문지 버전 하나를 영구적으로 삭제합니다(실행 취소 불가). 이 버전과 연결된 저장된 설문지 응답도 함께 삭제되며, 이를 참조하는 세션은 연결이 해제됩니다. 동일한 그룹의 다른 버전은 삭제되지 않습니다. 이를 참조하던 워크플로는 계속 실행되지만 설문지 단계에서 더 이상 해당 버전을 로드할 수 없습니다.",
        "operationId": "delete_questionnaire",
        "x-didit-sdk": {
          "resource": "questionnaires",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Questionnaires"
        ],
        "parameters": [
          {
            "name": "questionnaire_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "삭제할 설문지의 버전별 UUID입니다."
          }
        ],
        "responses": {
          "204": {
            "description": "설문지가 삭제되었습니다. 응답 본문은 비어 있습니다."
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "인증된 애플리케이션에 이 `questionnaire_uuid`를 가진 설문지가 존재하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. 지수 백오프로 재시도하세요."
          },
          "500": {
            "description": "예기치 않은 서버 오류가 발생했습니다. 안전하게 재시도할 수 있습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/questionnaires/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.questionnaires.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.questionnaires.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Questionnaires.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.questionnaires().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->questionnaires->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.questionnaires.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Questionnaires.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ]
      }
    },
    "/v3/users/": {
      "get": {
        "summary": "사용자 목록 조회",
        "description": "동일한 `vendor_data`(UUID가 아닌 자유 형식 문자열)를 공유하는 KYC 세션으로부터 Didit이 취합한 [사용자](/entities/users) 및 API를 통해 생성된 사용자 목록을 조회합니다. 페이지네이션이 적용되며, `last_session_at` 기준 내림차순으로 정렬됩니다. 이 엔드포인트는 필터링이나 검색 파라미터를 지원하지 않으므로 페이지를 가져온 후 클라이언트 측에서 필터링하십시오.",
        "operationId": "list_users",
        "x-didit-sdk": {
          "resource": "users",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "description": "페이지 크기입니다. 생략 시 기본값은 50입니다. 강제된 최댓값은 없으나 지연 시간을 줄이려면 페이지를 작게 유지하십시오."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "description": "반환할 첫 번째 레코드의 0부터 시작하는 오프셋입니다. 직접 계산하기보다는 이전 페이지의 `next` URL을 따르는 것이 좋습니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/users/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.users.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.users.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Users.ListAutoPaging(ctx, didit.UsersListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.users().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->users->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.users.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Users.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "인증 상태, 세션 수 및 기능 분석 정보가 포함된 페이지 단위로 제공되는 사용자 목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "일치하는 행 수입니다. 최대 100개까지 정확하며, 성능을 위해 그 이상은 100개로 제한됩니다. 마지막 페이지를 감지하는 데 사용하지 마십시오. 대신 `next`가 `null`인지 확인하십시오."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "다음 페이지의 절대 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "이전 페이지의 절대 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/UserListItem"
                      }
                    }
                  }
                },
                "examples": {
                  "Example": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "didit_internal_id": "f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418",
                          "vendor_data": "user-abc-123",
                          "display_name": null,
                          "full_name": "John Michael Doe",
                          "date_of_birth": "1990-05-15",
                          "effective_name": "John Michael Doe",
                          "status": "ACTIVE",
                          "portrait_image_url": "https://<media-host>/...",
                          "session_count": 3,
                          "approved_count": 2,
                          "declined_count": 0,
                          "in_review_count": 1,
                          "issuing_states": [
                            "USA"
                          ],
                          "approved_emails": [
                            "john@example.com"
                          ],
                          "approved_phones": [
                            "+14155551234"
                          ],
                          "features": {
                            "ID_VERIFICATION": "Approved",
                            "LIVENESS": "Approved",
                            "FACE_MATCH": "Approved",
                            "AML": "Approved"
                          },
                          "features_list": [
                            {
                              "feature": "ID_VERIFICATION",
                              "status": "Approved"
                            },
                            {
                              "feature": "LIVENESS",
                              "status": "Approved"
                            },
                            {
                              "feature": "FACE_MATCH",
                              "status": "Approved"
                            },
                            {
                              "feature": "AML",
                              "status": "Approved"
                            }
                          ],
                          "last_session_at": "2025-06-15T10:30:00Z",
                          "last_activity_at": "2025-06-15T10:30:00Z",
                          "first_session_at": "2025-06-01T08:00:00Z",
                          "tags": [
                            {
                              "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                              "name": "VIP",
                              "color": "#2567FF"
                            }
                          ],
                          "created_at": "2025-06-01T08:00:00Z"
                        },
                        {
                          "didit_internal_id": "6ed99d53-e8f5-4cf8-9ac1-4a506cb40f6b",
                          "vendor_data": null,
                          "display_name": "Jane S.",
                          "full_name": "Jane Elizabeth Smith",
                          "date_of_birth": "1985-11-22",
                          "effective_name": "Jane S.",
                          "status": "FLAGGED",
                          "portrait_image_url": null,
                          "session_count": 1,
                          "approved_count": 0,
                          "declined_count": 0,
                          "in_review_count": 1,
                          "issuing_states": [],
                          "approved_emails": [],
                          "approved_phones": [],
                          "features": {
                            "ID_VERIFICATION": "In Review"
                          },
                          "features_list": [
                            {
                              "feature": "ID_VERIFICATION",
                              "status": "In Review"
                            }
                          ],
                          "last_session_at": "2025-06-20T14:00:00Z",
                          "last_activity_at": "2025-06-20T14:05:00Z",
                          "first_session_at": "2025-06-20T14:00:00Z",
                          "tags": [],
                          "created_at": "2025-06-20T14:00:00Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "자격 증명이 제공되지 않았습니다. `x-api-key` 헤더(또는 `Authorization: Bearer` token)가 없는 `/v3/users/*` 경로에 대한 요청은 API에 도달하기 전에 인증 미들웨어에 의해 거부됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "키가 이 애플리케이션의 사용자를 나열할 수 없습니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/users/{vendor_data}/": {
      "get": {
        "summary": "사용자 가져오기",
        "description": "`vendor_data`(정확히 일치)로 [사용자](/entities/users) 한 명을 조회합니다. 목록 뷰에 `metadata`, `comments`, `updated_at`을 추가하고, `tags`를 상세 태그 링크 형태로 전환합니다.",
        "operationId": "get_user",
        "x-didit-sdk": {
          "resource": "users",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "귀하가 지정한 사용자의 고유 식별자입니다. 자유 형식 문자열(UUID 아님)입니다. 이 사용자를 처음 등록한 세션을 생성할 때 `vendor_data`로 전달한 값과 동일하며, 전송된 값과 정확히 일치해야 합니다.",
            "example": "user-abc-123"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/users/user-abc-123/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.retrieve(\n    \"user-abc-123\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.retrieve(\"user-abc-123\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.Retrieve(ctx, \"user-abc-123\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().retrieve(\"user-abc-123\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->users->retrieve('user-abc-123');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.retrieve(\"user-abc-123\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.RetrieveAsync(\"user-abc-123\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "메타데이터, 댓글/활동 로그 및 집계된 세션 데이터를 포함한 전체 사용자 세부정보입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDetailItem"
                },
                "examples": {
                  "Active user": {
                    "value": {
                      "didit_internal_id": "f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418",
                      "vendor_data": "user-abc-123",
                      "display_name": null,
                      "full_name": "John Michael Doe",
                      "date_of_birth": "1990-05-15",
                      "effective_name": "John Michael Doe",
                      "status": "ACTIVE",
                      "metadata": {
                        "tier": "premium",
                        "source": "website"
                      },
                      "portrait_image_url": "https://<media-host>/...",
                      "session_count": 3,
                      "approved_count": 2,
                      "declined_count": 0,
                      "in_review_count": 1,
                      "issuing_states": [
                        "USA"
                      ],
                      "approved_emails": [
                        "john@example.com"
                      ],
                      "approved_phones": [
                        "+14155551234"
                      ],
                      "features": {
                        "ID_VERIFICATION": "Approved",
                        "LIVENESS": "Approved",
                        "FACE_MATCH": "Approved",
                        "AML": "Approved"
                      },
                      "features_list": [
                        {
                          "feature": "ID_VERIFICATION",
                          "status": "Approved"
                        },
                        {
                          "feature": "LIVENESS",
                          "status": "Approved"
                        },
                        {
                          "feature": "FACE_MATCH",
                          "status": "Approved"
                        },
                        {
                          "feature": "AML",
                          "status": "Approved"
                        }
                      ],
                      "last_session_at": "2025-06-15T10:30:00Z",
                      "last_activity_at": "2025-06-15T10:30:00Z",
                      "first_session_at": "2025-06-01T08:00:00Z",
                      "tags": [
                        {
                          "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                          "tag": {
                            "uuid": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
                            "name": "VIP",
                            "color": "#2567FF",
                            "description": null,
                            "source": "custom",
                            "created_at": "2025-05-01T09:00:00Z",
                            "updated_at": "2025-05-01T09:00:00Z"
                          },
                          "added_by_email": "analyst@acme.com",
                          "added_by_name": "Jane Analyst",
                          "created_at": "2025-06-02T11:00:00Z"
                        }
                      ],
                      "comments": [
                        {
                          "uuid": "c1111111-2222-4333-8444-555555555555",
                          "comment_type": "STATUS_CHANGED",
                          "comment": null,
                          "actor_email": "analyst@acme.com",
                          "actor_name": "Jane Analyst",
                          "previous_status": "FLAGGED",
                          "new_status": "ACTIVE",
                          "previous_value": null,
                          "new_value": null,
                          "changed_fields": [],
                          "metadata": null,
                          "mentioned_emails": [],
                          "created_at": "2025-06-01T10:30:00Z"
                        }
                      ],
                      "created_at": "2025-06-01T08:00:00Z",
                      "updated_at": "2025-06-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "자격 증명이 제공되지 않았습니다. `x-api-key` 헤더(또는 `Authorization: Bearer` token)가 없는 `/v3/users/*` 경로에 대한 요청은 API에 도달하기 전에 인증 미들웨어에 의해 거부됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "유효하지 않거나 해지된 API 키이거나, 키에 이 애플리케이션의 사용자를 조회할 권한이 없습니다. 키가 누락되면 `403`을 반환하며, 잘못되었거나 해지되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에 제공된 `vendor_data`를 가진 사용자가 존재하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "사용자 업데이트",
        "description": "사용자 정보의 부분 업데이트: `display_name`, `full_name`, `date_of_birth`, `status`, `metadata`, `approved_emails`/`approved_phones`/`issuing_states`. `metadata`는 전체가 대체됩니다. 여기서 `status`를 변경하는 것은 [사용자 상태 업데이트](#patch-/v3/users/-vendor_data-/update-status/)와 동일하게 동작합니다. 선택적 `reason`과 함께 `STATUS_CHANGED` 활동을 기록하며, `BLOCKED`는 `vendor_data`를 시스템 차단 목록에 추가합니다(`BLOCKED`에서 다른 상태로 변경하면 해당 항목이 제거됨). `display_name`, `full_name`, `date_of_birth` 또는 `metadata`의 변경 사항은 `PROFILE_UPDATED` 활동으로 기록됩니다.",
        "operationId": "update_user",
        "x-didit-sdk": {
          "resource": "users",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "귀하가 지정한 사용자의 고유 식별자입니다(자유 형식 문자열, UUID 아님).",
            "example": "user-abc-123"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/users/user-abc-123/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"display_name\": \"Jane S.\", \"status\": \"FLAGGED\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.update(\n    \"user-abc-123\",\n    display_name=\"Jane S.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.update(\"user-abc-123\", {\n  display_name: \"Jane S.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.Update(ctx, \"user-abc-123\", didit.UsersUpdateParams{\n\tDisplayName: didit.String(\"Jane S.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.UsersUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().update(\"user-abc-123\", UsersUpdateParams.builder()\n        .displayName(\"Jane S.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->users->update('user-abc-123', [\n    'display_name' => 'Jane S.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.update(\n  \"user-abc-123\",\n  display_name: \"Jane S.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.UpdateAsync(\"user-abc-123\", new UsersUpdateParams\n{\n    DisplayName = \"Jane S.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "사용자가 업데이트되었습니다. 업데이트된 전체 사용자 레코드(Get User와 동일한 형식)가 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDetailItem"
                },
                "examples": {
                  "Updated": {
                    "value": {
                      "didit_internal_id": "f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418",
                      "vendor_data": "user-abc-123",
                      "display_name": "Jane S.",
                      "full_name": "Jane Elizabeth Smith",
                      "date_of_birth": "1985-11-22",
                      "effective_name": "Jane S.",
                      "status": "FLAGGED",
                      "metadata": {
                        "tier": "premium"
                      },
                      "portrait_image_url": "https://<media-host>/...",
                      "session_count": 3,
                      "approved_count": 2,
                      "declined_count": 0,
                      "in_review_count": 1,
                      "issuing_states": [
                        "USA"
                      ],
                      "approved_emails": [
                        "john@example.com"
                      ],
                      "approved_phones": [
                        "+14155551234"
                      ],
                      "features": {
                        "ID_VERIFICATION": "Approved",
                        "LIVENESS": "Approved",
                        "FACE_MATCH": "Approved",
                        "AML": "Approved"
                      },
                      "features_list": [
                        {
                          "feature": "ID_VERIFICATION",
                          "status": "Approved"
                        },
                        {
                          "feature": "LIVENESS",
                          "status": "Approved"
                        },
                        {
                          "feature": "FACE_MATCH",
                          "status": "Approved"
                        },
                        {
                          "feature": "AML",
                          "status": "Approved"
                        }
                      ],
                      "last_session_at": "2025-06-15T10:30:00Z",
                      "last_activity_at": "2025-06-15T10:30:00Z",
                      "first_session_at": "2025-06-01T08:00:00Z",
                      "tags": [
                        {
                          "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                          "tag": {
                            "uuid": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
                            "name": "VIP",
                            "color": "#2567FF",
                            "description": null,
                            "source": "custom",
                            "created_at": "2025-05-01T09:00:00Z",
                            "updated_at": "2025-05-01T09:00:00Z"
                          },
                          "added_by_email": "analyst@acme.com",
                          "added_by_name": "Jane Analyst",
                          "created_at": "2025-06-02T11:00:00Z"
                        }
                      ],
                      "comments": [],
                      "created_at": "2025-06-01T08:00:00Z",
                      "updated_at": "2025-06-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 본문 — 일반적으로 알 수 없는 `status`이거나 `date_of_birth`가 `YYYY-MM-DD` 형식이 아닙니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Bad status": {
                    "value": {
                      "status": [
                        "\"INVALID\" is not a valid choice."
                      ]
                    }
                  },
                  "Bad date_of_birth": {
                    "value": {
                      "date_of_birth": [
                        "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
                      ]
                    }
                  },
                  "Reason too long": {
                    "value": {
                      "reason": [
                        "Ensure this field has no more than 1000 characters."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "자격 증명이 제공되지 않았습니다. `x-api-key` 헤더(또는 `Authorization: Bearer` token)가 없는 `/v3/users/*` 경로에 대한 요청은 API에 도달하기 전에 인증 미들웨어에 의해 거부됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "키가 이 애플리케이션의 사용자를 업데이트할 수 없습니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에 제공된 `vendor_data`를 가진 사용자가 존재하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "full_name": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 512,
                    "description": "사용자의 성명"
                  },
                  "display_name": {
                    "type": "string",
                    "nullable": true,
                    "description": "이 사용자의 커스텀 표시 이름"
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "YYYY-MM-DD 형식의 생년월일"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "ACTIVE",
                      "FLAGGED",
                      "BLOCKED"
                    ],
                    "description": "사용자 라이프사이클 상태입니다. 변경 사항은 `STATUS_CHANGED` 활동으로 기록되며, `BLOCKED`는 `vendor_data`를 시스템 차단 목록에 추가합니다(`BLOCKED` 상태에서 벗어나면 해당 항목이 제거됨)."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "사용자에게 연결하는 임의의 JSON 객체입니다. 업데이트 시 기존 메타데이터를 **완전히 대체**합니다. 키만 추가하려면 클라이언트 측에서 병합하십시오."
                  },
                  "approved_emails": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "이 사용자의 인증된 이메일 주소입니다(예: `[\"john@example.com\"]`). 저장된 목록을 완전히 대체합니다."
                  },
                  "approved_phones": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "이 사용자의 인증된 전화번호입니다. 저장된 목록을 완전히 대체합니다."
                  },
                  "issuing_states": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "발급 국가 목록(ISO 3166-1 alpha-3, 예: `[\"USA\"]`)입니다. 저장된 목록을 완전히 대체합니다."
                  },
                  "reason": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 1000,
                    "description": "상태가 변경된 이유입니다. 상태가 실제로 변경될 때만 사용자 활동(`comments[].comment` 및 Business Console의 **Activity**)의 상태 변경 항목에 기록됩니다. webhook에는 포함되지 않습니다."
                  }
                }
              },
              "examples": {
                "Rename": {
                  "summary": "표시 이름 설정",
                  "value": {
                    "display_name": "Jane S."
                  }
                },
                "Override status": {
                  "summary": "검토를 위해 사용자 플래그 지정",
                  "value": {
                    "status": "FLAGGED"
                  }
                },
                "Add metadata": {
                  "summary": "메타데이터 JSON 대체",
                  "value": {
                    "metadata": {
                      "tier": "premium",
                      "risk_level": "low"
                    }
                  }
                },
                "Fix extracted DOB": {
                  "summary": "정확하게 추출된 프로필 필드",
                  "value": {
                    "full_name": "Jane Elizabeth Smith",
                    "date_of_birth": "1985-11-22"
                  }
                },
                "Flag with reason": {
                  "summary": "사용자 플래그 지정 및 사유 기록",
                  "value": {
                    "status": "FLAGGED",
                    "reason": "Address does not match the billing country"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/users/{vendor_data}/generate-pdf/": {
      "get": {
        "summary": "전체 사용자 이력 PDF 보고서 다운로드",
        "description": "Render and download one compliance-ready PDF containing the full verification history of the user identified by `vendor_data`. It is the same document the Console produces from **User detail → Actions → Download PDF**, so periodic compliance exports no longer need a person clicking in the Console.\n\n**보고서 포함 내용.** 프로필 요약(성명, 생년월일, 발급 주(또는 발급 지역), 승인된 이메일 및 전화번호), 각 기능의 최신 상태, 세션 카운터 및 포함된 세션 색인이 포함된 표지가 제공되며, 그 뒤로 포함된 각 세션의 표준 보고서가 시간순(가장 오래된 항목부터)으로 이어집니다. 각 세션 보고서는 해당 세션에 대해 `GET /v3/session/{sessionId}/generate-pdf/`가 반환하는 것과 동일한 문서입니다.\n\n**대상 세션.** `Approved`, `Declined`, `In Review` 또는 `Kyc Expired` 상태인 사용자 인증(KYC) 세션만 포함되며, 다른 상태의 세션은 제외됩니다. 사용자가 해당 상태 중 하나에 속한 세션을 보유하고 있지 않으면 endpoint가 `403`을 반환합니다(아래 참조).\n\n**제한.** 보고서에는 보고 가능한 **가장 최근 세션 20개**까지 포함됩니다. 사용자의 세션 수가 더 많은 경우 최신 20개가 포함되며, 제외된 이전 세션 수가 표지에 표시됩니다. 전체 목록을 JSON 형식으로 확인하려면 `GET /v3/sessions/?vendor_data=…`를 사용하십시오.\n\n**브랜딩.** 애플리케이션에 화이트 라벨 커스텀이 적용되어 있는 경우 표지와 모든 세션 보고서가 고객의 로고 및 개인정보 처리방침 URL로 렌더링됩니다. 그렇지 않은 경우 Didit 브랜딩이 적용됩니다. 보고서는 영어로 렌더링되며, 언어 파라미터는 제공되지 않습니다.\n\n**캐싱 없음.** 모든 호출 시 현재 데이터를 바탕으로 PDF를 다시 렌더링하므로, 수동 검토 후 생성된 보고서에는 검토자의 결정이 반영됩니다. 동일한 사용자에 대해 두 번 호출하면 바이트 단위로 서로 다른 파일이 생성될 수 있으므로, 불변 사본이 필요한 경우 다운로드한 파일을 보관하십시오.\n\n**지연 시간.** 렌더링은 동기식으로 진행되며 포함된 각 세션의 저장된 모든 이미지를 다운로드하므로, 미디어가 많은 세션을 다수 보유한 사용자의 경우 수십 초가 소요될 수 있습니다. 넉넉한 클라이언트 읽기 타임아웃(120초 권장)을 설정하고 본문을 디스크로 스트리밍하십시오. 생성이 클라이언트 타임아웃까지 무한정 지속되는 대신 서버 측 제한 시간에 도달하면 중단됩니다. 제한 시간에 도달하더라도 응답은 가장 최근 세션들을 포함하는 유효한 PDF로 반환되며, 표지에 생략된 세션 수가 표시됩니다.\n\n**범위.** 사용자는 API 키를 소유한 애플리케이션 내에서 확인됩니다. 키는 다른 애플리케이션의 사용자를 내보낼 수 없으며, 해당 사용자 정보가 존재하지 않아 endpoint에서 `404`를 반환합니다.\n\n**후행 슬래시.** 정규 경로는 후행 슬래시(`…/generate-pdf/`)로 끝납니다. 슬래시가 없는 요청도 동일한 응답으로 직접 처리됩니다. `301` 리디렉션이 발생하지 않으므로 클라이언트가 리디렉션을 추적할 필요가 없으며 `curl`에 `-L`을 사용할 필요도 없습니다. 예시와 같이 슬래시가 포함된 URL을 사용하십시오.",
        "operationId": "get_user_generate_pdf",
        "x-didit-sdk": {
          "resource": "users",
          "method": "generate_pdf",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "귀하가 지정한 사용자의 고유 식별자입니다. 자유 형식 문자열(UUID 아님)입니다. 사용자의 세션을 생성할 때 `vendor_data`로 전달한 값과 동일하며, 전송된 값과 정확히 일치해야 합니다. URL 인코딩해야 합니다. `/`가 포함된 값은 이 라우트에서 처리할 수 없습니다.",
            "example": "user-abc-123"
          }
        ],
        "responses": {
          "200": {
            "description": "렌더링된 PDF 문서로, 바이너리 `application/pdf` 형식으로 직접 반환됩니다. JSON 래퍼나 다운로드 URL 간접 참조가 없습니다. 본문은 `%PDF` 매직 바이트로 시작합니다. `.pdf` 파일로 저장하거나 호출자에게 스트리밍하세요.",
            "headers": {
              "Content-Disposition": {
                "description": "`attachment; filename=user_{didit_internal_id}.pdf` — 파일 이름은 `vendor_data`가 아닌 사용자의 안정적인 Didit 식별자(`GET /v3/users/{vendor_data}/`의 `didit_internal_id`)를 따릅니다.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=user_f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418.pdf"
                }
              },
              "Content-Length": {
                "description": "PDF의 총 크기(바이트 단위)이며, 본문은 청크로 분할되지 않습니다.",
                "schema": {
                  "type": "integer",
                  "example": 148213
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "자격 증명이 제공되지 않았습니다. `x-api-key` 헤더(또는 `Authorization: Bearer` token)가 없는 `/v3/users/*` 경로에 대한 요청은 API에 도달하기 전에 인증 미들웨어에 의해 거부됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한 부여 또는 적격성 실패입니다. 두 가지는 `detail` 문자열로 구분하십시오.\n\n- `\"You do not have permission to perform this action.\"` — API 키가 유효하지 않거나 취소되었거나, 요청에 애플리케이션 API 키 대신 콘솔 사용자 token이 포함되어 있습니다.\n- `\"This user has no sessions in review, declined, approved or kyc expired to report.\"` — 사용자가 애플리케이션에 존재하지만 아직 보고 가능한 상태의 세션이 없습니다(예: 모든 세션이 여전히 `In Progress` 상태이거나, 사용자가 `POST /v3/users/create/`를 통해 생성된 후 인증을 진행하지 않음). 보고서를 요청하기 전에 `status.updated` webhook을 기다리십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "This user has no sessions in review, declined, approved or kyc expired to report."
                    }
                  }
                },
                "examples": {
                  "Invalid credentials": {
                    "summary": "취소되었거나 유효하지 않은 API 키 또는 콘솔 사용자 token입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "No reportable sessions": {
                    "summary": "사용자가 존재하지만 Approved / Declined / In Review / Kyc Expired 세션이 없습니다",
                    "value": {
                      "detail": "This user has no sessions in review, declined, approved or kyc expired to report."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "API 키에 연결된 애플리케이션에 제공된 `vendor_data`를 가진 사용자가 존재하지 않습니다. 다른 애플리케이션의 사용자는 이 키에서 보이지 않으며 동일한 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "User not found."
                    }
                  }
                },
                "examples": {
                  "Unknown user": {
                    "summary": "vendor_data가 이 애플리케이션의 어떤 사용자와도 일치하지 않습니다",
                    "value": {
                      "detail": "User not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. PDF 생성에는 전역 GET 한도인 분당 600회 외에 이 endpoint와 `GET /v3/session/{sessionId}/generate-pdf/`가 공유하는 **인증 정보당 분당 50회**(API 키, Bearer token, 또는 미인증 시 소스 IP)의 전용 한도가 적용됩니다. `Retry-After`초(`X-RateLimit-*` 헤더에도 반영됨) 동안 대기한 후 재시도하세요. 보고서는 서버 측에 캐시되지 않으므로, 다시 가져오는 대신 각 보고서를 한 번 다운로드하여 파일을 저장해 두세요.",
            "headers": {
              "Retry-After": {
                "description": "요청을 재시도하기 전에 대기해야 하는 시간(초).",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "현재 윈도우에서 허용되는 최대 PDF 생성 횟수(50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남아 있는 요청 수입니다.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "현재 윈도우가 리셋되는 Unix 타임스탬프(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 1750000000
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "속도 제한 초과에 대한 사람이 읽기 쉬운 설명입니다.",
                      "example": "Session PDF generation rate limit exceeded. You can make up to 50 requests per minute."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "summary": "동일한 자격 증명에서 1분 동안 50회를 초과하는 PDF 생성 발생",
                    "value": {
                      "detail": "Session PDF generation rate limit exceeded. You can make up to 50 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --fail \\\n  'https://verification.didit.me/v3/users/user-abc-123/generate-pdf/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  --output user-history.pdf"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.users.generate_pdf(\n    \"user-abc-123\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.users.generatePdf(\"user-abc-123\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Users.GeneratePDF(ctx, \"user-abc-123\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.users().generatePdf(\"user-abc-123\")\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->users->generatePdf('user-abc-123');\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.users.generate_pdf(\"user-abc-123\")\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Users.GeneratePdfAsync(\"user-abc-123\");\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ]
      }
    },
    "/v3/users/delete/": {
      "post": {
        "summary": "사용자 일괄 삭제",
        "description": "사용자를 **영구 삭제**합니다. 사용자 레코드가 영구적으로 제거됩니다. 일상적인 차단의 경우 `BLOCKED` 상태로 [Update User Status](#patch-/v3/users/-vendor_data-/update-status/)를 사용하는 것이 좋습니다. `vendor_data_list`, `didit_internal_id_list` 또는 둘 다 동시에 사용하여 사용자를 선택하거나 `delete_all: true`를 전달하십시오. 이 endpoint는 필터로 `delete_all`의 범위를 좁히지 않습니다. Console의 People 필터는 `400`으로 거부되므로(`400` 응답 참조), 범위를 좁히려는 의도가 전체 삭제로 이어지지 않습니다. 두 가지 예외: `filter_has_approved_sessions` 및 `filter_has_declined_sessions`는 거부되지도 않고 적용되지도 않으므로, `delete_all: true`와 함께 사용하면 여전히 모든 사용자가 삭제됩니다. 이 필터들을 전송하지 마십시오.\n\n**생체 인식 템플릿:** `retain_face_embeddings`를 `true`로 설정하지 않는 한, 세션 삭제 후 이 사용자들을 위해 보존된 모든 이미지가 없는 생체 인식 템플릿(`/v3/biometric-templates/` 참조)은 사용자가 삭제되기 전에 제거되므로 중복 감지 및 얼굴 검색에서 해당 인물이 더 이상 일치하지 않게 됩니다. `retain_face_embeddings: true` 및 `face_retention_days`를 설정하면 해당 일수 동안 1인당 이미지가 없는 생체 인식 템플릿 1개를 유지하도록 선택할 수 있으며, 해당 인물에 대한 다른 정보는 일체 보존되지 않습니다. 생체 인식 스토어를 사용할 수 없어 템플릿을 제거할 수 없는 경우 호출은 `503`을 반환하고 요청의 어떤 사용자도 삭제되지 않으며, 요청을 다시 시도하면 작업이 완료됩니다.\n\n**제출된 규제 보고서:** 선택한 데이터가 최종 확정된 규제 보고서에 포함되어 있는 경우 전체 요청이 `409`로 거부되며 아무것도 삭제되지 않습니다. 응답 본문은 `code: in_filed_report`를 사용하며 `uuid`, `report_number`, `report_type`, `case_uuid`로 각 보고서를 지정합니다. 해당 보고서를 삭제한 후 요청을 다시 시도하십시오.",
        "operationId": "batch_delete_users",
        "x-didit-sdk": {
          "resource": "users",
          "method": "batch_delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "`vendor_data_list`, `didit_internal_id_list` 또는 `delete_all: true`를 제공하세요. 두 목록은 결합될 수 있으며 OR 조건으로 처리됩니다. `delete_all`이 `true`이면 우선 적용되며 두 목록은 모두 무시됩니다.",
                "properties": {
                  "vendor_data_list": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "삭제할 귀하 고유의 식별자 목록이며, 전송된 내용과 정확히 일치합니다."
                  },
                  "didit_internal_id_list": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "삭제할 Didit 내부 사용자 ID입니다. 생성 및 조회 endpoint에서 반환된 `didit_internal_id`입니다."
                  },
                  "delete_all": {
                    "type": "boolean",
                    "default": false,
                    "description": "`true`인 경우 애플리케이션의 모든 사용자를 삭제합니다."
                  },
                  "retain_face_embeddings": {
                    "type": "boolean",
                    "default": false,
                    "description": "중복 감지를 위해 삭제된 각 개인의 이미지가 없는 생체 인식 템플릿을 `face_retention_days` 동안 보존할지 여부에 대한 귀하의 명시적 선택입니다. 해당 개인에 관한 다른 모든 정보는 삭제됩니다. 사용자와 함께 템플릿을 삭제하려면 생략하거나 `false`를 전달하십시오. `true`인 경우 `face_retention_days`가 필수입니다."
                  },
                  "face_retention_days": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 3650,
                    "description": "`retain_face_embeddings`가 `true`일 때 이미지가 없는 생체 인식 템플릿이 보존되는 일수입니다. 해당 설정과 함께 필수이며, 설정 없이 전달되면 `face_retention_days`에 대해 `400` 오류로 거부됩니다.",
                    "example": 365
                  }
                }
              },
              "examples": {
                "Specific users": {
                  "summary": "vendor_data로 사용자 삭제",
                  "value": {
                    "vendor_data_list": [
                      "user-123",
                      "user-456"
                    ]
                  }
                },
                "By Didit internal ID": {
                  "summary": "didit_internal_id로 사용자 삭제",
                  "value": {
                    "didit_internal_id_list": [
                      "3f1c0d3e-8f0a-4c2e-9a3d-9b1f5f4a2c11"
                    ]
                  }
                },
                "All users": {
                  "summary": "이 애플리케이션의 모든 사용자 삭제",
                  "value": {
                    "delete_all": true
                  }
                },
                "Keep face templates": {
                  "summary": "사용자를 삭제하고 익명 얼굴 템플릿은 365일간 유지",
                  "value": {
                    "vendor_data_list": [
                      "user-123"
                    ],
                    "retain_face_embeddings": true,
                    "face_retention_days": 365
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/users/delete/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"vendor_data_list\": [\"user-123\", \"user-456\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.batch_delete(\n    vendor_data_list=[\"user-123\", \"user-456\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.batchDelete({\n  vendor_data_list: [\"user-123\", \"user-456\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.BatchDelete(ctx, didit.UsersBatchDeleteParams{\n\tVendorDataList: didit.Some([]string{\"user-123\", \"user-456\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.UsersBatchDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().batchDelete(UsersBatchDeleteParams.builder()\n        .vendorDataList(List.of(\"user-123\", \"user-456\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->users->batchDelete([\n    'vendor_data_list' => ['user-123', 'user-456'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.batch_delete(vendor_data_list: [\"user-123\", \"user-456\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.BatchDeleteAsync(new UsersBatchDeleteParams\n{\n    VendorDataList = new string[] { \"user-123\", \"user-456\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "사용자가 삭제되었습니다. 실제로 삭제된 사용자 수를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "integer",
                      "description": "삭제된 사용자 수(일치하지 않는 vendor_data 값은 제외됨)입니다."
                    }
                  }
                },
                "examples": {
                  "Deleted some": {
                    "value": {
                      "deleted": 2
                    }
                  },
                  "Nothing matched": {
                    "value": {
                      "deleted": 0
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 아무것도 삭제되지 않습니다. 오류는 필드 이름별로 키가 지정됩니다. 선택자가 없는 경우(두 목록 모두 없고 `delete_all`이 `true`가 아님) 본문은 `{\"vendor_data_list\": [\"This field is required unless delete_all is true.\"]}`입니다. 빈 목록은 자체 키 아래에서 `\"This list may not be empty.\"`로 거부됩니다. 콘솔 전용 필터(`filter_search`, `filter_status`, `filter_country`, `filter_date_from`, `filter_date_to`, `filter_tag`, `filter_latest_verification_status`, `filter_risk`, `filter_has_sessions`, `filter_has_open_alerts`, `filter_aml_monitoring`, `filter_can_sign_in`, `filter_auth_status`, `filter_auth_method` 또는 `filter_auth_mfa_enabled`)는 `false`를 포함해 값을 가지는 경우 해당 각 필드를 키로 하는 객체와 함께 거부됩니다. 그 외 알 수 없는 `filter_*` 키는 `\"Unknown filter.\"`로 거부됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing selector": {
                    "summary": "list와 delete_all이 모두 제공되지 않았습니다",
                    "value": {
                      "vendor_data_list": [
                        "This field is required unless delete_all is true."
                      ]
                    }
                  },
                  "Console-only filter": {
                    "value": {
                      "filter_has_sessions": "This filter is Console-only and is not supported by this endpoint."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "자격 증명이 제공되지 않았습니다. `x-api-key` 헤더(또는 `Authorization: Bearer` token)가 없는 `/v3/users/*` 경로에 대한 요청은 API에 도달하기 전에 인증 미들웨어에 의해 거부됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "유효하지 않거나 해지된 API 키이거나, 키에 이 애플리케이션의 사용자를 삭제할 권한이 없습니다. 키가 누락되면 `403`을 반환하며, 잘못되었거나 해지되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "생체 인식 템플릿을 보존하거나 삭제하는 동안 생체 인식 저장소를 사용할 수 없었습니다. 아무것도 삭제되지 않았으므로 동일한 요청을 반복하십시오. 재시도는 멱등성을 가지며 단일 템플릿으로 수렴됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Retryable": {
                    "value": {
                      "detail": "The biometric-template operation could not finish because an external store is unavailable. The operation is retryable."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "아무것도 삭제되지 않았습니다. `code`에 이유가 표시됩니다. 선택 항목에 제출 완료된 규제 보고서에 포함된 인물이 있는 경우 `in_filed_report`, 다른 요청이 선택된 인물 중 한 명을 아직 삭제 중인 경우 `subject_deletion_in_progress`입니다. 해당 삭제가 완료된 후 요청을 다시 시도하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/InFiledReportError"
                    },
                    {
                      "$ref": "#/components/schemas/SubjectDeletionInProgressError"
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/sessions/delete/": {
      "post": {
        "summary": "session_number로 KYC 세션 일괄 삭제",
        "description": "숫자 형식의 `session_number`를 지정하여 사용자 인증(KYC) 세션을 일괄 삭제하거나, `delete_all: true`를 사용하여 애플리케이션 내의 모든 KYC 세션을 삭제합니다.\n\n`session_number`는 콘솔 세션 목록에 표시되며 세션 생성 및 결정 endpoint에서 `session_number`로 반환되는 사람이 읽기 쉬운 증가형 카운터입니다. 이는 `session_id` UUID가 **아닙니다**. UUID로 세션을 삭제하거나 이 endpoint에서 처리하지 않는 기업 확인(KYB) 세션을 삭제하려면 대신 `DELETE /v3/session/{sessionId}/delete/`를 사용하십시오.\n\n**요청당 최대 20개의 세션이 즉시 삭제되며, 그 이상은 작업(job)으로 실행됩니다.** `session_numbers`로 선택하든 `delete_all`로 선택하든 일치하는 세션 수에 따라 처리 방식이 결정됩니다:\n- 일치하는 세션이 최대 20개인 경우: 응답이 반환되기 전에 삭제되며, `results[]`에 세션당 하나의 항목이 포함된 `200` 응답이 반환됩니다.\n- 20개를 초과하는 경우: 삭제 작업이 포함된 `202` 응답이 반환되고 세션은 백그라운드에서 삭제됩니다. `status`가 `COMPLETED` 또는 `FAILED`가 될 때까지 `GET /v3/sessions/delete/{job_id}/`를 폴링하십시오. 작업은 결과별 건수만 보고하며, 삭제된 세션 목록은 보고하지 않습니다. `delete_all` 작업은 요청 전에 생성된 세션만 삭제하며, 작업 실행 중에 시작된 세션은 삭제되지 않습니다.\n\n삭제된 각 세션은 단일 세션 삭제 endpoint와 정확히 동일하게 처리됩니다. 세션, 세션에 포함된 모든 인증 시도, 해당 결정 및 추출된 데이터, 관련 기능 레코드(신분증 인증, 얼굴, 라이브니스, 얼굴 대조 등) 및 저장된 모든 파일이 삭제되고, 모든 조회 endpoint에서 사라지며, 이전에 발급된 미디어 URL의 연결이 중단됩니다. 삭제된 세션에 대해 대기열에 남아 있는 webhook 전송 및 재시도는 삭제되며, 이미 전송된 webhook에는 영향을 주지 않습니다. 차단 목록 항목은 제거되지 **않으며**, 이미 소비된 크레딧은 환불되지 **않고**, 상위 User 엔터티는 삭제되지 **않습니다**(해당 항목은 `POST /v3/users/delete/` 사용). 삭제에 대한 webhook은 발생하지 않습니다. 삭제는 영구적이며 되돌릴 수 없습니다.\n\n**선택 의미:**\n- `delete_all: true`를 사용하면 접두사 `filter_`가 붙은 `GET /v3/sessions/`의 필터(예: `filter_status`, `filter_workflow_id`, `filter_date_from`)를 사용하여 선택 대상을 좁힐 수 있습니다. 세션 목록 조회에서 여러 값을 허용하는 필터(`status`, `workflow_id`, `country`, `region`, `document_type`, `document_name`, `session_type`, `warning`, `organization_name`)는 쉼표로 구분된 문자열 또는 배열을 허용하며, 다른 필터는 단일 값을 받습니다. 빈 값은 무시됩니다. 필터는 `delete_all`과 함께 사용할 때만 적용되며, 삭제 작업에도 동일한 필터가 적용됩니다.\n- 알 수 없는 `filter_*` 키가 있거나 필터 값을 읽을 수 없는 경우 아무것도 삭제되기 전에 전체 요청이 `400`으로 거부되므로 잘못 입력된 필터로 인해 삭제 범위가 모든 세션으로 확장되지 않습니다.\n- 애플리케이션에 현재 존재하는 KYC 세션과 일치하지 않는 `session_numbers` 항목(알 수 없는 번호, 이미 삭제된 세션 또는 다른 애플리케이션 소유의 세션)은 **경고 없이 건너뜁니다**. 이 항목들은 `results`에 표시되지 않으며 작업의 `total`에도 집계되지 않습니다.\n- 유효성 검사 실패(숫자가 아닌 항목, 빈 목록, `session_numbers`와 `delete_all`이 모두 제공되지 않은 경우, 애플리케이션이 수용할 수 없는 템플릿 보존 설정 등)가 발생하면 **전체 요청**이 `400`으로 거부되고 아무것도 삭제되지 않습니다.\n- 세션은 그룹 단위로 삭제됩니다. 스토리지 서비스를 사용할 수 없는 등의 이유로 그룹을 삭제할 수 없는 경우 해당 그룹의 모든 세션은 `face_retention_outcome: failed_retryable`로 보고되고 유지되며, 다른 그룹은 영향을 받지 않습니다. 해당 세션에 대해 요청을 다시 시도하십시오. 작업으로 실행되는 경우 이러한 그룹은 자동으로 재시도됩니다.\n- 목록 길이에 대한 문서화된 상한은 없으며, 아래의 공유 쓰기 속도 제한이 실질적인 한도입니다.\n\n**얼굴 생체 인식 데이터:** 선택적 필드인 `retain_face_embeddings`, `face_retention_days`, `face_retention_deadline`, `deletion_instruction`, `instruction_id`는 `DELETE /v3/session/{sessionId}/delete/`에서와 동일한 의미를 가지며 일치하는 모든 세션에 적용됩니다. 각 결과는 자체 `face_retention_outcome`을 보고합니다.\n\n**응답:** 일치하는 세션이 최대 20개인 경우 `results[]`가 포함된 `200 OK`가 반환되고, 그 이상인 경우 삭제 작업이 포함된 `202 Accepted`가 반환됩니다. `face_retention_outcome: failed_retryable`을 제외한 모든 결과는 삭제를 확인하며, 이는 삭제되지 않아 재시도해야 하는 세션을 보고합니다. 이 endpoint의 이전 버전은 `204 No Content`를 반환했으므로, `204`를 검증하는 클라이언트를 업데이트하십시오.\n\n**멱등성:** 동일한 요청을 반복해도 추가로 삭제되지 않습니다. 더 이상 세션과 일치하지 않는 번호는 건너뜁니다.\n\n**`delete_all: true` (파괴적 작업):** 애플리케이션에 남아 있는 **모든** KYC 세션을 삭제합니다. 이 옵션이 설정되면 `session_numbers`는 무시됩니다. 확인 단계가 없으며 실행 취소할 수 없습니다.\n\n**인증:** `x-api-key` 헤더의 API 키를 사용합니다. 자격 증명이 없거나 유효하지 않은 경우 `403`(`{\"detail\": \"You do not have permission to perform this action.\"}`)이 반환되며, 이 API는 `401`을 반환하지 않습니다.\n\n**속도 제한:** 모든 POST/PATCH/DELETE endpoint에서 API 키당 분당 300개의 요청으로 공유되는 쓰기 예산이 적용되며, 초과 시 `429`가 반환됩니다.\n\n이 endpoint는 API 키만 허용합니다. 둘 다 허용하는 단일 세션 삭제와 달리 Business Console 사용자 Bearer 토큰은 `403`으로 거부됩니다.\n\n**제출된 규제 보고서:** 선택한 데이터가 최종 확정된 규제 보고서에 포함되어 있는 경우 전체 요청이 `409`로 거부되고 아무것도 삭제되지 않습니다. 본문은 `code: in_filed_report`를 사용하며 `uuid`, `report_number`, `report_type`, `case_uuid`로 각 보고서를 명시합니다. 보고서를 삭제한 후 요청을 다시 시도하십시오.",
        "operationId": "batch_delete_sessions",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "batch_delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "session_numbers": {
                    "type": "array",
                    "description": "삭제할 KYC 세션의 숫자 `session_number` 값(숫자 전용 문자열, JSON 숫자도 허용되며 변환됨)입니다. `delete_all`이 `true`가 아닌 한 필수이며, 빈 목록은 `400`을 반환합니다. 숫자가 아닌 항목이 있으면 전체 요청이 `400`으로 거부됩니다(`delete_all`이 `true`인 경우 유효성 검사를 건너뛰고 항목을 무시함). 애플리케이션의 라이브 세션과 일치하지 않는 번호는 알림 없이 건너뜁니다.",
                    "items": {
                      "type": "string",
                      "pattern": "^[0-9]+$",
                      "example": "1001"
                    },
                    "minItems": 1,
                    "example": [
                      "1001",
                      "1002",
                      "1003"
                    ]
                  },
                  "delete_all": {
                    "type": "boolean",
                    "description": "`true`인 경우 호출 애플리케이션의 나머지 모든 KYC 세션이 삭제되고 `session_numbers`는 무시됩니다(`filter_*` 키로 선택 항목을 좁히지 않는 한). 일치하는 세션이 20개를 초과하면 요청 전에 생성된 세션만 포함하는 삭제 작업(`202`)으로 실행됩니다. 기본값은 `false`입니다. 되돌릴 수 없으며 확인 단계가 없습니다.",
                    "default": false,
                    "example": false
                  },
                  "retain_face_embeddings": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "이번 삭제에 대해 애플리케이션의 `face_retention_policy`를 재정의합니다. `true`는 세션이 삭제된 후에도 세션의 사용자에 연결된 이미지가 없는 얼굴 생체 인식 템플릿 하나를 유지합니다. `false`는 세션과 함께 얼굴 임베딩을 삭제합니다. 생략하거나 `null`로 설정하면 애플리케이션 정책을 따릅니다. KYB 세션 및 얼굴 임베딩이 없는 세션의 경우 무시됩니다.",
                    "example": true
                  },
                  "face_retention_days": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 3650,
                    "description": "보존된 템플릿의 유한 보존 기간(일 단위)입니다. 애플리케이션에서 이미 `face_retention_days`를 설정하지 않은 한 템플릿이 보존될 때 필수입니다. 템플릿의 `expires_at`은 이 기간, 애플리케이션의 일반 데이터 보존 기간, 그리고 `face_retention_deadline` 중 가장 빠른 시점으로 설정됩니다.",
                    "example": 365
                  },
                  "face_retention_deadline": {
                    "type": "string",
                    "format": "date-time",
                    "description": "보존된 템플릿의 선택적 강제 만료일입니다. 미래 시점이어야 합니다.",
                    "example": "2027-08-28T00:00:00Z"
                  },
                  "deletion_instruction": {
                    "type": "string",
                    "enum": [
                      "operational_session_delete",
                      "privacy_erasure"
                    ],
                    "default": "operational_session_delete",
                    "description": "제공하는 지시의 유형입니다. `operational_session_delete`는 세션을 삭제하고 정책 또는 `retain_face_embeddings`에 명시된 경우에만 템플릿을 보존합니다. `privacy_erasure`는 세션을 삭제하기 전에 세션의 사용자에 고정된 보존된 모든 생체 인식 템플릿을 제거하며, 애플리케이션 정책으로 재정의할 수 없고 `retain_face_embeddings: true`와 함께 사용할 수 없습니다(`400`).",
                    "example": "operational_session_delete"
                  },
                  "instruction_id": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "이 삭제 지침에 대한 귀하의 영구 참조값입니다(예: 삭제 티켓 id). 감사 로그 및 보존되는 템플릿에 기록됩니다. 생략 시 Didit이 생성합니다.",
                    "example": "dsar-2026-0142"
                  },
                  "filter_status": {
                    "description": "`delete_all` 대상을 [세션 목록 조회](/ko/sessions-api/list-sessions)의 `status` 필터와 일치하는 동일한 값의 세션으로 좁힙니다. 쉼표로 구분된 문자열 또는 배열입니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 선택 대상을 좁히지 않습니다.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_vendor_data": {
                    "description": "`delete_all` 대상을 [세션 목록 조회](/ko/sessions-api/list-sessions)의 `vendor_data` 필터와 일치하는 동일한 값의 세션으로 좁힙니다. 목록이 아닌 단일 값입니다. 배열은 하나의 쉼표로 구분된 텍스트로 결합되므로 여러 값이 대체 항목으로 매칭되지 않습니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 선택 대상을 좁히지 않습니다.",
                    "type": "string"
                  },
                  "filter_search": {
                    "description": "`delete_all` 대상을 [세션 목록 조회](/ko/sessions-api/list-sessions)의 `search` 필터와 일치하는 동일한 값의 세션으로 좁힙니다. 목록이 아닌 단일 값입니다. 배열은 하나의 쉼표로 구분된 텍스트로 결합되므로 여러 값이 대체 항목으로 매칭되지 않습니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 선택 대상을 좁히지 않습니다.",
                    "type": "string"
                  },
                  "filter_workflow_id": {
                    "description": "`delete_all` 대상을 [세션 목록 조회](/ko/sessions-api/list-sessions)의 `workflow_id` 필터와 일치하는 동일한 값의 세션으로 좁힙니다. 쉼표로 구분된 문자열 또는 배열입니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 선택 대상을 좁히지 않습니다.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_date_from": {
                    "description": "`delete_all`의 대상 범위를 [세션 목록](/ko/sessions-api/list-sessions)의 `date_from` 필터와 동일한 값을 갖는 세션으로 좁힙니다. 목록이 아닌 단일 값이어야 합니다. 배열은 쉼표로 구분된 하나의 값으로 결합되므로 여러 값을 전달하면 `400`으로 거부됩니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 대상 범위를 좁히지 않습니다.",
                    "type": "string",
                    "format": "date"
                  },
                  "filter_date_to": {
                    "description": "`delete_all`의 대상 범위를 [세션 목록](/ko/sessions-api/list-sessions)의 `date_to` 필터와 동일한 값을 갖는 세션으로 좁힙니다. 목록이 아닌 단일 값이어야 합니다. 배열은 쉼표로 구분된 하나의 값으로 결합되므로 여러 값을 전달하면 `400`으로 거부됩니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 대상 범위를 좁히지 않습니다.",
                    "type": "string",
                    "format": "date"
                  },
                  "filter_country": {
                    "description": "`delete_all`의 대상 범위를 [세션 목록](/ko/sessions-api/list-sessions)의 `country` 필터와 동일한 값을 갖는 세션으로 좁힙니다. 쉼표로 구분된 문자열 또는 배열입니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 대상 범위를 좁히지 않습니다.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_document_type": {
                    "description": "`delete_all`의 대상 범위를 [세션 목록](/ko/sessions-api/list-sessions)의 `document_type` 필터와 동일한 값을 갖는 세션으로 좁힙니다. 쉼표로 구분된 문자열 또는 배열입니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 대상 범위를 좁히지 않습니다.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_document_name": {
                    "description": "`delete_all`의 대상 범위를 [세션 목록](/ko/sessions-api/list-sessions)의 `document_name` 필터와 동일한 값을 갖는 세션으로 좁힙니다. 쉼표로 구분된 문자열 또는 배열입니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 대상 범위를 좁히지 않습니다.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_region": {
                    "description": "`delete_all` 대상을 [세션 목록 조회](/ko/sessions-api/list-sessions)의 `region` 필터와 일치하는 동일한 값의 세션으로 좁힙니다. 쉼표로 구분된 문자열 또는 배열입니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 선택 대상을 좁히지 않습니다.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_didit_internal_id": {
                    "description": "`delete_all`의 대상 범위를 [세션 목록](/ko/sessions-api/list-sessions)의 `didit_internal_id` 필터와 동일한 값을 갖는 세션으로 좁힙니다. 목록이 아닌 단일 값이어야 합니다. 배열은 쉼표로 구분된 하나의 값으로 결합되므로 여러 값을 전달하면 `400`으로 거부됩니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 대상 범위를 좁히지 않습니다.",
                    "type": "string",
                    "format": "uuid"
                  },
                  "filter_session_type": {
                    "description": "`delete_all` 대상을 [세션 목록 조회](/ko/sessions-api/list-sessions)의 `session_type` 필터와 일치하는 동일한 값의 세션으로 좁힙니다. 쉼표로 구분된 문자열 또는 배열입니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 선택 대상을 좁히지 않습니다.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_api_service": {
                    "description": "`delete_all`의 대상 범위를 [세션 목록](/ko/sessions-api/list-sessions)의 `api_service` 필터와 동일한 값을 갖는 세션으로 좁힙니다. 목록이 아닌 단일 값이어야 합니다. 배열은 쉼표로 구분된 하나의 값으로 결합되므로 여러 값을 전달하면 `400`으로 거부됩니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 대상 범위를 좁히지 않습니다.",
                    "type": "string"
                  },
                  "filter_screened_full_name": {
                    "description": "`delete_all` 대상을 [세션 목록 조회](/ko/sessions-api/list-sessions)의 `screened_full_name` 필터와 일치하는 동일한 값의 세션으로 좁힙니다. 목록이 아닌 단일 값입니다. 배열은 하나의 쉼표로 구분된 텍스트로 결합되므로 여러 값이 대체 항목으로 매칭되지 않습니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 선택 대상을 좁히지 않습니다.",
                    "type": "string"
                  },
                  "filter_warning": {
                    "description": "`delete_all` 대상을 [세션 목록 조회](/ko/sessions-api/list-sessions)의 `warning` 필터와 일치하는 동일한 값의 세션으로 좁힙니다. 쉼표로 구분된 문자열 또는 배열입니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 선택 대상을 좁히지 않습니다.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_status_initialized_as_in_review": {
                    "description": "`delete_all` 대상을 [세션 목록 조회](/ko/sessions-api/list-sessions)의 `status_initialized_as_in_review` 필터와 일치하는 동일한 값의 세션으로 좁힙니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 선택 대상을 좁히지 않습니다.",
                    "type": "boolean"
                  },
                  "filter_is_kyc_to_be_reviewed": {
                    "description": "`delete_all`의 대상 범위를 [세션 목록](/ko/sessions-api/list-sessions)의 `is_kyc_to_be_reviewed` 필터와 동일한 값을 갖는 세션으로 좁힙니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 대상 범위를 좁히지 않습니다.",
                    "type": "boolean"
                  },
                  "filter_euuid": {
                    "description": "`delete_all`의 대상 범위를 [세션 목록](/ko/sessions-api/list-sessions)의 `euuid` 필터와 동일한 값을 갖는 세션으로 좁힙니다. 목록이 아닌 단일 값이어야 합니다. 배열은 쉼표로 구분된 하나의 값으로 결합되므로 여러 값을 전달하면 `400`으로 거부됩니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 대상 범위를 좁히지 않습니다.",
                    "type": "string",
                    "format": "uuid"
                  },
                  "filter_organization_name": {
                    "description": "`delete_all` 대상을 [세션 목록 조회](/ko/sessions-api/list-sessions)의 `organization_name` 필터와 일치하는 동일한 값의 세션으로 좁힙니다. 쉼표로 구분된 문자열 또는 배열입니다. API 키를 사용할 경우 본인 조직의 이름과만 일치할 수 있으므로, 조직의 전체 세션을 선택하거나 아무것도 선택하지 않습니다. `delete_all`이 없으면 무시됩니다. 빈 값은 무시되며 선택 대상을 좁히지 않습니다.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  }
                }
              },
              "examples": {
                "Specific sessions": {
                  "summary": "번호별 특정 세션 삭제",
                  "value": {
                    "session_numbers": [
                      "1001",
                      "1002",
                      "1003"
                    ]
                  }
                },
                "All sessions": {
                  "summary": "애플리케이션의 모든 KYC 세션 삭제",
                  "value": {
                    "delete_all": true
                  }
                },
                "Delete and retain templates": {
                  "summary": "세션을 삭제하되 이미지가 없는 생체 인식 템플릿은 365일간 유지",
                  "value": {
                    "session_numbers": [
                      "1001",
                      "1002"
                    ],
                    "retain_face_embeddings": true,
                    "face_retention_days": 365,
                    "instruction_id": "post-approval-cleanup-2026-08"
                  }
                },
                "Privacy erasure": {
                  "summary": "세션을 삭제하고 해당 사용자에 대해 보존된 모든 템플릿 완전 삭제",
                  "value": {
                    "session_numbers": [
                      "1001"
                    ],
                    "deletion_instruction": "privacy_erasure",
                    "instruction_id": "dsar-2026-0142"
                  }
                },
                "Filtered delete_all": {
                  "summary": "2026년 9월에 생성된 특정 워크플로의 모든 거부된 세션 삭제",
                  "value": {
                    "delete_all": true,
                    "filter_status": [
                      "Declined"
                    ],
                    "filter_workflow_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "filter_date_from": "2026-09-01",
                    "filter_date_to": "2026-09-30"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "요청에서 일치하여 처리된 세션은 최대 20개입니다. 일치하는 세션당 하나의 결과가 반환되며, 일치하는 항목이 없는 번호(알 수 없거나 이미 삭제됨)는 건너뛰고 표시되지 않습니다. `face_retention_outcome`이 `failed_retryable`인 경우를 제외하고 결과는 삭제를 확인합니다. 이 세션은 삭제되지 않았으므로 재시도해야 합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "session_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "삭제된 세션입니다."
                          },
                          "session_number": {
                            "type": "integer",
                            "nullable": true,
                            "description": "삭제된 세션의 번호입니다."
                          },
                          "face_retention_outcome": {
                            "type": "string",
                            "enum": [
                              "retained_with_user",
                              "deleted",
                              "none",
                              "ineligible_no_vendor_user",
                              "failed_retryable"
                            ],
                            "description": "세션의 얼굴 생체 인식 데이터에 대해 수행된 작업입니다. `deleted`: 얼굴 임베딩이 세션과 함께 삭제되었습니다(기본값). `retained_with_user`: 세션은 삭제되고 이미지가 포함되지 않은 생체 인식 템플릿 하나가 사용자에 연결된 상태로 유지됩니다. `biometric_template_uuid`를 참조하세요. `none`: 세션에 얼굴 임베딩이 없었습니다(예: 라이브니스 셀피가 없는 문서 전용 KYC 세션. KYB 세션은 이 endpoint에서 선택되지 않습니다). `ineligible_no_vendor_user`: 보존이 요청되었으나 세션에 연결된 사용자가 없어 얼굴 임베딩이 세션과 함께 삭제되었습니다. `failed_retryable`(배치 endpoint 전용): 이 세션과 함께 삭제되던 그룹을 삭제할 수 없었습니다(스토리지 서비스, 생체 인식 저장소 또는 모니터링 공급자를 사용할 수 없음). 이 세션은 그대로 유지되므로 요청을 재시도하세요."
                          },
                          "biometric_template_uuid": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "`face_retention_outcome`이 `retained_with_user`일 때 보존된 생체 인식 템플릿의 ID입니다. 그 외의 경우 `null`입니다. `/v3/biometric-templates/{template_uuid}/`를 통해 관리합니다."
                          },
                          "biometric_template_expires_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "`face_retention_outcome`이 `retained_with_user`일 때 보존된 생체 인식 템플릿이 삭제되는 시점입니다. 템플릿이 보존되지 않은 경우 `null`입니다."
                          },
                          "deleted_child_verifications": {
                            "type": "integer",
                            "description": "KYC 세션만 삭제하는 이 endpoint에서는 항상 `0`입니다. `DELETE /v3/session/{sessionId}/delete/`로 기업 확인(KYB) 세션을 삭제하면 해당 세션이 생성하여 함께 삭제된 인증 건수가 보고됩니다."
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Mixed outcomes": {
                    "value": {
                      "results": [
                        {
                          "session_id": "4c5c7f3a-3b1d-4b7e-9c39-2b4f7e6a1d02",
                          "session_number": 1001,
                          "face_retention_outcome": "deleted",
                          "biometric_template_uuid": null,
                          "biometric_template_expires_at": null,
                          "deleted_child_verifications": 0
                        },
                        {
                          "session_id": "b8e1d2c3-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                          "session_number": 1002,
                          "face_retention_outcome": "retained_with_user",
                          "biometric_template_uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                          "biometric_template_expires_at": "2027-10-09T10:15:00Z",
                          "deleted_child_verifications": 0
                        },
                        {
                          "session_id": "7a1e9c2d-5f4b-4c3a-8e2d-1b0a9f8e7d6c",
                          "session_number": 1003,
                          "face_retention_outcome": "ineligible_no_vendor_user",
                          "biometric_template_uuid": null,
                          "biometric_template_expires_at": null,
                          "deleted_child_verifications": 0
                        },
                        {
                          "session_id": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
                          "session_number": 1004,
                          "face_retention_outcome": "failed_retryable",
                          "biometric_template_uuid": null,
                          "biometric_template_expires_at": null,
                          "deleted_child_verifications": 0
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "20개를 초과하는 세션이 일치했습니다. 백그라운드에서 삭제됩니다. `status`가 `COMPLETED` 또는 `FAILED`가 될 때까지 `GET /v3/sessions/delete/{job_id}/`를 폴링하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionDeletionJob"
                },
                "examples": {
                  "Job accepted": {
                    "value": {
                      "job_id": "5b8f2c1e-7d3a-4f6b-9e2c-1a0d8f7e6c5b",
                      "status": "PENDING",
                      "total": 250,
                      "processed": 0,
                      "outcomes": {
                        "deleted": 0,
                        "none": 0,
                        "retained_with_user": 0,
                        "ineligible_no_vendor_user": 0,
                        "failed_retryable": 0,
                        "already_deleted": 0
                      },
                      "deleted_child_verifications": 0,
                      "error": null,
                      "created_at": "2026-10-09T10:15:00Z",
                      "completed_at": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 오류 — 아무것도 삭제되지 않았습니다. 오류 값은 필드 이름을 키로 하는 메시지 문자열 배열입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session_numbers": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "additionalProperties": {
                    "description": "기타 키: List Sessions 필터가 아닌 `filter_*` 키(`\"Unknown filter.\"`), 또는 값을 읽을 수 없는 `filter_*` 키(해당 `filter_*` 키를 키로 하고 메시지 배열을 포함)."
                  }
                },
                "examples": {
                  "Missing selector": {
                    "summary": "session_numbers와 delete_all이 모두 제공되지 않았습니다",
                    "value": {
                      "session_numbers": [
                        "This field is required unless delete_all is true."
                      ]
                    }
                  },
                  "Empty list": {
                    "summary": "session_numbers가 빈 배열입니다",
                    "value": {
                      "session_numbers": [
                        "This list may not be empty."
                      ]
                    }
                  },
                  "Non-numeric entry": {
                    "summary": "session_numbers에 숫자가 아닌 문자열이 포함되어 있습니다",
                    "value": {
                      "session_numbers": [
                        "All session_numbers must be numeric."
                      ]
                    }
                  },
                  "Privacy erasure cannot retain": {
                    "summary": "deletion_instruction privacy_erasure가 retain_face_embeddings true와 결합되었습니다",
                    "value": {
                      "retain_face_embeddings": [
                        "Privacy erasure cannot retain biometric templates."
                      ]
                    }
                  },
                  "No finite retention duration": {
                    "summary": "요청 또는 애플리케이션에 face_retention_days 없이 보존이 요청됨",
                    "value": {
                      "detail": "A finite biometric-template retention duration is required."
                    }
                  },
                  "Unknown filter": {
                    "summary": "List Sessions에 없는 filter_* 키",
                    "value": {
                      "filter_reviewer": "Unknown filter."
                    }
                  },
                  "Unreadable filter value": {
                    "summary": "읽을 수 없는 필터 값",
                    "value": {
                      "filter_date_from": [
                        "Enter a valid date."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었습니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "x-api-key 헤더가 없거나 키가 유효하지 않습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "공유 쓰기 속도 제한을 초과했습니다(API 키당 분당 300개의 POST/PATCH/DELETE 요청). 재시도하기 전에 `Retry-After` 및 `X-RateLimit-*` 응답 헤더를 확인하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "쓰기 예산 소진됨",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "선택한 세션이 확정된 규제 보고서에 포함되어 있습니다. 아무것도 삭제되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InFiledReportError"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/sessions/delete/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"session_numbers\": [\"1001\", \"1002\", \"1003\"]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.batch_delete(\n    session_numbers=[\"1001\", \"1002\", \"1003\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.batchDelete({\n  session_numbers: [\"1001\", \"1002\", \"1003\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.BatchDelete(ctx, didit.SessionsBatchDeleteParams{\n\tSessionNumbers: didit.Some([]string{\"1001\", \"1002\", \"1003\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsBatchDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().batchDelete(SessionsBatchDeleteParams.builder()\n        .sessionNumbers(List.of(\"1001\", \"1002\", \"1003\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->batchDelete([\n    'session_numbers' => ['1001', '1002', '1003'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.batch_delete(session_numbers: [\"1001\", \"1002\", \"1003\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.BatchDeleteAsync(new SessionsBatchDeleteParams\n{\n    SessionNumbers = new string[] { \"1001\", \"1002\", \"1003\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/sessions/delete/{job_id}/": {
      "get": {
        "summary": "대량 세션 삭제 작업 조회",
        "description": "`POST /v3/sessions/delete/`가 `202`로 응답한 세션 대량 삭제 작업의 진행 상황입니다(`session_numbers`로 선택되었거나 `delete_all`을 사용하여 일치하는 세션이 20개를 초과하는 경우). `status`가 `PENDING` 또는 `PROCESSING`인 동안 몇 초마다 폴링하고, `COMPLETED` 또는 `FAILED`가 되면 중단하십시오.\n\n작업은 각 결과로 끝난 세션 수와 지금까지 처리한 세션 수를 보고하며, 삭제된 세션이 무엇인지는 보고하지 않습니다. `FAILED` 작업은 `error`에 그 이유를 포함합니다. 도달하지 못한 세션은 여전히 남아 있으므로 삭제 요청을 반복하여 삭제하십시오.\n\n**인증:** `x-api-key` 헤더의 API 키. 작업은 이를 생성한 애플리케이션에만 표시되며, 다른 `job_id`는 `404`를 반환합니다. 자격 증명이 누락되었거나 유효하지 않으면 `403`을 반환합니다. 이 API는 절대 `401`을 반환하지 않습니다.",
        "operationId": "get_session_deletion_job",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "retrieve_deletion_job",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "`POST /v3/sessions/delete/`의 `202`와 함께 반환된 `job_id`입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl 'https://verification.didit.me/v3/sessions/delete/JOB_ID/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.retrieve_deletion_job(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.retrieveDeletionJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.RetrieveDeletionJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().retrieveDeletionJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->retrieveDeletionJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.retrieve_deletion_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.RetrieveDeletionJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "작업입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionDeletionJob"
                },
                "examples": {
                  "Processing": {
                    "value": {
                      "job_id": "5b8f2c1e-7d3a-4f6b-9e2c-1a0d8f7e6c5b",
                      "status": "PROCESSING",
                      "total": 250,
                      "processed": 100,
                      "outcomes": {
                        "deleted": 82,
                        "none": 18,
                        "retained_with_user": 0,
                        "ineligible_no_vendor_user": 0,
                        "failed_retryable": 0,
                        "already_deleted": 0
                      },
                      "deleted_child_verifications": 0,
                      "error": null,
                      "created_at": "2026-10-09T10:15:00Z",
                      "completed_at": null
                    }
                  },
                  "Completed": {
                    "value": {
                      "job_id": "5b8f2c1e-7d3a-4f6b-9e2c-1a0d8f7e6c5b",
                      "status": "COMPLETED",
                      "total": 250,
                      "processed": 250,
                      "outcomes": {
                        "deleted": 204,
                        "none": 44,
                        "retained_with_user": 0,
                        "ineligible_no_vendor_user": 0,
                        "failed_retryable": 0,
                        "already_deleted": 2
                      },
                      "deleted_child_verifications": 0,
                      "error": null,
                      "created_at": "2026-10-09T10:15:00Z",
                      "completed_at": "2026-10-09T10:16:40Z"
                    }
                  },
                  "Failed": {
                    "value": {
                      "job_id": "5b8f2c1e-7d3a-4f6b-9e2c-1a0d8f7e6c5b",
                      "status": "FAILED",
                      "total": 250,
                      "processed": 100,
                      "outcomes": {
                        "deleted": 82,
                        "none": 18,
                        "retained_with_user": 0,
                        "ineligible_no_vendor_user": 0,
                        "failed_retryable": 0,
                        "already_deleted": 0
                      },
                      "deleted_child_verifications": 0,
                      "error": "The deletion stopped before it finished. The sessions it had not reached are still in place; repeat the request to delete them.",
                      "created_at": "2026-10-09T10:15:00Z",
                      "completed_at": "2026-10-09T10:15:52Z"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었습니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "x-api-key 헤더가 없거나 키가 유효하지 않습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "호출한 애플리케이션에 대해 이 `job_id`를 가진 삭제 작업이 존재하지 않습니다. 작업은 이를 생성한 애플리케이션에만 표시됩니다."
          }
        }
      }
    },
    "/v3/sessions/{session_id}/reviews/": {
      "get": {
        "summary": "세션 검토 및 활동 로그 목록 조회",
        "description": "사용자 인증(KYC) 세션의 감사 추적 / 활동 피드를 최신순으로 페이지네이션된 봉투(`count` / `next` / `previous` / `results`, 기본값 페이지당 50개 항목)로 반환합니다.\n\n피드 항목은 세션과 상호작용하는 모든 행위자에 의해 작성됩니다: `PATCH /v3/session/{session_id}/update-status/`를 통한 수동 결정(`previous_status` → `new_status` 기록), Console 검토자 활동(`@email` 멘션이 포함된 댓글, KYC/POA 데이터 수정, 파일 업로드/삭제, 태그 변경, 상세 페이지 조회), 지속적인 AML 모니터링 일치 항목, 동일한 경로에 `POST`로 추가된 메모. 이 피드를 읽는 것은 Didit Console 세션 보기의 **Activity** 패널과 API 측면에서 동일합니다.\n\n사용자 인증(KYC) 세션만 여기서 처리할 수 있으며, 기업 확인(KYB) 세션 ID는 `404`를 반환합니다.",
        "operationId": "list_session_reviews",
        "x-didit-sdk": {
          "resource": "sessions.reviews",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "description": "사용자 인증(KYC) 세션의 UUID입니다. API 키와 동일한 애플리케이션에 속해야 합니다. 다른 애플리케이션의 UUID, 삭제된 세션 및 기업 확인(KYB) 세션 ID는 모두 `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "페이지 크기입니다. 기본값은 `50`입니다.",
            "schema": {
              "type": "integer",
              "default": 50,
              "example": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "(정렬된) 피드의 시작 부분부터 건너뛸 항목 수입니다. 기본값은 `0`입니다. 응답의 `next` / `previous` URL에 피드를 순회하기 위한 올바른 값이 포함되어 있습니다.",
            "schema": {
              "type": "integer",
              "default": 0,
              "example": 0
            }
          },
          {
            "name": "ordering",
            "in": "query",
            "required": false,
            "description": "정렬 순서입니다. 피드의 기본값은 최신순(`-created_at`)이며, 오래된 순으로 조회하려면 `created_at`을 전달합니다. 알 수 없는 값은 오류 없이 무시되며(기본 순서 적용), 다른 시리얼라이저 필드 이름도 허용됩니다.",
            "schema": {
              "type": "string",
              "default": "-created_at",
              "example": "created_at"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "페이지가 나뉜 활동 피드이며 기본적으로 최신순으로 정렬됩니다. `count`는 전체 항목 수이며, `next` / `previous`는 사전에 구성된 페이지 URL입니다(양 끝에서는 `null`). 빈 `results`와 함께 `count`가 `0`인 경우 아직 기록된 활동이 없음을 의미합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "이 세션의 피드 항목 총 개수입니다(모든 페이지 합산).",
                      "example": 3
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "다음 페이지의 URL이며, 마지막 페이지에서는 `null`입니다.",
                      "example": null
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "이전 페이지의 URL이며, 첫 번째 페이지에서는 `null`입니다.",
                      "example": null
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ReviewItem"
                      },
                      "description": "이 페이지의 피드 항목입니다."
                    }
                  }
                },
                "examples": {
                  "DecisionTrail": {
                    "summary": "수동 승인 및 API로 추가된 메모",
                    "value": {
                      "count": 3,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "de0561bc-5583-4409-9171-1a31a4c8a5f4",
                          "activity_type": "STATUS_UPDATED",
                          "actor_display": "API Client",
                          "actor_email": null,
                          "actor_type": "API_KEY",
                          "new_status": "Approved",
                          "previous_status": "In Review",
                          "comment": "Document re-checked manually; address matches.",
                          "mentioned_emails": [],
                          "previous_value": {
                            "status": "In Review"
                          },
                          "new_value": {
                            "status": "Approved"
                          },
                          "changed_fields": [
                            "status"
                          ],
                          "metadata": null,
                          "created_at": "2026-06-12T00:19:31.918735Z"
                        },
                        {
                          "uuid": "35370f58-5098-44ee-8a06-8c9af80b2455",
                          "activity_type": "STATUS_UPDATED",
                          "actor_display": "Unknown",
                          "actor_email": null,
                          "actor_type": "CONSOLE_USER",
                          "new_status": null,
                          "previous_status": null,
                          "comment": "Note without status.",
                          "mentioned_emails": [],
                          "previous_value": null,
                          "new_value": null,
                          "changed_fields": [],
                          "metadata": null,
                          "created_at": "2026-06-12T00:18:44.504157Z"
                        },
                        {
                          "uuid": "00338f82-f1c5-4f57-8614-c49bb258af1a",
                          "activity_type": "STATUS_UPDATED",
                          "actor_display": "Unknown",
                          "actor_email": null,
                          "actor_type": "CONSOLE_USER",
                          "new_status": "In Review",
                          "previous_status": null,
                          "comment": "Flagging for manual document re-check.",
                          "mentioned_emails": [],
                          "previous_value": null,
                          "new_value": null,
                          "changed_fields": [],
                          "metadata": null,
                          "created_at": "2026-06-12T00:18:44.466537Z"
                        }
                      ]
                    }
                  },
                  "PaginatedFirstPage": {
                    "summary": "limit=2가 적용된 첫 번째 페이지 — next에 후속 URL이 포함됩니다.",
                    "value": {
                      "count": 4,
                      "next": "https://verification.didit.me/v3/sessions/8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d/reviews/?limit=2&offset=2",
                      "previous": null,
                      "results": [
                        {
                          "uuid": "de0561bc-5583-4409-9171-1a31a4c8a5f4",
                          "activity_type": "STATUS_UPDATED",
                          "actor_display": "API Client",
                          "actor_email": null,
                          "actor_type": "API_KEY",
                          "new_status": "Approved",
                          "previous_status": "In Review",
                          "comment": "Document re-checked manually; address matches.",
                          "mentioned_emails": [],
                          "previous_value": {
                            "status": "In Review"
                          },
                          "new_value": {
                            "status": "Approved"
                          },
                          "changed_fields": [
                            "status"
                          ],
                          "metadata": null,
                          "created_at": "2026-06-12T00:19:31.918735Z"
                        },
                        {
                          "uuid": "bd4e6227-bdd2-42b2-a726-1d12f785a457",
                          "activity_type": "STATUS_UPDATED",
                          "actor_display": "Unknown",
                          "actor_email": null,
                          "actor_type": "CONSOLE_USER",
                          "new_status": null,
                          "previous_status": null,
                          "comment": null,
                          "mentioned_emails": [],
                          "previous_value": null,
                          "new_value": null,
                          "changed_fields": [],
                          "metadata": null,
                          "created_at": "2026-06-12T00:18:44.540238Z"
                        }
                      ]
                    }
                  },
                  "Empty": {
                    "summary": "아직 기록된 활동이 없는 세션",
                    "value": {
                      "count": 0,
                      "next": null,
                      "previous": null,
                      "results": []
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key`가 누락되었거나 잘못된 형식이거나 만료되었거나 폐기되었습니다. 세션 조회 전에 인증을 먼저 확인하므로 세션 UUID가 존재하지 않는 경우에도 누락된 키는 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "You do not have permission to perform this action."
                    }
                  }
                },
                "examples": {
                  "InvalidKey": {
                    "summary": "x-api-key 헤더가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 UUID를 가진 사용자 인증(KYC) 세션을 애플리케이션에서 확인할 수 없습니다. UUID가 존재하지 않거나 세션이 삭제되었거나 다른 애플리케이션에 속해 있습니다. 기업 확인(KYB) 세션 ID 또한 여기서 `404`를 반환합니다. 검토 피드는 KYC 세션에 대해서만 조회할 수 있습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "Session not found."
                    }
                  }
                },
                "examples": {
                  "NotFound": {
                    "summary": "알 수 없거나, 삭제되었거나, 다른 애플리케이션에 속한 세션 UUID",
                    "value": {
                      "detail": "Session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. `Retry-After` 및 `X-RateLimit-*` 응답 헤더를 확인하세요. [속도 제한](/ko/integration/rate-limiting)을 참조하세요."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -s 'https://verification.didit.me/v3/sessions/8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d/reviews/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.reviews.list(\n    \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.reviews.list(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.Reviews.ListAutoPaging(ctx, \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", didit.SessionsReviewsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().reviews().list(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->sessions->reviews->list('8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.reviews.list(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.Reviews.ListAsync(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "summary": "세션의 감사 추적 기록에 검토 메모 추가",
        "description": "사용자 인증(KYC) 세션의 검토/활동 피드에 메모를 추가합니다. **이 endpoint는 항목만 기록하며, 세션을 절대 변경하지 않습니다.** 세션의 `status`는 변경되지 않고 유지되며, 상태 전환 유효성 검사가 실행되지 않고, webhook도 트리거되지 않습니다. 세션을 실제로 승인, 거부 또는 다시 열려면(이 피드에 모든 귀속 정보가 포함된 `STATUS_UPDATED` 항목도 함께 기록됨) 대신 `PATCH /v3/session/{session_id}/update-status/`를 사용하십시오.\n\n두 본문 필드는 모두 선택 사항이며 빈 JSON 객체도 허용됩니다. `new_status`는 항목의 레이블로만 저장되며 10개의 세션 상태 값 중 어느 것이든 허용됩니다(대소문자 구분). `comment` 내부의 `@email` 멘션은 일반 텍스트로만 저장되며, 이 endpoint에서 알림을 트리거하지 않고 항목의 `mentioned_emails`는 비어 있는 상태로 유지됩니다.\n\n귀속 관련 참고 사항: 여기서 생성된 항목에는 행위자 정보가 포함되지 않습니다. 피드에는 `actor_display: \"Unknown\"`, `actor_type: \"CONSOLE_USER\"`, `activity_type: \"STATUS_UPDATED\"`(저장소 기본값)로 표시되며, `201` 본문의 `user` 필드는 `\"Unknown\"`입니다.",
        "operationId": "create_session_review",
        "x-didit-sdk": {
          "resource": "sessions.reviews",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "Content-Type",
            "in": "header",
            "required": false,
            "description": "JSON 본문을 전송할 때 `application/json`으로 설정합니다.",
            "schema": {
              "type": "string",
              "example": "application/json"
            }
          },
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "description": "사용자 인증(KYC) 세션의 UUID입니다. API 키와 동일한 애플리케이션에 속해야 합니다. 다른 애플리케이션의 UUID, 삭제된 세션 및 기업 확인(KYB) 세션 ID는 모두 `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "new_status": {
                    "type": "string",
                    "nullable": true,
                    "enum": [
                      "Not Started",
                      "In Progress",
                      "Approved",
                      "Declined",
                      "In Review",
                      "Expired",
                      "Abandoned",
                      "Kyc Expired",
                      "Resubmitted",
                      "Awaiting User"
                    ],
                    "description": "항목에 기록할 선택 사항인 상태 라벨입니다. 대소문자를 구분하는 세션 상태 값을 허용합니다(`\"approved\"`는 `400`으로 거부됨). 여기에 상태를 기록해도 세션의 실제 상태는 변경되지 **않습니다**. 실제 상태를 변경하려면 상태 업데이트 endpoint를 사용하세요.",
                    "example": "In Review"
                  },
                  "comment": {
                    "type": "string",
                    "nullable": true,
                    "description": "선택적 자유 텍스트 메모입니다(적용되는 길이 제한 없음). 있는 그대로 저장되며, 이 endpoint에서는 `@email` 멘션이 처리되지 않습니다.",
                    "example": "Flagging for manual document re-check."
                  }
                }
              },
              "examples": {
                "NoteWithStatusLabel": {
                  "summary": "상태 라벨이 포함된 메모(세션 상태 변경 없음)",
                  "value": {
                    "new_status": "In Review",
                    "comment": "Flagging for manual document re-check."
                  }
                },
                "CommentOnly": {
                  "summary": "상태 라벨이 없는 일반 메모",
                  "value": {
                    "comment": "Customer emailed an updated utility bill; awaiting upload."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "세션의 감사 추적에 기록된 항목. 세션 자체는 변경되지 않으며, `status`는 이전 값을 유지하고 webhook은 전송되지 않습니다. 새 항목은 `GET …/reviews/` 상단에도 표시됩니다(`actor_display: \"Unknown\"` 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "type": "string",
                      "description": "항목 작성자의 표시 이름입니다. 이 endpoint를 통해 생성된 항목은 행위자 귀속을 기록하지 않으므로 항상 `\"Unknown\"`입니다.",
                      "example": "Unknown"
                    },
                    "new_status": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "Not Started",
                        "In Progress",
                        "Approved",
                        "Declined",
                        "In Review",
                        "Expired",
                        "Abandoned",
                        "Kyc Expired",
                        "Resubmitted",
                        "Awaiting User"
                      ],
                      "description": "항목에 기록된 상태 라벨이며, 전송된 라벨이 없는 경우 `null`입니다. 세션의 실제 상태에는 영향을 미치지 않습니다.",
                      "example": "In Review"
                    },
                    "comment": {
                      "type": "string",
                      "nullable": true,
                      "description": "항목에 기록된 메모이며, 전송된 내용이 없으면 `null`입니다.",
                      "example": "Flagging for manual document re-check."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "항목이 작성된 시점(ISO 8601 UTC)입니다.",
                      "example": "2026-06-12T00:18:44.466537Z"
                    }
                  }
                },
                "examples": {
                  "NoteWithStatusLabel": {
                    "summary": "상태 라벨이 있는 메모",
                    "value": {
                      "user": "Unknown",
                      "new_status": "In Review",
                      "comment": "Flagging for manual document re-check.",
                      "created_at": "2026-06-12T00:18:44.466537Z"
                    }
                  },
                  "CommentOnly": {
                    "summary": "일반 메모",
                    "value": {
                      "user": "Unknown",
                      "new_status": null,
                      "comment": "Note without status.",
                      "created_at": "2026-06-12T00:18:44.504157Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류이며, 필드별 메시지 맵으로 반환됩니다. 일반적인 원인은 `new_status` 값이 허용된 10개의 상태 중 하나가 아닌 경우입니다(대소문자 구분).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "new_status": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "\"approved\" is not a valid choice."
                      ]
                    }
                  }
                },
                "examples": {
                  "InvalidStatusChoice": {
                    "summary": "소문자 / 알 수 없는 상태 값",
                    "value": {
                      "new_status": [
                        "\"approved\" is not a valid choice."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key`가 누락되었거나 잘못된 형식이거나 만료되었거나 폐기되었습니다. 세션 조회 전에 인증을 먼저 확인하므로 세션 UUID가 존재하지 않는 경우에도 누락된 키는 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "You do not have permission to perform this action."
                    }
                  }
                },
                "examples": {
                  "InvalidKey": {
                    "summary": "x-api-key 헤더가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 UUID를 가진 사용자 인증(KYC) 세션을 애플리케이션에서 확인할 수 없습니다. UUID가 존재하지 않거나 세션이 삭제되었거나 다른 애플리케이션에 속해 있습니다. 기업 확인(KYB) 세션 ID 또한 여기서 `404`를 반환합니다. 검토 피드는 KYC 세션에 대해서만 조회할 수 있습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "Session not found."
                    }
                  }
                },
                "examples": {
                  "NotFound": {
                    "summary": "알 수 없거나, 삭제되었거나, 다른 애플리케이션에 속한 세션 UUID",
                    "value": {
                      "detail": "Session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. `Retry-After` 및 `X-RateLimit-*` 응답 헤더를 확인하세요. [속도 제한](/ko/integration/rate-limiting)을 참조하세요."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "# Records an audit-trail note only -- the session's status does NOT change.\ncurl -s -X POST https://verification.didit.me/v3/sessions/8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d/reviews/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"new_status\": \"In Review\",\n    \"comment\": \"Flagging for manual document re-check.\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.reviews.create(\n    \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\",\n    new_status=\"In Review\",\n    comment=\"Flagging for manual document re-check.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.reviews.create(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", {\n  new_status: \"In Review\",\n  comment: \"Flagging for manual document re-check.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Reviews.Create(ctx, \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", didit.SessionsReviewsCreateParams{\n\tNewStatus: didit.Some(didit.SessionsReviewsCreateParamsNewStatus(\"In Review\")),\n\tComment:   didit.String(\"Flagging for manual document re-check.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsReviewsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().reviews().create(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", SessionsReviewsCreateParams.builder()\n        .newStatus(SessionsReviewsCreateParams.NewStatus.of(\"In Review\"))\n        .comment(\"Flagging for manual document re-check.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->reviews->create('8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d', [\n    'new_status' => 'In Review',\n    'comment' => 'Flagging for manual document re-check.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.reviews.create(\n  \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\",\n  new_status: \"In Review\",\n  comment: \"Flagging for manual document re-check.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Reviews.CreateAsync(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", new SessionsReviewsCreateParams\n{\n    NewStatus = new SessionsReviewsCreateParamsNewStatus(\"In Review\"),\n    Comment = \"Flagging for manual document re-check.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/billing/balance/": {
      "get": {
        "summary": "크레딧 잔액 조회",
        "description": "USD 기준 현재 선불 크레딧 잔액(조직 전체) 및 자동 충전 설정을 조회합니다. 금액은 십진수 문자열이므로 decimal 라이브러리로 파싱하십시오.",
        "operationId": "get_billing_balance",
        "x-didit-sdk": {
          "resource": "billing",
          "method": "retrieve_balance",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Billing"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/billing/balance/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.billing.retrieve_balance()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.billing.retrieveBalance();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Billing.RetrieveBalance(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.billing().retrieveBalance();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->billing->retrieveBalance();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.billing.retrieve_balance\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Billing.RetrieveBalanceAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "현재 크레딧 잔액 및 조직의 자동 충전 설정입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "balance",
                    "auto_refill_enabled"
                  ],
                  "properties": {
                    "balance": {
                      "type": "string",
                      "description": "USD 기준 현재 선불 크레딧 잔액(고정소수점 십진수 문자열)입니다. 인증 요금이 청구될 때 차감되고 충전이 정산되면 증가합니다."
                    },
                    "auto_refill_enabled": {
                      "type": "boolean",
                      "description": "`true`인 경우 잔액이 `auto_refill_threshold` 미만으로 내려가면 Didit이 저장된 결제 수단으로 자동 청구하여 크레딧을 충전합니다. 콘솔 → 결제에서 구성합니다."
                    },
                    "auto_refill_amount": {
                      "type": "string",
                      "nullable": true,
                      "description": "자동 충전 시마다 액면가 그대로 청구되어 잔액에 추가될 USD 금액입니다. Console → 결제에서 \\$50부터 \\$20,000까지 설정할 수 있습니다. 자동 충전이 비활성화되어 있거나 설정되지 않은 경우 `null`입니다."
                    },
                    "auto_refill_threshold": {
                      "type": "string",
                      "nullable": true,
                      "description": "USD 단위의 트리거 임계값입니다. `balance`가 이 값 아래로 떨어지면 자동 충전이 실행됩니다. 자동 충전이 비활성화되어 있거나 설정되지 않은 경우 `null`입니다."
                    }
                  }
                },
                "examples": {
                  "Healthy balance with auto-refill": {
                    "value": {
                      "balance": "1234.5600",
                      "auto_refill_enabled": true,
                      "auto_refill_amount": "500.00",
                      "auto_refill_threshold": "100.00"
                    }
                  },
                  "Low balance, manual top-up only": {
                    "value": {
                      "balance": "12.0000",
                      "auto_refill_enabled": false,
                      "auto_refill_amount": null,
                      "auto_refill_threshold": null
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 폐기되었거나, 해당 키에 이 조직의 결제 데이터를 읽을 수 있는 권한이 없습니다. 누락된 키는 `403`을 반환하며, 잘못되었거나 폐기되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/billing/top-up/": {
      "post": {
        "summary": "크레딧 충전",
        "description": "호스팅된 Stripe Checkout 세션을 통해 크레딧 충전(충전당 **\\$50~\\$20,000**). 충전은 Free, Growth 및 Scale 요금제에서 사용할 수 있으며, 할인이나 보너스 없이 액면가 그대로 추가되고 12개월간 유지됩니다. Enterprise 연간 계약은 충전할 수 없습니다. 반환된 `checkout_session_url`로 고객을 리디렉션하십시오.",
        "operationId": "billing_top_up",
        "x-didit-sdk": {
          "resource": "billing",
          "method": "top_up",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Billing"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount_in_dollars"
                ],
                "properties": {
                  "amount_in_dollars": {
                    "type": "number",
                    "minimum": 50,
                    "maximum": 20000,
                    "description": "청구할 금액(USD)입니다. **50에서 20,000 사이여야 합니다.** 잔액은 할인이나 보너스 없이 동일한 금액으로 충전됩니다. 세금은 고객의 결제 주소를 바탕으로 결제 시 자동 추가됩니다."
                  },
                  "success_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "결제 성공 후 호스팅 체크아웃이 고객을 리디렉션하는 URL입니다. 현재 기본값은 `https://console.didit.me`입니다. 기본 호스트를 사용할 수 없으므로 정상 작동하는 URL을 명시적으로 전달하세요. 호스팅 체크아웃이 세션 ID를 대체하도록 하려면 리터럴 플레이스홀더인 `{CHECKOUT_SESSION_ID}`를 추가하세요."
                  },
                  "cancel_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "고객이 체크아웃 창을 중단하거나 닫을 때 호스팅 체크아웃이 고객을 리디렉션하는 URL입니다. 현재 기본값은 `https://console.didit.me`입니다. 기본 호스트를 사용할 수 없으므로 정상 작동하는 URL을 명시적으로 전달하세요."
                  }
                }
              },
              "examples": {
                "Minimum top-up": {
                  "value": {
                    "amount_in_dollars": 50
                  }
                },
                "Custom amount with redirects": {
                  "value": {
                    "amount_in_dollars": 500,
                    "success_url": "https://yourapp.com/billing/top-up/success",
                    "cancel_url": "https://yourapp.com/billing/top-up/cancel"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/billing/top-up/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"amount_in_dollars\": 500,\n    \"success_url\": \"https://yourapp.com/billing/success\",\n    \"cancel_url\": \"https://yourapp.com/billing/cancel\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.billing.top_up(\n    amount_in_dollars=50.0,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.billing.topUp({\n  amount_in_dollars: 50.0,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Billing.TopUp(ctx, didit.BillingTopUpParams{\n\tAmountInDollars: 50.0,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BillingTopUpParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.billing().topUp(BillingTopUpParams.builder()\n        .amountInDollars(50.0)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->billing->topUp([\n    'amount_in_dollars' => 50.0,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.billing.top_up(amount_in_dollars: 50.0)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Billing.TopUpAsync(new BillingTopUpParams\n{\n    AmountInDollars = 50.0,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "호스팅 결제 세션이 생성되었습니다. 결제를 완료하도록 사용자를 `checkout_session_url`로 리디렉션하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "checkout_session_id",
                    "checkout_session_url"
                  ],
                  "properties": {
                    "checkout_session_id": {
                      "type": "string",
                      "description": "호스팅 결제 세션 식별자(예: `cs_test_a1B2c3...`)입니다. 서버 측 대사 작업에 유용합니다."
                    },
                    "checkout_session_url": {
                      "type": "string",
                      "format": "uri",
                      "description": "일회용 호스팅 결제 페이지 URL입니다. 결제를 완료하려면 고객을 이 페이지로 리디렉션하십시오."
                    }
                  }
                },
                "examples": {
                  "Created": {
                    "value": {
                      "checkout_session_id": "cs_test_a1B2c3D4e5F6g7H8i9J0",
                      "checkout_session_url": "https://checkout.example.com/c/pay/cs_test_a1B2c3D4e5F6g7H8i9J0"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 payload: 금액이 누락되었거나, 숫자가 아니거나, 최소 금액인 \\$50 미만이거나 최대 금액인 \\$20,000를 초과했거나, 조직이 Enterprise 연간 계약을 이용 중입니다. 오류 본문은 JSON 배열입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing amount": {
                    "value": [
                      "amount_in_dollars is required."
                    ]
                  },
                  "Not a number": {
                    "value": [
                      "amount_in_dollars must be a number."
                    ]
                  },
                  "Below minimum": {
                    "value": [
                      "Amount must be at least $50."
                    ]
                  },
                  "Above maximum": {
                    "value": [
                      "Amount must be at most $20,000."
                    ]
                  },
                  "Annual plan": {
                    "value": [
                      "You have an annual plan. Contact your account manager to top up."
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 취소되었습니다. 또는 키가 이 조직에 대한 충전 세션을 생성할 수 없습니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/destinations/": {
      "get": {
        "summary": "webhook 대상 목록 조회",
        "description": "모든 webhook 대상 목록을 조회합니다(페이지네이션되지 않은 배열, 오래된 순). 각 항목에는 대상의 구성, 지난 30일간(`metrics_window_days`)의 전송 지표(일별 하나의 `daily_points` 항목 포함), 대상의 상태(`health_status`, `failing_streak`, `failing_since`, `last_success_at`)가 포함됩니다. 목록에는 `summary` 객체가 없으며 서명 비밀 키는 절대 포함되지 않습니다. 각 항목에는 `secret_last4`만 표시됩니다. `secret_shared_key`를 확인하려면 단일 대상(`GET /v3/webhook/destinations/{destination_uuid}/`)을 조회하십시오.",
        "operationId": "list_webhook_destinations",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/webhook/destinations/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.list()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.list();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.List(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().list();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->list();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.webhooks.destinations.list.each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.ListAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "webhook 대상 목록(페이지 매김 없음, 오래된 순서대로).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "uuid": {
                        "type": "string",
                        "format": "uuid",
                        "description": "안정적인 대상 식별자입니다. 수정/삭제 시 `{destination_uuid}`로 사용하세요."
                      },
                      "label": {
                        "type": "string",
                        "description": "콘솔에 표시되는 사람이 읽기 쉬운 이름입니다."
                      },
                      "url": {
                        "type": "string",
                        "format": "uri",
                        "description": "webhook payload가 포함된 `POST` 요청을 수신하는 대상 URL입니다."
                      },
                      "enabled": {
                        "type": "boolean",
                        "description": "`false`인 경우 Didit은 이 대상으로의 전송을 알림 없이 건너뜁니다."
                      },
                      "webhook_version": {
                        "type": "string",
                        "enum": [
                          "v1",
                          "v2",
                          "v3"
                        ],
                        "description": "이 대상으로 전송되는 payload 스키마 버전입니다. `v3`가 현재 권장되는 형식입니다."
                      },
                      "subscribed_events": {
                        "$ref": "#/components/schemas/WebhookSubscribedEvents"
                      },
                      "subscribed_events_count": {
                        "type": "integer",
                        "description": "UI 렌더링에 유용한 `subscribed_events`의 캐시된 길이입니다."
                      },
                      "deliveries_count": {
                        "type": "integer",
                        "description": "지난 30일 동안 이 대상에 수행된 전송 시도 횟수(재시도 포함)입니다."
                      },
                      "failed_deliveries_count": {
                        "type": "integer",
                        "description": "지난 30일 동안 대상이 HTTP 400 이상으로 응답했거나 응답하지 않은(시간 초과, 연결 거부 또는 차단된 주소) 전송 시도 횟수입니다."
                      },
                      "average_response_time_ms": {
                        "type": "integer",
                        "nullable": true,
                        "description": "지난 30일간의 평균 응답 시간(밀리초)으로, 정수로 반올림됩니다. 해당 기간 내 전송이 없었던 경우 `null`입니다."
                      },
                      "error_rate_percentage": {
                        "type": "integer",
                        "description": "지난 30일간의 `round(failed_deliveries_count / deliveries_count * 100)`; 전송 내역이 없으면 `0`입니다."
                      },
                      "last_delivery_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "가장 최근 전송 시도(성공 또는 실패)의 타임스탬프입니다. 전송된 적이 없는 경우 `null`입니다."
                      },
                      "metrics_window_days": {
                        "type": "integer",
                        "description": "`deliveries_count`, `failed_deliveries_count`, `average_response_time_ms`, `error_rate_percentage`, `daily_points`가 적용되는 기간(일 단위)입니다. 항상 `30`입니다."
                      },
                      "health_status": {
                        "type": "string",
                        "enum": [
                          "healthy",
                          "degraded",
                          "failing"
                        ],
                        "description": "전송 상태입니다. `failing`: 대상이 마지막으로 성공적으로 응답한 이후 3개 이상의 연속 이벤트가 첫 번째 전송 시도에서 실패했습니다(`failing_streak` 참조). `degraded`: failing 상태는 아니지만 지난 24시간 동안 전송 시도가 실패했고 이후 시도에서도 해당 이벤트를 전송하지 못했습니다. 전송에 성공하는 재시도 또는 재발송이 발생하면 이 상태가 해제됩니다. `healthy`: 둘 다 해당하지 않습니다. `enabled`와 무관합니다. 실패한 시도는 HTTP 400 이상의 응답을 받았거나 응답이 전혀 없는 시도를 의미합니다."
                      },
                      "failing_streak": {
                        "type": "integer",
                        "description": "최근 30일 이내에 대상이 마지막으로 성공적인 응답을 보낸 이후, 첫 번째 전송 시도에 실패한 연속 이벤트 수입니다. 재시도는 계산되지 않으며 재시도 또는 재발송을 포함한 성공적인 시도가 있으면 연속 실패가 종료됩니다. 마지막 성공 이후 실패한 이벤트가 없으면 `0`입니다."
                      },
                      "failing_since": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "현재 `failing_streak`의 첫 번째 실패 시도가 발생한 시점입니다. `failing_streak`가 `0`인 경우 `null`입니다."
                      },
                      "last_success_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "최근 30일 이내에 대상이 400 미만의 HTTP 상태로 전송에 마지막으로 응답한 시점입니다. 해당 기간 내에 응답이 없었던 경우 `null`입니다."
                      },
                      "environment": {
                        "type": "string",
                        "enum": [
                          "live",
                          "sandbox"
                        ],
                        "description": "대상을 소유한 애플리케이션의 환경."
                      },
                      "daily_points": {
                        "type": "array",
                        "description": "전송이 없었던 날을 포함하여 지난 30일 동안의 UTC 일자당 항목 1개(가장 오래된 항목부터 정렬)입니다. 재시도를 포함한 모든 시도 횟수를 집계합니다.",
                        "items": {
                          "type": "object",
                          "properties": {
                            "date": {
                              "type": "string",
                              "format": "date",
                              "description": "UTC 기준 일자입니다."
                            },
                            "total_deliveries": {
                              "type": "integer",
                              "description": "해당 일에 시도된 전송 시도 횟수입니다."
                            },
                            "failed_deliveries": {
                              "type": "integer",
                              "description": "해당 날짜에 수행된 시도 중 HTTP 400 이상으로 응답되었거나 전혀 응답되지 않은 시도 횟수입니다."
                            }
                          }
                        }
                      },
                      "secret_last4": {
                        "type": "string",
                        "description": "대상의 현재 서명 비밀의 마지막 4자로, 비밀을 서로 구분할 수 있습니다. 서명 검증에는 충분하지 않습니다."
                      },
                      "created_by_email": {
                        "type": "string",
                        "nullable": true,
                        "description": "대상을 생성한 Business Console 멤버의 이메일입니다. API 키로 생성된 대상의 경우 `null`입니다."
                      },
                      "created_by_name": {
                        "type": "string",
                        "nullable": true,
                        "description": "대상을 생성한 Business Console 멤버의 이름입니다. API 키로 생성된 대상의 경우 `null`입니다."
                      },
                      "created_at": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "updated_at": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "examples": {
                  "Two destinations": {
                    "value": [
                      {
                        "uuid": "11111111-2222-3333-4444-555555555555",
                        "label": "Production session webhooks",
                        "url": "https://yourapp.com/webhooks/didit",
                        "enabled": true,
                        "webhook_version": "v3",
                        "subscribed_events": [
                          "status.updated",
                          "data.updated"
                        ],
                        "subscribed_events_count": 2,
                        "deliveries_count": 12453,
                        "failed_deliveries_count": 14,
                        "average_response_time_ms": 187,
                        "error_rate_percentage": 0,
                        "last_delivery_at": "2026-05-17T09:21:18Z",
                        "metrics_window_days": 30,
                        "health_status": "healthy",
                        "failing_streak": 0,
                        "failing_since": null,
                        "last_success_at": "2026-05-17T09:21:18Z",
                        "environment": "live",
                        "daily_points": [
                          {
                            "date": "2026-04-18",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-19",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-20",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-21",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-22",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-23",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-24",
                            "total_deliveries": 415,
                            "failed_deliveries": 9
                          },
                          {
                            "date": "2026-04-25",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-26",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-27",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-28",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-29",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-30",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-01",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-02",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-03",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-04",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-05",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-06",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-07",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-08",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-09",
                            "total_deliveries": 415,
                            "failed_deliveries": 5
                          },
                          {
                            "date": "2026-05-10",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-11",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-12",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-13",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-14",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-15",
                            "total_deliveries": 416,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-16",
                            "total_deliveries": 416,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-17",
                            "total_deliveries": 416,
                            "failed_deliveries": 0
                          }
                        ],
                        "secret_last4": "0xnQ",
                        "created_by_email": null,
                        "created_by_name": null,
                        "created_at": "2026-01-04T08:00:00Z",
                        "updated_at": "2026-04-22T14:09:11Z"
                      },
                      {
                        "uuid": "22222222-3333-4444-5555-666666666666",
                        "label": "Staging mirror",
                        "url": "https://staging.yourapp.com/webhooks/didit",
                        "enabled": false,
                        "webhook_version": "v3",
                        "subscribed_events": [
                          "status.updated"
                        ],
                        "subscribed_events_count": 1,
                        "deliveries_count": 0,
                        "failed_deliveries_count": 0,
                        "average_response_time_ms": null,
                        "error_rate_percentage": 0,
                        "last_delivery_at": null,
                        "metrics_window_days": 30,
                        "health_status": "healthy",
                        "failing_streak": 0,
                        "failing_since": null,
                        "last_success_at": null,
                        "environment": "live",
                        "daily_points": [
                          {
                            "date": "2026-04-18",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-19",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-20",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-21",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-22",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-23",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-24",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-25",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-26",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-27",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-28",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-29",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-30",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-01",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-02",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-03",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-04",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-05",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-06",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-07",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-08",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-09",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-10",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-11",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-12",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-13",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-14",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-15",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-16",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-17",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          }
                        ],
                        "secret_last4": "k9Qe",
                        "created_by_email": "reviewer@example.com",
                        "created_by_name": "Example Reviewer",
                        "created_at": "2026-03-12T10:15:02Z",
                        "updated_at": "2026-03-12T10:15:02Z"
                      }
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나, 형식이 잘못되었거나, 만료되었거나, 다른 애플리케이션으로 범위가 지정되었습니다. 키가 누락된 경우 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "webhook 대상 생성",
        "description": "webhook 대상을 생성합니다. 응답에는 자동 생성된 `secret_shared_key` HMAC 서명 비밀이 포함됩니다(나중에 `GET /v3/webhook/destinations/{destination_uuid}/`를 통해서도 읽을 수 있음). 항상 최소 하나의 이벤트가 포함된 `subscribed_events`를 전송하십시오(와일드카드 사용 불가). 빈 목록을 명시적으로 전달하면 400으로 거부되며, 필드를 생략하면 아무것도 구독하지 않는 대상이 생성되어 webhook을 수신할 수 없습니다. `(application, url)` 쌍은 애플리케이션의 대상 간에 고유해야 합니다.",
        "operationId": "create_webhook_destination",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/webhook/destinations/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"label\": \"Production session webhooks\",\n    \"url\": \"https://yourapp.com/webhooks/didit\",\n    \"webhook_version\": \"v3\",\n    \"subscribed_events\": [\"status.updated\", \"data.updated\"]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.create(\n    label=\"Production session webhooks\",\n    url=\"https://yourapp.com/webhooks/didit\",\n    webhook_version=\"v3\",\n    subscribed_events=[\"status.updated\", \"data.updated\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.create({\n  label: \"Production session webhooks\",\n  url: \"https://yourapp.com/webhooks/didit\",\n  webhook_version: \"v3\",\n  subscribed_events: [\"status.updated\", \"data.updated\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.Create(ctx, didit.WebhooksDestinationsCreateParams{\n\tLabel:            \"Production session webhooks\",\n\tURL:              \"https://yourapp.com/webhooks/didit\",\n\tWebhookVersion:   didit.Some(didit.WebhooksDestinationsCreateParamsWebhookVersion(\"v3\")),\n\tSubscribedEvents: didit.Some([]didit.WebhookEvent{didit.WebhookEvent(\"status.updated\"), didit.WebhookEvent(\"data.updated\")}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.WebhookEvent;\nimport me.didit.types.WebhooksDestinationsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().create(WebhooksDestinationsCreateParams.builder()\n        .label(\"Production session webhooks\")\n        .url(\"https://yourapp.com/webhooks/didit\")\n        .webhookVersion(WebhooksDestinationsCreateParams.WebhookVersion.of(\"v3\"))\n        .subscribedEvents(List.of(WebhookEvent.of(\"status.updated\"), WebhookEvent.of(\"data.updated\")))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->create([\n    'label' => 'Production session webhooks',\n    'url' => 'https://yourapp.com/webhooks/didit',\n    'webhook_version' => 'v3',\n    'subscribed_events' => ['status.updated', 'data.updated'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.create(\n  label: \"Production session webhooks\",\n  url: \"https://yourapp.com/webhooks/didit\",\n  webhook_version: \"v3\",\n  subscribed_events: [\"status.updated\", \"data.updated\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.CreateAsync(new WebhooksDestinationsCreateParams\n{\n    Label = \"Production session webhooks\",\n    Url = \"https://yourapp.com/webhooks/didit\",\n    WebhookVersion = new WebhooksDestinationsCreateParamsWebhookVersion(\"v3\"),\n    SubscribedEvents = new WebhookEvent[] { \"status.updated\", \"data.updated\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "label",
                  "url"
                ],
                "properties": {
                  "label": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Console → Webhooks에 표시되는 사람이 읽기 쉬운 이름입니다. 여러 대상이 있을 때 대상을 구분하는 데 도움이 됩니다(예: \"Prod\", \"Staging mirror\")."
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "`POST` 요청을 수신할 HTTPS URL입니다. 애플리케이션의 대상 간에 고유해야 합니다. 안정적이고 보안이 강화된 endpoint를 사용하십시오. Didit은 백오프 일정에 따라 실패한 전송을 재시도합니다.",
                    "maxLength": 2000
                  },
                  "enabled": {
                    "type": "boolean",
                    "default": true,
                    "description": "`false`인 경우 대상은 저장되지만 Didit은 해당 대상에 webhook을 푸시하지 않습니다. 보류해 두고자 하는 스테이징 구성에 유용합니다."
                  },
                  "webhook_version": {
                    "type": "string",
                    "enum": [
                      "v1",
                      "v2",
                      "v3"
                    ],
                    "description": "Didit이 전송할 payload 스키마 버전입니다. `v3`가 현재 권장되는 형식이며, 이전 버전은 레거시 연동과의 하위 호환성을 위해 유지됩니다."
                  },
                  "subscribed_events": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/WebhookSubscribedEvents"
                      }
                    ],
                    "description": "전송할 이벤트입니다. 사실상 필수 항목입니다. 명시적인 `[]`는 400 오류로 거부되며, 필드를 생략하면 구독이 없는 대상이 생성되어 아무것도 수신하지 않습니다."
                  }
                }
              },
              "examples": {
                "session_updates": {
                  "summary": "세션 상태 및 데이터 업데이트",
                  "value": {
                    "label": "Production session webhooks",
                    "url": "https://yourapp.com/webhooks/didit",
                    "webhook_version": "v3",
                    "subscribed_events": [
                      "status.updated",
                      "data.updated"
                    ]
                  }
                },
                "transaction_updates": {
                  "summary": "거래 모니터링 업데이트",
                  "value": {
                    "label": "Transaction monitoring webhooks",
                    "url": "https://yourapp.com/webhooks/didit-transactions",
                    "webhook_version": "v3",
                    "subscribed_events": [
                      "transaction.created",
                      "transaction.status.updated"
                    ]
                  }
                },
                "entity_updates": {
                  "summary": "사용자 및 기업 엔터티 업데이트",
                  "value": {
                    "label": "Entity lifecycle webhooks",
                    "url": "https://yourapp.com/webhooks/didit-entities",
                    "webhook_version": "v3",
                    "subscribed_events": [
                      "user.status.updated",
                      "user.data.updated",
                      "business.status.updated",
                      "business.data.updated",
                      "activity.created"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "대상이 생성되었습니다. `secret_shared_key`는 HMAC 서명 비밀입니다. 지금 저장하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "안정적인 대상 식별자입니다. 후속 호출에서 `{destination_uuid}`로 사용하세요."
                    },
                    "label": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "enabled": {
                      "type": "boolean"
                    },
                    "webhook_version": {
                      "type": "string",
                      "enum": [
                        "v1",
                        "v2",
                        "v3"
                      ]
                    },
                    "secret_shared_key": {
                      "type": "string",
                      "description": "이 대상에 바인딩된 자동 생성 HMAC 서명 비밀(43자 URL 안전 token)입니다. 수신되는 webhook의 서명 헤더를 검증하는 데 사용합니다. API 키 호출자에게는 항상 전체가 반환됩니다. 콘솔 사용자는 `read:webhooks` 권한이 필요하며, 그렇지 않으면 빈 문자열이 표시됩니다."
                    },
                    "secret_last4": {
                      "type": "string",
                      "description": "대상의 현재 서명 비밀의 마지막 4자로, 비밀을 서로 구분할 수 있습니다. 서명 검증에는 충분하지 않습니다."
                    },
                    "previous_secret_expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Business Console에서 대상의 서명 비밀이 교체된 후 24시간 동안 설정됩니다. 이 시점까지 해당 대상으로 이루어지는 모든 전송에는 교체된 비밀로 생성된 `X-Signature-Previous`, `X-Signature-V2-Previous`, `X-Signature-Simple-Previous`도 함께 포함됩니다([서명 검증](/ko/integration/webhooks#서명-검증) 참조). 지난 24시간 동안 교체된 적이 없으면 `null`입니다."
                    },
                    "subscribed_events": {
                      "$ref": "#/components/schemas/WebhookSubscribedEvents"
                    },
                    "created_by_email": {
                      "type": "string",
                      "nullable": true,
                      "description": "대상을 생성한 Business Console 멤버의 이메일입니다. API 키로 생성된 대상의 경우 `null`입니다."
                    },
                    "created_by_name": {
                      "type": "string",
                      "nullable": true,
                      "description": "대상을 생성한 Business Console 멤버의 이름입니다. API 키로 생성된 대상의 경우 `null`입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "health_status": {
                      "type": "string",
                      "enum": [
                        "healthy",
                        "degraded",
                        "failing"
                      ],
                      "description": "전송 상태입니다. `failing`: 대상이 마지막으로 성공적으로 응답한 이후 3개 이상의 연속 이벤트가 첫 번째 전송 시도에서 실패했습니다(`failing_streak` 참조). `degraded`: failing 상태는 아니지만 지난 24시간 동안 전송 시도가 실패했고 이후 시도에서도 해당 이벤트를 전송하지 못했습니다. 전송에 성공하는 재시도 또는 재발송이 발생하면 이 상태가 해제됩니다. `healthy`: 둘 다 해당하지 않습니다. `enabled`와 무관합니다. 실패한 시도는 HTTP 400 이상의 응답을 받았거나 응답이 전혀 없는 시도를 의미합니다."
                    },
                    "failing_streak": {
                      "type": "integer",
                      "description": "최근 30일 이내에 대상이 마지막으로 성공적인 응답을 보낸 이후, 첫 번째 전송 시도에 실패한 연속 이벤트 수입니다. 재시도는 계산되지 않으며 재시도 또는 재발송을 포함한 성공적인 시도가 있으면 연속 실패가 종료됩니다. 마지막 성공 이후 실패한 이벤트가 없으면 `0`입니다."
                    },
                    "failing_since": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "현재 `failing_streak`의 첫 번째 실패 시도가 발생한 시점입니다. `failing_streak`가 `0`인 경우 `null`입니다."
                    },
                    "last_success_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "최근 30일 이내에 대상이 400 미만의 HTTP 상태로 전송에 마지막으로 응답한 시점입니다. 해당 기간 내에 응답이 없었던 경우 `null`입니다."
                    },
                    "environment": {
                      "type": "string",
                      "enum": [
                        "live",
                        "sandbox"
                      ],
                      "description": "대상을 소유한 애플리케이션의 환경."
                    },
                    "summary": {
                      "type": "object",
                      "description": "최근 `metrics_window_days`(30)일 동안의 전송 지표입니다. `last_delivery_at`은 시점과 관계없이 가장 최근의 시도를 나타냅니다.",
                      "properties": {
                        "total_deliveries": {
                          "type": "integer"
                        },
                        "failed_deliveries": {
                          "type": "integer"
                        },
                        "error_rate_percentage": {
                          "type": "integer"
                        },
                        "min_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "avg_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "max_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "last_delivery_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "metrics_window_days": {
                          "type": "integer",
                          "description": "다른 요약 지표가 적용되는 기간(일 단위)입니다. 항상 `30`입니다."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Created": {
                    "value": {
                      "uuid": "11111111-2222-3333-4444-555555555555",
                      "label": "Production session webhooks",
                      "url": "https://yourapp.com/webhooks/didit",
                      "enabled": true,
                      "webhook_version": "v3",
                      "secret_shared_key": "tno2NTeRC1ZK3sBOYlBJDyEzBVENl3pQ1AcZyAW0xnQ",
                      "secret_last4": "0xnQ",
                      "previous_secret_expires_at": null,
                      "subscribed_events": [
                        "status.updated",
                        "data.updated"
                      ],
                      "created_by_email": null,
                      "created_by_name": null,
                      "created_at": "2026-05-17T10:00:00Z",
                      "updated_at": "2026-05-17T10:00:00Z",
                      "health_status": "healthy",
                      "failing_streak": 0,
                      "failing_since": null,
                      "last_success_at": null,
                      "environment": "live",
                      "summary": {
                        "total_deliveries": 0,
                        "failed_deliveries": 0,
                        "error_rate_percentage": 0,
                        "min_response_time_ms": null,
                        "avg_response_time_ms": null,
                        "max_response_time_ms": null,
                        "last_delivery_at": null,
                        "metrics_window_days": 30
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 실패 — 일반적으로 중복된 URL, 누락되었거나 유효하지 않은 `subscribed_events`, 또는 알 수 없는 이벤트 이름 때문입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Duplicate URL": {
                    "value": {
                      "url": [
                        "This webhook destination already exists for the application."
                      ]
                    }
                  },
                  "Empty events list": {
                    "value": {
                      "subscribed_events": [
                        "At least one subscribed event is required."
                      ]
                    }
                  },
                  "Unknown event": {
                    "value": {
                      "subscribed_events": [
                        "Unsupported webhook events: foo.bar"
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나, 형식이 잘못되었거나, 만료되었거나, 다른 애플리케이션으로 범위가 지정되었습니다. 키가 누락된 경우 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/destinations/{destination_uuid}/": {
      "get": {
        "summary": "webhook 대상 가져오기",
        "description": "`secret_shared_key` 서명 비밀, 상태(`health_status`, `failing_streak`, `failing_since`, `last_success_at`) 및 지난 30일 동안의 전송 `summary`를 포함한 단일 webhook 대상을 조회합니다. API 키 호출자는 항상 비밀 전문을 받습니다. `read:webhooks` 권한이 없는 콘솔 사용자는 빈 문자열을 보게 됩니다.",
        "operationId": "get_webhook_destination",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "webhook 대상의 UUID입니다(생성/조회 시 반환된 `uuid`).",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "webhook 대상 세부 정보입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "label": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "enabled": {
                      "type": "boolean"
                    },
                    "webhook_version": {
                      "type": "string",
                      "enum": [
                        "v1",
                        "v2",
                        "v3"
                      ]
                    },
                    "secret_shared_key": {
                      "type": "string",
                      "description": "HMAC 서명 비밀(43자 URL에서 안전한 token)입니다. API 키 호출자에게는 항상 전체가 반환되며, Console 사용자에게는 `read:webhooks`가 필요하고, 그렇지 않으면 빈 문자열입니다."
                    },
                    "secret_last4": {
                      "type": "string",
                      "description": "대상의 현재 서명 비밀의 마지막 4자로, 비밀을 서로 구분할 수 있습니다. 서명 검증에는 충분하지 않습니다."
                    },
                    "previous_secret_expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Business Console에서 대상의 서명 비밀이 교체된 후 24시간 동안 설정됩니다. 이 시점까지 해당 대상으로 이루어지는 모든 전송에는 교체된 비밀로 생성된 `X-Signature-Previous`, `X-Signature-V2-Previous`, `X-Signature-Simple-Previous`도 함께 포함됩니다([서명 검증](/ko/integration/webhooks#서명-검증) 참조). 지난 24시간 동안 교체된 적이 없으면 `null`입니다."
                    },
                    "subscribed_events": {
                      "$ref": "#/components/schemas/WebhookSubscribedEvents"
                    },
                    "created_by_email": {
                      "type": "string",
                      "nullable": true,
                      "description": "대상을 생성한 Business Console 멤버의 이메일입니다. API 키로 생성된 대상의 경우 `null`입니다."
                    },
                    "created_by_name": {
                      "type": "string",
                      "nullable": true,
                      "description": "대상을 생성한 Business Console 멤버의 이름입니다. API 키로 생성된 대상의 경우 `null`입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "health_status": {
                      "type": "string",
                      "enum": [
                        "healthy",
                        "degraded",
                        "failing"
                      ],
                      "description": "전송 상태입니다. `failing`: 대상이 마지막으로 성공적으로 응답한 이후 3개 이상의 연속 이벤트가 첫 번째 전송 시도에서 실패했습니다(`failing_streak` 참조). `degraded`: failing 상태는 아니지만 지난 24시간 동안 전송 시도가 실패했고 이후 시도에서도 해당 이벤트를 전송하지 못했습니다. 전송에 성공하는 재시도 또는 재발송이 발생하면 이 상태가 해제됩니다. `healthy`: 둘 다 해당하지 않습니다. `enabled`와 무관합니다. 실패한 시도는 HTTP 400 이상의 응답을 받았거나 응답이 전혀 없는 시도를 의미합니다."
                    },
                    "failing_streak": {
                      "type": "integer",
                      "description": "최근 30일 이내에 대상이 마지막으로 성공적인 응답을 보낸 이후, 첫 번째 전송 시도에 실패한 연속 이벤트 수입니다. 재시도는 계산되지 않으며 재시도 또는 재발송을 포함한 성공적인 시도가 있으면 연속 실패가 종료됩니다. 마지막 성공 이후 실패한 이벤트가 없으면 `0`입니다."
                    },
                    "failing_since": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "현재 `failing_streak`의 첫 번째 실패 시도가 발생한 시점입니다. `failing_streak`가 `0`인 경우 `null`입니다."
                    },
                    "last_success_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "최근 30일 이내에 대상이 400 미만의 HTTP 상태로 전송에 마지막으로 응답한 시점입니다. 해당 기간 내에 응답이 없었던 경우 `null`입니다."
                    },
                    "environment": {
                      "type": "string",
                      "enum": [
                        "live",
                        "sandbox"
                      ],
                      "description": "대상을 소유한 애플리케이션의 환경."
                    },
                    "summary": {
                      "type": "object",
                      "description": "최근 `metrics_window_days`(30)일 동안의 전송 지표입니다. `last_delivery_at`은 시점과 관계없이 가장 최근의 시도를 나타냅니다.",
                      "properties": {
                        "total_deliveries": {
                          "type": "integer"
                        },
                        "failed_deliveries": {
                          "type": "integer"
                        },
                        "error_rate_percentage": {
                          "type": "integer"
                        },
                        "min_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "avg_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "max_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "last_delivery_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "metrics_window_days": {
                          "type": "integer",
                          "description": "다른 요약 지표가 적용되는 기간(일 단위)입니다. 항상 `30`입니다."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Healthy destination": {
                    "value": {
                      "uuid": "11111111-2222-3333-4444-555555555555",
                      "label": "Production session webhooks",
                      "url": "https://yourapp.com/webhooks/didit",
                      "enabled": true,
                      "webhook_version": "v3",
                      "secret_shared_key": "tno2NTeRC1ZK3sBOYlBJDyEzBVENl3pQ1AcZyAW0xnQ",
                      "secret_last4": "0xnQ",
                      "previous_secret_expires_at": null,
                      "subscribed_events": [
                        "status.updated",
                        "data.updated"
                      ],
                      "created_by_email": null,
                      "created_by_name": null,
                      "created_at": "2026-01-04T08:00:00Z",
                      "updated_at": "2026-04-22T14:09:11Z",
                      "health_status": "healthy",
                      "failing_streak": 0,
                      "failing_since": null,
                      "last_success_at": "2026-05-17T09:21:18Z",
                      "environment": "live",
                      "summary": {
                        "total_deliveries": 12453,
                        "failed_deliveries": 14,
                        "error_rate_percentage": 0,
                        "min_response_time_ms": 41,
                        "avg_response_time_ms": 187,
                        "max_response_time_ms": 2103,
                        "last_delivery_at": "2026-05-17T09:21:18Z",
                        "metrics_window_days": 30
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나, 형식이 잘못되었거나, 만료되었거나, 다른 애플리케이션으로 범위가 지정되었습니다. 키가 누락된 경우 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 UUID를 가진 대상이 존재하지 않거나, 다른 애플리케이션에 속해 있거나, 삭제되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "webhook 대상 업데이트",
        "description": "webhook 대상을 업데이트합니다. **`subscribed_events`는 병합되지 않고 전체가 대체(REPLACED)됩니다**: 먼저 조회한 후 추가하여 다시 전송하십시오. 시크릿은 교체되지 않습니다. 본문의 `uuid`는 무시되며 경로에서 대상 이름을 지정합니다.",
        "operationId": "update_webhook_destination",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "업데이트할 webhook 대상의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string",
                    "description": "새로운 읽기 쉬운 이름입니다."
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "새 대상 URL입니다. 애플리케이션 내에서 고유해야 합니다."
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "이 대상을 삭제하지 않고 전송을 일시 중지하려면 `false`로 설정합니다."
                  },
                  "webhook_version": {
                    "type": "string",
                    "enum": [
                      "v1",
                      "v2",
                      "v3"
                    ],
                    "description": "향후 전송에 사용할 새 payload 스키마 버전입니다."
                  },
                  "subscribed_events": {
                    "$ref": "#/components/schemas/WebhookSubscribedEvents"
                  }
                }
              },
              "examples": {
                "Pause destination": {
                  "value": {
                    "enabled": false
                  }
                },
                "Add transaction events": {
                  "value": {
                    "subscribed_events": [
                      "status.updated",
                      "data.updated",
                      "transaction.created",
                      "transaction.status.updated"
                    ]
                  }
                },
                "Move target URL": {
                  "value": {
                    "label": "Production session webhooks v2",
                    "url": "https://api.yourapp.com/webhooks/didit/v2"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"subscribed_events\": [\n      \"status.updated\",\n      \"data.updated\",\n      \"transaction.created\"\n    ]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    enabled=False,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.update(\"11111111-2222-3333-4444-555555555555\", {\n  enabled: false,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.WebhooksDestinationsUpdateParams{\n\tEnabled: didit.Bool(false),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.WebhooksDestinationsUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().update(\"11111111-2222-3333-4444-555555555555\", WebhooksDestinationsUpdateParams.builder()\n        .enabled(false)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->update('11111111-2222-3333-4444-555555555555', [\n    'enabled' => false,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  enabled: false\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new WebhooksDestinationsUpdateParams\n{\n    Enabled = false,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "업데이트된 webhook 대상입니다. 본문의 형태는 `GET /v3/webhook/destinations/{destination_uuid}/`와 동일합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "label": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "enabled": {
                      "type": "boolean"
                    },
                    "webhook_version": {
                      "type": "string",
                      "enum": [
                        "v1",
                        "v2",
                        "v3"
                      ]
                    },
                    "secret_shared_key": {
                      "type": "string"
                    },
                    "secret_last4": {
                      "type": "string",
                      "description": "대상의 현재 서명 비밀의 마지막 4자로, 비밀을 서로 구분할 수 있습니다. 서명 검증에는 충분하지 않습니다."
                    },
                    "previous_secret_expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Business Console에서 대상의 서명 비밀이 교체된 후 24시간 동안 설정됩니다. 이 시점까지 해당 대상으로 이루어지는 모든 전송에는 교체된 비밀로 생성된 `X-Signature-Previous`, `X-Signature-V2-Previous`, `X-Signature-Simple-Previous`도 함께 포함됩니다([서명 검증](/ko/integration/webhooks#서명-검증) 참조). 지난 24시간 동안 교체된 적이 없으면 `null`입니다."
                    },
                    "subscribed_events": {
                      "$ref": "#/components/schemas/WebhookSubscribedEvents"
                    },
                    "created_by_email": {
                      "type": "string",
                      "nullable": true,
                      "description": "대상을 생성한 Business Console 멤버의 이메일입니다. API 키로 생성된 대상의 경우 `null`입니다."
                    },
                    "created_by_name": {
                      "type": "string",
                      "nullable": true,
                      "description": "대상을 생성한 Business Console 멤버의 이름입니다. API 키로 생성된 대상의 경우 `null`입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "health_status": {
                      "type": "string",
                      "enum": [
                        "healthy",
                        "degraded",
                        "failing"
                      ],
                      "description": "전송 상태입니다. `failing`: 대상이 마지막으로 성공적으로 응답한 이후 3개 이상의 연속 이벤트가 첫 번째 전송 시도에서 실패했습니다(`failing_streak` 참조). `degraded`: failing 상태는 아니지만 지난 24시간 동안 전송 시도가 실패했고 이후 시도에서도 해당 이벤트를 전송하지 못했습니다. 전송에 성공하는 재시도 또는 재발송이 발생하면 이 상태가 해제됩니다. `healthy`: 둘 다 해당하지 않습니다. `enabled`와 무관합니다. 실패한 시도는 HTTP 400 이상의 응답을 받았거나 응답이 전혀 없는 시도를 의미합니다."
                    },
                    "failing_streak": {
                      "type": "integer",
                      "description": "최근 30일 이내에 대상이 마지막으로 성공적인 응답을 보낸 이후, 첫 번째 전송 시도에 실패한 연속 이벤트 수입니다. 재시도는 계산되지 않으며 재시도 또는 재발송을 포함한 성공적인 시도가 있으면 연속 실패가 종료됩니다. 마지막 성공 이후 실패한 이벤트가 없으면 `0`입니다."
                    },
                    "failing_since": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "현재 `failing_streak`의 첫 번째 실패 시도가 발생한 시점입니다. `failing_streak`가 `0`인 경우 `null`입니다."
                    },
                    "last_success_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "최근 30일 이내에 대상이 400 미만의 HTTP 상태로 전송에 마지막으로 응답한 시점입니다. 해당 기간 내에 응답이 없었던 경우 `null`입니다."
                    },
                    "environment": {
                      "type": "string",
                      "enum": [
                        "live",
                        "sandbox"
                      ],
                      "description": "대상을 소유한 애플리케이션의 환경."
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "total_deliveries": {
                          "type": "integer"
                        },
                        "failed_deliveries": {
                          "type": "integer"
                        },
                        "error_rate_percentage": {
                          "type": "integer"
                        },
                        "min_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "avg_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "max_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "last_delivery_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "metrics_window_days": {
                          "type": "integer",
                          "description": "다른 요약 지표가 적용되는 기간(일 단위)입니다. 항상 `30`입니다."
                        }
                      },
                      "description": "최근 `metrics_window_days`(30)일 동안의 전송 지표입니다. `last_delivery_at`은 시점과 관계없이 가장 최근의 시도를 나타냅니다."
                    }
                  }
                },
                "examples": {
                  "Paused": {
                    "value": {
                      "uuid": "11111111-2222-3333-4444-555555555555",
                      "label": "Production session webhooks",
                      "url": "https://yourapp.com/webhooks/didit",
                      "enabled": false,
                      "webhook_version": "v3",
                      "secret_shared_key": "tno2NTeRC1ZK3sBOYlBJDyEzBVENl3pQ1AcZyAW0xnQ",
                      "secret_last4": "0xnQ",
                      "previous_secret_expires_at": null,
                      "subscribed_events": [
                        "status.updated",
                        "data.updated"
                      ],
                      "created_by_email": null,
                      "created_by_name": null,
                      "created_at": "2026-01-04T08:00:00Z",
                      "updated_at": "2026-05-17T11:02:55Z",
                      "health_status": "healthy",
                      "failing_streak": 0,
                      "failing_since": null,
                      "last_success_at": "2026-05-17T09:21:18Z",
                      "environment": "live",
                      "summary": {
                        "total_deliveries": 12453,
                        "failed_deliveries": 14,
                        "error_rate_percentage": 0,
                        "min_response_time_ms": 41,
                        "avg_response_time_ms": 187,
                        "max_response_time_ms": 2103,
                        "last_delivery_at": "2026-05-17T09:21:18Z",
                        "metrics_window_days": 30
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 실패(중복된 URL, 비어 있거나 알 수 없는 이벤트 목록, 잘못된 형식의 본문).",
            "content": {
              "application/json": {
                "examples": {
                  "Duplicate URL": {
                    "value": {
                      "url": [
                        "This webhook destination already exists for the application."
                      ]
                    }
                  },
                  "Empty events": {
                    "value": {
                      "subscribed_events": [
                        "At least one subscribed event is required."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나, 형식이 잘못되었거나, 만료되었거나, 다른 애플리케이션으로 범위가 지정되었습니다. 키가 누락된 경우 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "해당 UUID를 가진 대상이 존재하지 않습니다(또는 삭제되었거나 다른 애플리케이션에 속함).",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "summary": "webhook 대상 삭제",
        "description": "webhook 대상, 해당 서명 비밀 및 전체 전송 로그를 영구적으로 삭제합니다. 이 작업은 실행 취소할 수 없습니다. 대상 URL로 새 webhook이 전송되지 않으며, 동일한 이벤트를 구독하는 다른 대상은 계속 수신합니다. 삭제 후 해당 대상은 `GET /v3/webhook/destinations/`에 더 이상 나타나지 않으며, 전송, 전송 상세 정보 및 재전송을 포함하여 `/v3/webhook/destinations/{destination_uuid}/` 아래의 모든 경로는 404를 응답합니다. 애플리케이션의 기존 `webhook_url`은 남아 있는 활성화된 대상 중 가장 오래된 대상의 URL로 설정되거나, 활성화된 대상이 남아 있지 않으면 삭제됩니다. DELETE를 다시 호출하면 404가 반환됩니다.",
        "operationId": "delete_webhook_destination",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "삭제할 webhook 대상의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.webhooks.destinations.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.webhooks.destinations.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Webhooks.Destinations.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.webhooks().destinations().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->webhooks->destinations->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.webhooks.destinations.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Webhooks.Destinations.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ],
        "responses": {
          "204": {
            "description": "대상, 서명 비밀 및 전송 로그가 영구적으로 삭제되었습니다. 응답 본문이 없습니다."
          },
          "403": {
            "description": "API 키가 누락되었거나, 형식이 잘못되었거나, 만료되었거나, 다른 애플리케이션으로 범위가 지정되었습니다. 키가 누락된 경우 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 이 UUID를 가진 대상이 존재하지 않습니다(이미 삭제되었거나 존재한 적이 없음).",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/wallet-screening/": {
      "post": {
        "summary": "지갑 주소 스크리닝",
        "description": "거래를 생성하지 않고 단일 암호화폐 지갑/주소에 대해 온디맨드 AML 스크리닝을 실행합니다. 애플리케이션에 구성된 블록체인 분석 공급자를 확인하고, 주소를 동기식으로 스크리닝하며, 정규화된 위험 결과를 반환합니다. LIGHTNING은 Marketplace를 통해 추가된 Elliptic 또는 Chainalysis BYOK 연결에서만 사용할 수 있습니다. 거래 테이블에는 아무것도 기록되지 않습니다. 성공한 스크리닝 건당 1회의 AML 모니터링 사용량이 청구됩니다(샌드박스 애플리케이션에는 청구되지 않음).",
        "operationId": "screenWallet",
        "x-didit-sdk": {
          "resource": "wallet_screening",
          "method": "screen",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "wallet_address"
                ],
                "properties": {
                  "wallet_address": {
                    "type": "string",
                    "description": "스크리닝할 암호화폐 주소 또는 네트워크 식별자입니다. 선택한 네트워크와 일치해야 합니다(예: EVM 체인의 경우 `0x`로 시작하는 40자 16진수 주소). 별칭: `address`.",
                    "example": "0x94f1b9b64e2932f6a2db338f616844400cd58e8a"
                  },
                  "blockchain": {
                    "type": "string",
                    "description": "선택적 네트워크 식별자입니다. 생략 시 주소 형식에서 네트워크를 판별합니다. `bc1`, `1`, `3` 주소는 비트코인(BTC), `T` 주소는 트론(TRX), base58 공개 키는 솔라나(SOL)입니다. `0x` 주소는 모든 EVM 네트워크에서 유효하므로, 이에 대해 `blockchain`을 생략하면 `candidate_chains`의 후보 네트워크와 함께 422 응답을 반환합니다. 관리형 스크리닝은 BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE(Base), OP(Optimism), ARB(Arbitrum One), AVAX(Avalanche C-Chain), ADA(Cardano), XLM(Stellar), HBAR(Hedera)를 지원합니다. USDT 및 USDC는 레거시 이더리움 별칭이며 다중 네트워크 검색이 아닙니다. 연결된 제공업체의 지원 범위는 다를 수 있습니다. LIGHTNING은 지원되는 연결된 제공업체가 필요합니다. CELO(Celo), MODE(Mode), PLUME(Plume)은 연결된 TRM Labs 계정을 통해 스크리닝되며, 관리형 스크리닝에서는 400을 반환합니다. 별칭: `currency`.",
                    "enum": [
                      "BTC",
                      "LIGHTNING",
                      "ETH",
                      "LTC",
                      "XRP",
                      "BCH",
                      "DOGE",
                      "TRX",
                      "SOL",
                      "MATIC",
                      "BNB",
                      "USDT",
                      "USDC",
                      "BASE",
                      "OP",
                      "ARB",
                      "AVAX",
                      "ADA",
                      "XLM",
                      "HBAR",
                      "CELO",
                      "MODE",
                      "PLUME"
                    ],
                    "example": "ETH"
                  },
                  "direction": {
                    "type": "string",
                    "description": "선택 사항입니다. 주소가 인바운드(입금) 또는 아웃바운드(출금) 거래 상대방으로 스크리닝되는지 여부입니다. `inbound`, `outbound`, `deposit`, `withdrawal`을 허용합니다. 생략 시 전송 전 중립적 스크리닝으로 기본 설정됩니다. 이는 공급자에게 컨텍스트로만 전달되며, 반환되는 `risk_score`와 `severity`, 그리고 `direction`과 관계없이 항상 둘 다 반환되는 `source_of_funds`/`destination_of_funds` 분석 내역을 변경하지 않습니다. 따라서 `direction`을 변경하거나 생략해도 주소를 다시 스크리닝할 필요가 없습니다.",
                    "enum": [
                      "inbound",
                      "outbound",
                      "deposit",
                      "withdrawal"
                    ]
                  }
                }
              },
              "example": {
                "wallet_address": "0x94f1b9b64e2932f6a2db338f616844400cd58e8a",
                "blockchain": "ETH"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/wallet-screening/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"wallet_address\": \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n    \"blockchain\": \"ETH\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.wallet_screening.screen(\n    wallet_address=\"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n    blockchain=\"ETH\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.walletScreening.screen({\n  wallet_address: \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n  blockchain: \"ETH\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.WalletScreening.Screen(ctx, didit.WalletScreeningScreenParams{\n\tWalletAddress: \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n\tBlockchain:    didit.Some(didit.WalletScreeningScreenParamsBlockchain(\"ETH\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.WalletScreeningScreenParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.walletScreening().screen(WalletScreeningScreenParams.builder()\n        .walletAddress(\"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\")\n        .blockchain(WalletScreeningScreenParams.Blockchain.of(\"ETH\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->walletScreening->screen([\n    'wallet_address' => '0x94f1b9b64e2932f6a2db338f616844400cd58e8a',\n    'blockchain' => 'ETH',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.wallet_screening.screen(\n  wallet_address: \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n  blockchain: \"ETH\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.WalletScreening.ScreenAsync(new WalletScreeningScreenParams\n{\n    WalletAddress = \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n    Blockchain = new WalletScreeningScreenParamsBlockchain(\"ETH\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "정규화된 지갑 스크리닝 결과입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletScreeningResult"
                },
                "example": {
                  "provider": "merklescience",
                  "screening_type": "WALLET_SCREENING",
                  "risk_score": 95,
                  "severity": "CRITICAL",
                  "status": "SCREENED",
                  "summary": "Merkle Science risk: Critical (5/5). SANCTIONS HIT. Dominant risk: sanctioned. Driven by: the address is attributed to Sanctions / OFAC (Example Sanctions)",
                  "wallet_address": "0x94f1b9b64e2932f6a2db338f616844400cd58e8a",
                  "transaction_hash": null,
                  "blockchain": "ETH",
                  "block_timestamp": null,
                  "total_value_usd": null,
                  "fee_usd": null,
                  "sender_rows": [],
                  "receiver_rows": [],
                  "transaction_flows": [],
                  "transaction_flows_status": null,
                  "transaction_flows_error": null,
                  "source_of_funds": [
                    {
                      "category": "sanctioned",
                      "percentage": 100.0,
                      "amount_usd": 9813695.0,
                      "entity_name": "Example Sanctions",
                      "entity_type": "Sanctions",
                      "entity_subtype": "OFAC",
                      "hops": null,
                      "description": "Sanctions / OFAC",
                      "is_direct": true,
                      "exposure_direction": "incoming",
                      "exposure_type": "direct",
                      "provider_entity_id": "118885",
                      "provider_entity_type_id": "30",
                      "provider_entity_subtype_id": "125",
                      "country": "",
                      "raw_amount": null,
                      "raw_currency": null
                    }
                  ],
                  "destination_of_funds": [
                    {
                      "category": "defi",
                      "percentage": 84.824453,
                      "amount_usd": 7783414.38,
                      "entity_name": "Example DeFi 7",
                      "entity_type": "DeFi",
                      "entity_subtype": "Bridges",
                      "hops": null,
                      "description": "DeFi / Bridges",
                      "is_direct": false,
                      "exposure_direction": "outgoing",
                      "exposure_type": "indirect",
                      "provider_entity_id": "118459",
                      "provider_entity_type_id": "33",
                      "provider_entity_subtype_id": "143",
                      "country": "",
                      "raw_amount": null,
                      "raw_currency": null
                    },
                    {
                      "category": "defi",
                      "percentage": 15.175547,
                      "amount_usd": 1392494.37,
                      "entity_name": "Example DeFi 2",
                      "entity_type": "DeFi",
                      "entity_subtype": "Yield Aggregator",
                      "hops": null,
                      "description": "DeFi / Yield Aggregator",
                      "is_direct": false,
                      "exposure_direction": "outgoing",
                      "exposure_type": "indirect",
                      "provider_entity_id": "90192",
                      "provider_entity_type_id": "33",
                      "provider_entity_subtype_id": "142",
                      "country": "",
                      "raw_amount": null,
                      "raw_currency": null
                    }
                  ],
                  "counterparty_connections": [
                    {
                      "entity_name": "Example Sanctions",
                      "entity_type": "Sanctions",
                      "entity_subtype": "OFAC",
                      "risk_level": "critical",
                      "categories": [
                        "sanctioned"
                      ],
                      "received_usd": null,
                      "sent_usd": null,
                      "received_hops": null,
                      "sent_hops": null,
                      "percentage": 0.0,
                      "is_direct": true,
                      "country": null,
                      "provider_entity_id": null
                    },
                    {
                      "entity_name": "Example Sanctions",
                      "entity_type": "Sanctions",
                      "entity_subtype": "OFAC",
                      "risk_level": "critical",
                      "categories": [
                        "sanctioned"
                      ],
                      "received_usd": null,
                      "sent_usd": null,
                      "received_hops": null,
                      "sent_hops": null,
                      "percentage": 0.0,
                      "is_direct": true,
                      "country": null,
                      "provider_entity_id": null
                    }
                  ],
                  "network_nodes": [],
                  "network_edges": [],
                  "sanctions_hit": true,
                  "pep_counterparty": null,
                  "dominant_risk_category": "sanctioned",
                  "risk_factors": [
                    {
                      "source": "attribution",
                      "category": "sanctioned",
                      "label": "Sanctions / OFAC",
                      "entity_name": "Example Sanctions",
                      "direction": "attribution",
                      "exposure_type": "attribution",
                      "amount_usd": null,
                      "percentage": 0.0,
                      "is_high_risk": true,
                      "description": "the address is attributed to Sanctions / OFAC (Example Sanctions)"
                    },
                    {
                      "source": "exposure",
                      "category": "sanctioned",
                      "label": "Sanctions / OFAC",
                      "entity_name": "Example Sanctions",
                      "direction": "incoming",
                      "exposure_type": "direct",
                      "amount_usd": 9813695.0,
                      "percentage": 51.679304,
                      "is_high_risk": true,
                      "description": "51.6793% direct incoming exposure to Sanctions / OFAC (Example Sanctions)"
                    },
                    {
                      "source": "exposure",
                      "category": "defi",
                      "label": "DeFi / Bridges",
                      "entity_name": "Example DeFi 7",
                      "direction": "outgoing",
                      "exposure_type": "indirect",
                      "amount_usd": 7783414.38,
                      "percentage": 40.987766,
                      "is_high_risk": false,
                      "description": "40.9878% indirect outgoing exposure to DeFi / Bridges (Example DeFi 7)"
                    },
                    {
                      "source": "exposure",
                      "category": "defi",
                      "label": "DeFi / Yield Aggregator",
                      "entity_name": "Example DeFi 2",
                      "direction": "outgoing",
                      "exposure_type": "indirect",
                      "amount_usd": 1392494.37,
                      "percentage": 7.33293,
                      "is_high_risk": false,
                      "description": "7.33293% indirect outgoing exposure to DeFi / Yield Aggregator (Example DeFi 2)"
                    }
                  ],
                  "raw_response": {
                    "...": "provider-specific details"
                  },
                  "report_signature": "<hmac-sha256 over the result, scoped to your application>"
                }
              }
            }
          },
          "400": {
            "description": "검증 오류 — 잘못된 형식의 지갑 주소, 누락된 `wallet_address`, 지원되지 않는 `blockchain`, 네트워크 이름이 명시되지 않는 형식의 주소에서 `blockchain` 생략, 또는 Elliptic이나 Chainalysis BYOK Marketplace 연동이 없는 LIGHTNING."
          },
          "401": {
            "description": "`x-api-key`가 누락되었거나 유효하지 않습니다."
          },
          "409": {
            "description": "애플리케이션에 구성된 AML 제공업체가 없거나, 구성된 제공업체가 아직 지갑 스크리닝을 지원하지 않습니다. 먼저 거래 모니터링을 구성하세요."
          },
          "422": {
            "description": "모든 EVM 네트워크가 공유하는 `0x` 주소에 대해 `blockchain`이 생략되었습니다. 아무것도 스크리닝되거나 청구되지 않았습니다. `blockchain`을 `candidate_chains` 중 하나로 설정하여 다시 전송하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "blockchain": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "A 0x address is valid on every EVM chain. Send blockchain as one of: ETH, BNB, MATIC, BASE, ARB, OP, CELO, MODE, PLUME."
                      ]
                    },
                    "candidate_chains": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "ETH",
                        "BNB",
                        "MATIC",
                        "BASE",
                        "ARB",
                        "OP",
                        "CELO",
                        "MODE",
                        "PLUME"
                      ]
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "AML 제공업체가 스크리닝을 완료할 수 없습니다. 나중에 다시 시도해 주세요."
          }
        }
      }
    },
    "/v3/wallet-screening/pdf/": {
      "post": {
        "summary": "지갑 스크리닝 결과를 PDF로 렌더링",
        "description": "`POST /v3/wallet-screening/`의 상태 비저장(stateless) 동반 기능: 해당 endpoint가 반환한 정확한 JSON 본문(추가된 `report_signature` 포함)을 다시 전송하여 동일한 결과의 Didit 브랜드 PDF를 받습니다. 제공업체를 호출하지 않으며 요금이 청구되거나 데이터가 보존되지 않습니다. 이는 Didit이 이미 생성한 결과를 다시 렌더링하기만 합니다. 서명은 PDF를 수정되지 않은 결과와 연결하므로, 다시 전송하기 전에 `risk_score`, `severity`, `sanctions_hit` 또는 기타 서명된 필드를 수정하면 `400` 오류가 발생합니다.",
        "operationId": "screenWalletPdf",
        "x-didit-sdk": {
          "resource": "wallet_screening",
          "method": "screen_pdf",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "`report_signature`를 포함하여 `POST /v3/wallet-screening/`에서 반환된 수정되지 않은 JSON 객체입니다.",
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WalletScreeningResult"
                  }
                ],
                "required": [
                  "report_signature"
                ],
                "description": "`POST /v3/wallet-screening/` 응답과 동일한 형태입니다. `report_signature`를 포함하여 해당 응답 본문을 그대로 다시 전달하십시오."
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "# $RESULT is the saved JSON body from POST /v3/wallet-screening/\ncurl -X POST 'https://verification.didit.me/v3/wallet-screening/pdf/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d \"$RESULT\" \\\n  -o wallet_screening_report.pdf"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.wallet_screening.screen_pdf(\n    provider=\"your-provider\",\n    screening_type=\"WALLET_SCREENING\",\n    risk_score=1,\n    severity=\"UNKNOWN\",\n    status=\"SCREENED\",\n    summary=\"your-summary\",\n    wallet_address=\"your-wallet-address\",\n    blockchain=\"your-blockchain\",\n    source_of_funds=[{}],\n    destination_of_funds=[{}],\n    counterparty_connections=[{}],\n    sanctions_hit=True,\n    dominant_risk_category=\"your-dominant-risk-category\",\n    report_signature=\"your-report-signature\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.walletScreening.screenPdf({\n  provider: \"your-provider\",\n  screening_type: \"WALLET_SCREENING\",\n  risk_score: 1,\n  severity: \"UNKNOWN\",\n  status: \"SCREENED\",\n  summary: \"your-summary\",\n  wallet_address: \"your-wallet-address\",\n  blockchain: \"your-blockchain\",\n  source_of_funds: [{}],\n  destination_of_funds: [{}],\n  counterparty_connections: [{}],\n  sanctions_hit: true,\n  dominant_risk_category: \"your-dominant-risk-category\",\n  report_signature: \"your-report-signature\",\n});\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.WalletScreening.ScreenPDF(ctx, didit.WalletScreeningResultParam{\n\tProvider:                \"your-provider\",\n\tScreeningType:           \"WALLET_SCREENING\",\n\tRiskScore:               1,\n\tSeverity:                \"UNKNOWN\",\n\tStatus:                  \"SCREENED\",\n\tSummary:                 \"your-summary\",\n\tWalletAddress:           \"your-wallet-address\",\n\tBlockchain:              \"your-blockchain\",\n\tSourceOfFunds:           []didit.WalletScreeningResultParamSourceOfFunds{{}},\n\tDestinationOfFunds:      []didit.WalletScreeningResultParamDestinationOfFunds{{}},\n\tCounterpartyConnections: []didit.WalletScreeningResultParamCounterpartyConnections{{}},\n\tSanctionsHit:            true,\n\tDominantRiskCategory:    didit.String(\"your-dominant-risk-category\"),\n\tReportSignature:         \"your-report-signature\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.WalletScreeningResult;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.walletScreening().screenPdf(WalletScreeningResult.builder()\n        .provider(\"your-provider\")\n        .screeningType(WalletScreeningResult.ScreeningType.of(\"WALLET_SCREENING\"))\n        .riskScore(1L)\n        .severity(WalletScreeningResult.Severity.of(\"UNKNOWN\"))\n        .status(WalletScreeningResult.Status.of(\"SCREENED\"))\n        .summary(\"your-summary\")\n        .walletAddress(\"your-wallet-address\")\n        .blockchain(\"your-blockchain\")\n        .sourceOfFunds(List.of(WalletScreeningResult.SourceOfFunds.builder()\n                .build()))\n        .destinationOfFunds(List.of(WalletScreeningResult.DestinationOfFunds.builder()\n                .build()))\n        .counterpartyConnections(List.of(WalletScreeningResult.CounterpartyConnections.builder()\n                .build()))\n        .sanctionsHit(true)\n        .dominantRiskCategory(\"your-dominant-risk-category\")\n        .reportSignature(\"your-report-signature\")\n        .build())\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->walletScreening->screenPdf([\n    'provider' => 'your-provider',\n    'screening_type' => 'WALLET_SCREENING',\n    'risk_score' => 1,\n    'severity' => 'UNKNOWN',\n    'status' => 'SCREENED',\n    'summary' => 'your-summary',\n    'wallet_address' => 'your-wallet-address',\n    'blockchain' => 'your-blockchain',\n    'source_of_funds' => [[]],\n    'destination_of_funds' => [[]],\n    'counterparty_connections' => [[]],\n    'sanctions_hit' => true,\n    'dominant_risk_category' => 'your-dominant-risk-category',\n    'report_signature' => 'your-report-signature',\n]);\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.wallet_screening.screen_pdf(\n  provider: \"your-provider\",\n  screening_type: \"WALLET_SCREENING\",\n  risk_score: 1,\n  severity: \"UNKNOWN\",\n  status: \"SCREENED\",\n  summary: \"your-summary\",\n  wallet_address: \"your-wallet-address\",\n  blockchain: \"your-blockchain\",\n  source_of_funds: [{}],\n  destination_of_funds: [{}],\n  counterparty_connections: [{}],\n  sanctions_hit: true,\n  dominant_risk_category: \"your-dominant-risk-category\",\n  report_signature: \"your-report-signature\"\n)\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.WalletScreening.ScreenPdfAsync(new WalletScreeningResult\n{\n    Provider = \"your-provider\",\n    ScreeningType = \"WALLET_SCREENING\",\n    RiskScore = 1,\n    Severity = \"UNKNOWN\",\n    Status = \"SCREENED\",\n    Summary = \"your-summary\",\n    WalletAddress = \"your-wallet-address\",\n    Blockchain = \"your-blockchain\",\n    SourceOfFunds = new WalletScreeningResultSourceOfFunds[] { new() },\n    DestinationOfFunds = new WalletScreeningResultDestinationOfFunds[] { new() },\n    CounterpartyConnections = new WalletScreeningResultCounterpartyConnections[] { new() },\n    SanctionsHit = true,\n    DominantRiskCategory = \"your-dominant-risk-category\",\n    ReportSignature = \"your-report-signature\",\n});\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ],
        "responses": {
          "200": {
            "description": "렌더링된 PDF 문서로, 바이너리 `application/pdf` 형식으로 직접 반환됩니다. JSON 래퍼가 없습니다.",
            "headers": {
              "Content-Disposition": {
                "description": "다시 게시된 결과의 `wallet_address`(또는 `transaction_hash`)에서 파생된 `attachment; filename=wallet_screening_{address}.pdf`입니다.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=wallet_screening_0x28c6c06298d514db0899.pdf"
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "본문이 지갑 스크리닝 결과 형식과 일치하는 JSON 객체가 아니거나, `report_signature`가 누락되었거나 다시 게시된 필드와 일치하지 않습니다(다시 게시하기 전에 수정되거나 잘림).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "Not an object": {
                    "value": {
                      "non_field_errors": [
                        "Expected a JSON object matching a wallet-screening result."
                      ]
                    }
                  },
                  "Missing or invalid signature": {
                    "value": {
                      "report_signature": [
                        "This wallet-screening result is missing or fails its report signature - repost the exact JSON returned by the wallet-screening endpoint, unmodified."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`x-api-key`가 누락되었거나 유효하지 않습니다."
          }
        }
      }
    },
    "/v3/transactions/": {
      "get": {
        "summary": "거래 목록 조회",
        "description": "모니터링된 거래의 페이지 단위 목록이며 최신순(`txn_date` 내림차순)으로 정렬됩니다. `count`는 최대 100으로 제한되므로 실제 행 수를 확인하려면 `total_transactions`를 사용하십시오. 이 endpoint는 필터링이나 검색 파라미터를 지원하지 않습니다.",
        "operationId": "listTransactions",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "description": "페이지 크기입니다. 생략 시 기본값은 50입니다. 강제된 최댓값은 없으나 지연 시간을 줄이려면 페이지를 작게 유지하십시오."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "description": "반환할 첫 번째 레코드의 0부터 시작하는 오프셋입니다. 이전 페이지의 `next` URL을 따르는 것이 좋습니다."
          },
          {
            "name": "travel_rule_status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Travel Rule 전송이 정확히 이 상태(예: `ON_HOLD` 또는 `AWAITING_COUNTERPARTY`)인 거래만 반환합니다. `count`는 이 필터를 따르며, `total_transactions`는 애플리케이션의 모든 거래를 계속해서 계산합니다."
          },
          {
            "name": "assignee",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "쉼표로 구분되며, 거래가 값 중 하나와 일치하면 매칭됩니다. `unassigned`는 아직 아무에게도 배정되지 않은 상태, `rules`는 검토자 없이 규칙에 따라 자체적으로 결정된 상태를 의미하며, 멤버 이메일은 배정된 검토자와 일치합니다. `me`는 로그인한 Console 검토자를 가리키므로, API 키로 `me`를 전송하면 `400`이 반환됩니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.ListAutoPaging(ctx, didit.TransactionsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->transactions->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "거래 요약의 페이지 단위 목록(최신순)입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "일치하는 거래의 상한이 적용된 개수(최대 100개까지 정확하며 이후 상한 적용). 페이지를 매길 때 실제 개수를 확인하려면 `total_transactions`를 사용하십시오."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "다음 페이지의 절대 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "이전 페이지의 절대 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "total_transactions": {
                      "type": "integer",
                      "description": "애플리케이션의 (삭제되지 않은) 정확한 총 거래 수입니다. 페이지네이션된 응답에 존재합니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid",
                            "description": "고유 Didit 거래 식별자입니다. 세부 정보/메모/관련 호출에서 `{transaction_id}`로 사용하세요."
                          },
                          "transaction_number": {
                            "type": "integer",
                            "description": "Console에 표시되는 애플리케이션별 순차 거래 번호(예: `4123`)입니다."
                          },
                          "txn_id": {
                            "type": "string",
                            "description": "생성 호출 시 고객이 제공한 식별자(최대 128자)입니다. 애플리케이션별로 고유합니다."
                          },
                          "transaction_type": {
                            "type": "string",
                            "description": "저장된 최상위 카테고리: `finance`, `kyc`, `travelRule`, `userPlatformEvent`, `gamblingBet`, `gamblingLimitChange`, `gamblingBonusChange`, `auditTrailEvent`. 여러 단어로 된 값은 snake_case로 제출하더라도 camelCase로 반환됩니다."
                          },
                          "action_type": {
                            "type": "string",
                            "description": "카테고리 내 하위 유형입니다(예: `deposit`, `withdrawal`, `transfer`)."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "APPROVED",
                              "IN_REVIEW",
                              "DECLINED",
                              "AWAITING_USER"
                            ],
                            "description": "현재 모니터링 판정 결과입니다."
                          },
                          "direction": {
                            "type": "string",
                            "enum": [
                              "INBOUND",
                              "OUTBOUND"
                            ],
                            "description": "주체 기준의 방향입니다. 제출된 대소문자에 관계없이 대문자로 저장됩니다."
                          },
                          "amount": {
                            "type": "string",
                            "description": "끝자리의 0이 제거된 십진수 문자열 형태의 거래 금액(예: `\"1500\"`, `\"0.5\"`, `\"0.123456789012345678\"`)입니다. 소수점 이하 최대 18자리입니다."
                          },
                          "currency": {
                            "type": "string",
                            "description": "`amount`의 통화 코드입니다. 암호화폐 자산 심볼(예: `BTC`)뿐만 아니라 모든 ISO 4217 알파벳 코드(예: `EUR`, `USD`, `NGN`)를 사용할 수 있습니다. 현재 유통 중인 코드를 사용하는 것이 좋습니다. 지원되는 모든 코드에 환율이 제공되는 것은 아닙니다. 해당 코드의 환율을 사용할 수 없는 경우(예: ISO 회계 단위 `XSU` 또는 Didit에서 가격을 책정하지 않는 암호화폐 심볼), 자동 변환이 실패하며 요청에 사전 변환된 `amount_in_default_currency`가 제공되지 않는 한 `preferred_currency_amount`는 null로 반환됩니다."
                          },
                          "preferred_currency_amount": {
                            "type": "string",
                            "nullable": true,
                            "description": "제공되는 경우 애플리케이션의 선호 통화로 변환된 `amount`입니다."
                          },
                          "preferred_currency_code": {
                            "type": "string",
                            "nullable": true,
                            "description": "`preferred_currency_amount`에 사용되는 선호 통화 코드입니다. 애플리케이션의 기준 통화이며, 현재 통용되는 모든 ISO 4217 코드입니다. 환율을 사용할 수 없는 코드의 경우, 요청에서 사전 환산된 `amount_in_default_currency`를 제공하지 않는 한 `preferred_currency_amount`는 null로 유지됩니다."
                          },
                          "payment_details": {
                            "type": "string",
                            "nullable": true,
                            "description": "제출된 자유 형식 결제 참조 또는 메모입니다."
                          },
                          "score": {
                            "type": "integer",
                            "description": "위험 점수(일반적으로 0–100). 높을수록 위험합니다."
                          },
                          "severity": {
                            "type": "string",
                            "nullable": true,
                            "enum": [
                              "UNKNOWN",
                              "LOW",
                              "MEDIUM",
                              "HIGH",
                              "CRITICAL"
                            ],
                            "description": "규칙/제공업체에서 설정한 범주형 위험 심각도(`UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`). 설정되기 전까지는 `null`입니다."
                          },
                          "subject_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "`APPLICANT` 당사자의 성명입니다."
                          },
                          "subject_vendor_data": {
                            "type": "string",
                            "nullable": true,
                            "description": "신청자에 대한 귀하의 내부 사용자/기업 식별자입니다."
                          },
                          "subject_country": {
                            "type": "string",
                            "nullable": true,
                            "description": "제출된 `address.country`의 신청인 국가 코드입니다(일반적으로 ISO 3166-1 alpha-3)."
                          },
                          "counterparty_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "`COUNTERPARTY` 당사자의 성명(있는 경우)입니다."
                          },
                          "counterparty_vendor_data": {
                            "type": "string",
                            "nullable": true,
                            "description": "거래 상대방에 대한 귀하의 내부 식별자입니다."
                          },
                          "counterparty_country": {
                            "type": "string",
                            "nullable": true,
                            "description": "제출된 `address.country`의 거래 상대방 국가 코드입니다."
                          },
                          "tags": {
                            "type": "array",
                            "description": "거래에 연결된 태그(수동 또는 규칙에 의해)입니다.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "uuid": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "color": {
                                  "type": "string"
                                },
                                "description": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "source": {
                                  "type": "string",
                                  "enum": [
                                    "didit",
                                    "custom"
                                  ],
                                  "description": "태그가 Didit 프리셋인지 커스텀 태그인지 여부입니다."
                                }
                              }
                            }
                          },
                          "txn_date": {
                            "type": "string",
                            "format": "date-time",
                            "description": "거래가 발생한 시점입니다(생성 시점의 `transaction_at` 기준)."
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time",
                            "description": "Didit이 제출 내용을 기록한 시점입니다."
                          },
                          "decision_reason_code": {
                            "type": "string",
                            "nullable": true,
                            "description": "현재 `status`에 대한 기계 판독 가능한 사유(예: `WALLET_HIGH_RISK`)."
                          },
                          "decision_reason_label": {
                            "type": "string",
                            "nullable": true,
                            "description": "`decision_reason_code`에 대한 사람이 읽기 쉬운 라벨입니다."
                          },
                          "assigned_to_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "이 거래에 배정된 콘솔 검토자의 표시 이름입니다."
                          },
                          "travel_rule_status": {
                            "type": "string",
                            "nullable": true,
                            "description": "거래의 Travel Rule 전송 상태(예: `COMPLETED`)이며, 없는 경우 `null`입니다."
                          },
                          "travel_rule": {
                            "nullable": true,
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/TransactionTravelRule"
                              }
                            ],
                            "description": "거래의 Travel Rule 전송으로, `GET /v3/transactions/{transaction_id}/`의 `travel_rule`과 동일한 블록이거나 거래에 해당 사항이 없는 경우 `null`입니다."
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Single transaction": {
                    "value": {
                      "count": 1,
                      "next": null,
                      "previous": null,
                      "total_transactions": 1,
                      "results": [
                        {
                          "uuid": "abcdef12-3456-4890-abcd-ef1234567890",
                          "transaction_number": 4123,
                          "txn_id": "your-txn-2026-05-17-001",
                          "transaction_type": "finance",
                          "action_type": "withdrawal",
                          "status": "IN_REVIEW",
                          "direction": "OUTBOUND",
                          "amount": "1500",
                          "currency": "EUR",
                          "preferred_currency_amount": "1620.45",
                          "preferred_currency_code": "USD",
                          "payment_details": "Withdrawal to crypto wallet",
                          "txn_date": "2026-05-17T08:42:00Z",
                          "created_at": "2026-05-17T08:42:11Z",
                          "score": 78,
                          "severity": "HIGH",
                          "decision_reason_code": "WALLET_HIGH_RISK",
                          "decision_reason_label": "Destination wallet flagged as high risk",
                          "tags": [
                            {
                              "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                              "name": "Manual review",
                              "color": "#F59E0B",
                              "description": null,
                              "source": "custom"
                            }
                          ],
                          "subject_name": "Maria Garcia",
                          "subject_vendor_data": "user-12345",
                          "counterparty_name": null,
                          "counterparty_vendor_data": null,
                          "counterparty_country": null,
                          "subject_country": null,
                          "assigned_to_name": "Alex Reviewer",
                          "travel_rule_status": null,
                          "travel_rule": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 폐기되었거나, 해당 키에 이 애플리케이션의 거래를 조회할 수 있는 권한이 없습니다. 누락된 키는 `403`을 반환하며, 잘못되었거나 폐기되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "거래 생성",
        "description": "동기식 AML/위험 모니터링을 위해 거래를 제출합니다. 거래는 `APPROVED` 상태로 생성된 후 귀하의 규칙(및 해당하는 경우 암호화폐 스크리닝)이 인라인으로 실행되어 반환되는 `status`를 `IN_REVIEW` 또는 `DECLINED`로 변경할 수 있습니다. **`transaction_id`는 멱등성 키입니다**(최대 128자, 앱당 고유). 이를 재사용하면 400이 반환됩니다. 프로덕션 애플리케이션의 경우 성공 시 `transaction.created` webhook이 전송됩니다. 샌드박스 애플리케이션에는 요금이 청구되지 않으며 `transaction.created` 또는 `transaction.status.updated` webhook을 발송하지 않습니다. 샌드박스 Travel Rule 정보 교환은 `environment: sandbox`가 포함된 `travel_rule.status.updated` webhook을 발송합니다. Travel Rule 전송은 거래 상대방에게 연락하기 전에 저장 및 반환됩니다. `travel_rule.status`는 `AWAITING_COUNTERPARTY`(귀하의 임계값 미만인 경우 `NOT_APPLICABLE`, 신고된 자체 보관 지갑의 경우 `UNCONFIRMED_OWNERSHIP`, 상대 지갑이 귀하의 자체 검증 지갑인 경우 `COMPLETED`)로 반환되며 `travel_rule.protocol`은 null입니다. 그런 다음 Didit이 레일을 선택하고 교환을 전송하며, 거래 상대방에게 도달할 수 있는 레일이 없을 때의 `COUNTERPARTY_VASP_NOT_FOUND`를 포함하여 전송의 모든 후속 상태 변경이 `travel_rule.status.updated` webhook으로 전달됩니다. 레일이나 상태가 변경되면 귀하의 규칙이 다시 실행됩니다.",
        "operationId": "createTransaction",
        "tags": [
          "Transactions"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/transactions/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"transaction_id\": \"your-txn-2026-05-17-001\",\n    \"transaction_category\": \"finance\",\n    \"transaction_details\": {\n      \"direction\": \"outbound\",\n      \"amount\": 1500,\n      \"currency\": \"EUR\",\n      \"action_type\": \"withdrawal\"\n    },\n    \"subject\": {\n      \"entity_type\": \"individual\",\n      \"vendor_data\": \"user-12345\",\n      \"full_name\": \"Maria Garcia\"\n    }\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.create(\n    transaction_id=\"your-txn-2026-05-17-001\",\n    transaction_category=\"finance\",\n    transaction_details={\n        \"direction\": \"outbound\",\n        \"amount\": 1500.0,\n        \"currency\": \"EUR\",\n        \"action_type\": \"withdrawal\",\n    },\n    subject={\n        \"entity_type\": \"individual\",\n        \"vendor_data\": \"user-12345\",\n        \"full_name\": \"Maria Garcia\",\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.create({\n  transaction_id: \"your-txn-2026-05-17-001\",\n  transaction_category: \"finance\",\n  transaction_details: {\n    direction: \"outbound\",\n    amount: 1500.0,\n    currency: \"EUR\",\n    action_type: \"withdrawal\",\n  },\n  subject: {\n    entity_type: \"individual\",\n    vendor_data: \"user-12345\",\n    full_name: \"Maria Garcia\",\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Create(ctx, didit.TransactionsCreateParams{\n\tTransactionID:       \"your-txn-2026-05-17-001\",\n\tTransactionCategory: \"finance\",\n\tTransactionDetails: didit.TransactionsCreateParamsTransactionDetails{\n\t\tDirection:  \"outbound\",\n\t\tAmount:     1500.0,\n\t\tCurrency:   \"EUR\",\n\t\tActionType: didit.String(\"withdrawal\"),\n\t},\n\tSubject: didit.TransactionsCreateParamsSubject{\n\t\tEntityType: didit.String(\"individual\"),\n\t\tVendorData: \"user-12345\",\n\t\tFullName:   \"Maria Garcia\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TransactionsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().create(TransactionsCreateParams.builder()\n        .transactionId(\"your-txn-2026-05-17-001\")\n        .transactionCategory(TransactionsCreateParams.TransactionCategory.of(\"finance\"))\n        .transactionDetails(TransactionsCreateParams.TransactionDetails.builder()\n                .direction(TransactionsCreateParams.TransactionDetails.Direction.of(\"outbound\"))\n                .amount(1500.0)\n                .currency(\"EUR\")\n                .actionType(\"withdrawal\")\n                .build())\n        .subject(TransactionsCreateParams.Subject.builder()\n                .entityType(\"individual\")\n                .vendorData(\"user-12345\")\n                .fullName(\"Maria Garcia\")\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->create([\n    'transaction_id' => 'your-txn-2026-05-17-001',\n    'transaction_category' => 'finance',\n    'transaction_details' => [\n        'direction' => 'outbound',\n        'amount' => 1500.0,\n        'currency' => 'EUR',\n        'action_type' => 'withdrawal',\n    ],\n    'subject' => [\n        'entity_type' => 'individual',\n        'vendor_data' => 'user-12345',\n        'full_name' => 'Maria Garcia',\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.create(\n  transaction_id: \"your-txn-2026-05-17-001\",\n  transaction_category: \"finance\",\n  transaction_details: {\n    direction: \"outbound\",\n    amount: 1500.0,\n    currency: \"EUR\",\n    action_type: \"withdrawal\",\n  },\n  subject: {\n    entity_type: \"individual\",\n    vendor_data: \"user-12345\",\n    full_name: \"Maria Garcia\",\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.CreateAsync(new TransactionsCreateParams\n{\n    TransactionId = \"your-txn-2026-05-17-001\",\n    TransactionCategory = \"finance\",\n    TransactionDetails = new()\n    {\n        Direction = \"outbound\",\n        Amount = 1500.0,\n        Currency = \"EUR\",\n        ActionType = \"withdrawal\",\n    },\n    Subject = new()\n    {\n        EntityType = \"individual\",\n        VendorData = \"user-12345\",\n        FullName = \"Maria Garcia\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "transaction_id": {
                    "type": "string",
                    "description": "귀하가 지정한 해당 거래의 고유 식별자입니다(최대 128자).",
                    "example": "your-txn-2026-05-17-001"
                  },
                  "transaction_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "거래가 발생한 시점입니다. 생략 시 현재 시간으로 기본 설정됩니다."
                  },
                  "time_zone": {
                    "type": "string",
                    "description": "IANA 표준 시간대 식별자(예: `Europe/Madrid`)입니다."
                  },
                  "transaction_category": {
                    "type": "string",
                    "description": "거래의 카테고리. CamelCase 별칭(`travelRule`, `userPlatformEvent`, `gamblingBet` 등)도 허용되며, 여러 단어로 이루어진 카테고리의 경우 저장/반영되는 값은 camelCase입니다.",
                    "example": "finance",
                    "enum": [
                      "finance",
                      "kyc",
                      "travel_rule",
                      "user_event",
                      "audit_trail_event",
                      "gambling_bet",
                      "gambling_limit_change",
                      "gambling_bonus_change",
                      "travelRule"
                    ]
                  },
                  "transaction_details": {
                    "type": "object",
                    "description": "거래의 핵심 금융 세부 정보입니다.",
                    "required": [
                      "direction",
                      "amount",
                      "currency"
                    ],
                    "properties": {
                      "direction": {
                        "type": "string",
                        "description": "주체 기준의 거래 방향입니다. 대소문자를 구분하지 않으며, `in`/`out`을 별칭으로 사용할 수 있습니다. 대문자(`INBOUND`/`OUTBOUND`)로 에코되어 반환됩니다.",
                        "example": "outbound",
                        "enum": [
                          "inbound",
                          "outbound",
                          "in",
                          "out"
                        ]
                      },
                      "amount": {
                        "type": "number",
                        "description": "거래 금액(소수점 이하 최대 18자리)입니다. 정확한 정밀도가 중요한 경우 십진수 문자열(예: `\"0.123456789012345678\"`)로 전송하십시오. JSON 숫자는 먼저 바이너리 부동소수점으로 파싱되므로 약 15자리를 초과하는 유효 숫자는 금액이 저장되기 전에 반올림됩니다. 0 이상이어야 합니다. 거래 방향이 부호를 결정하므로 음수 금액을 전달하면 `400`이 반환됩니다.",
                        "example": 1500
                      },
                      "currency": {
                        "type": "string",
                        "description": "통화 코드입니다. 암호화폐 자산 심볼(예: `BTC`)뿐만 아니라 모든 ISO 4217 알파벳 코드(예: `EUR`, `USD`, `NGN`)를 사용할 수 있습니다. 현재 유통 중인 코드를 사용하는 것이 좋습니다. 지원되는 모든 코드에 환율이 제공되는 것은 아닙니다. 해당 코드의 환율을 사용할 수 없는 경우(예: ISO 회계 단위 `XSU` 또는 Didit에서 가격을 책정하지 않는 암호화폐 심볼), 자동 변환이 실패하며 요청에 사전 변환된 `amount_in_default_currency`가 제공되지 않는 한 `preferred_currency_amount`는 null로 반환됩니다.",
                        "example": "EUR"
                      },
                      "currency_kind": {
                        "type": "string",
                        "description": "통화가 `fiat`인지 `crypto`인지 여부입니다."
                      },
                      "amount_in_default_currency": {
                        "type": "number",
                        "nullable": true,
                        "description": "기본 통화로 사전 환산된 금액입니다. 생략하면 자동 환율 변환이 시도됩니다. 0 이상이어야 합니다."
                      },
                      "default_currency": {
                        "type": "string",
                        "description": "환산 금액의 기본 통화 코드입니다. 현재 유통되는 ISO 4217 코드 중 하나입니다."
                      },
                      "payment_details": {
                        "type": "string",
                        "nullable": true,
                        "description": "자유 형식 결제 참조 또는 메모입니다."
                      },
                      "payment_reference_id": {
                        "type": "string",
                        "nullable": true,
                        "description": "외부 결제 시스템 참조입니다. 크립토 AML 거래 해시 스크리닝의 경우 블록체인 거래 해시를 전송하고 관련 주소와 함께 `subject.payment_method.account_id`도 제공해야 합니다."
                      },
                      "action_type": {
                        "type": "string",
                        "nullable": true,
                        "description": "거래의 하위 유형입니다(예: `deposit`, `withdrawal`, `transfer`)."
                      },
                      "crypto_params": {
                        "type": "object",
                        "description": "통화(자산 심볼)와 별도로 선택하는 암호화폐 네트워크입니다. 커스텀 token 심볼을 기록한다고 해서 해당 컨트랙트의 거래 해시 지원이 보장되지는 않습니다.",
                        "properties": {
                          "crypto_chain": {
                            "type": "string",
                            "description": "스크리닝에 사용된 실제 네트워크입니다. 관리형 스크리닝은 BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), ARB (Arbitrum One), AVAX (Avalanche C-Chain), ADA (Cardano), XLM (Stellar), HBAR (Hedera)를 지원합니다. MATIC의 경우 POLYGON 또는 POL, BNB의 경우 BSC, TRX의 경우 TRON과 같은 일반적인 네트워크 이름도 허용됩니다. 멀티 네트워크 토큰의 경우 항상 이를 지정해야 합니다. 0x 거래 해시와 함께 전송된 USDT, USDC 또는 ETH에 이 값이 누락된 경우, Didit은 Ethereum, BNB Chain, Polygon, Base, Arbitrum, Optimism에서 해당 해시를 조회하여 발견된 네트워크에서 스크리닝합니다. 어떤 네트워크에도 존재하지 않는 경우 해당 거래는 스크리닝되지 않으며, custom_values.aml_screening_status는 FAILED가 되고 custom_values.aml_screening_error에 이유가 표시됩니다. 지갑으로 스크리닝할 때(거래 해시 없음) USDT 또는 USDC에 이 값이 누락된 경우, Tron 주소는 Tron에서, Solana 주소는 Solana에서 스크리닝되며, 0x 주소는 거래를 전송했거나 해당 토큰을 보유하고 있는 6개 네트워크 중 첫 번째 네트워크에서 스크리닝되거나, 어느 네트워크에서도 활동이 없는 경우 Ethereum에서 스크리닝됩니다. 연동된 제공업체의 지원 범위는 상이하며, LIGHTNING은 지원되는 연동 제공업체가 필요합니다.",
                            "example": "BASE"
                          }
                        }
                      }
                    }
                  },
                  "subject": {
                    "type": "object",
                    "description": "거래의 주체(신청자)입니다.",
                    "required": [
                      "vendor_data",
                      "full_name"
                    ],
                    "properties": {
                      "entity_type": {
                        "type": "string",
                        "description": "엔티티 유형: `individual` 또는 `company`."
                      },
                      "vendor_data": {
                        "type": "string",
                        "description": "귀하의 내부 사용자/기업 식별자입니다.",
                        "example": "user-12345"
                      },
                      "full_name": {
                        "type": "string",
                        "description": "대상자의 성명입니다.",
                        "example": "Maria Garcia"
                      },
                      "first_name": {
                        "type": "string",
                        "description": "대상자의 이름입니다."
                      },
                      "last_name": {
                        "type": "string",
                        "description": "대상자의 성입니다."
                      },
                      "date_of_birth": {
                        "type": "string",
                        "format": "date",
                        "description": "생년월일(YYYY-MM-DD)입니다."
                      },
                      "address": {
                        "type": "object",
                        "description": "주소 객체입니다.",
                        "properties": {
                          "country": {
                            "type": "string",
                            "description": "국가 코드입니다(ISO 3166-1 alpha-3 권장). 당사자의 `country_code`로 복사됩니다."
                          },
                          "town": {
                            "type": "string"
                          },
                          "state": {
                            "type": "string"
                          },
                          "street": {
                            "type": "string"
                          },
                          "post_code": {
                            "type": "string"
                          }
                        }
                      },
                      "institution_details": {
                        "type": "object",
                        "description": "기관 세부 정보(기관 대상 전용).",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "code": {
                            "type": "string"
                          },
                          "address": {
                            "type": "object"
                          }
                        }
                      },
                      "device_context": {
                        "type": "object",
                        "description": "거래 시점에 캡처된 기기 컨텍스트입니다. browser_family 및 platform은 명시적인 최상위 키로 전송되어야 하며 user_agent에서 파생되지 않습니다. 요청 시 camelCase 별칭인 device도 허용됩니다.",
                        "properties": {
                          "fingerprint": {
                            "type": "string",
                            "description": "고유 기기 핑거프린트입니다."
                          },
                          "persistent_device_id": {
                            "type": "string",
                            "description": "세션 간 유지되는 고유 기기 식별자(v2 핑거프린트 스키마)입니다."
                          },
                          "user_agent": {
                            "type": "string",
                            "description": "브라우저 또는 앱 사용자 에이전트 문자열입니다. CamelCase 별칭: userAgent."
                          },
                          "browser_family": {
                            "type": "string",
                            "description": "브라우저 계열(예: Chrome, Firefox, Safari)입니다. 명시적으로 전송해야 하며, user_agent에서 파생되지 않습니다. CamelCase 별칭: browserFamily."
                          },
                          "browser_version": {
                            "type": "string",
                            "description": "브라우저 버전 문자열입니다. 명시적으로 전송해야 합니다. CamelCase 별칭: browserVersion."
                          },
                          "platform": {
                            "type": "string",
                            "description": "플랫폼 식별자(web, ios, android, macos, windows, linux)입니다. user_agent에서 파생되지 않으므로 반드시 명시적으로 전송해야 합니다."
                          },
                          "os_family": {
                            "type": "string",
                            "description": "운영체제 제품군(예: iOS, Android, Windows). CamelCase 별칭: osFamily."
                          },
                          "os_version": {
                            "type": "string",
                            "description": "운영체제 버전 문자열입니다. CamelCase 별칭: osVersion."
                          },
                          "accept_language": {
                            "type": "string",
                            "description": "Accept-Language 헤더 값입니다. 카멜 표기법 별칭: acceptLang."
                          },
                          "session_id": {
                            "type": "string",
                            "description": "사용자의 현재 세션의 세션 식별자입니다. 메타데이터에 저장됩니다. CamelCase 별칭: sessionId."
                          },
                          "session_age_ms": {
                            "type": "number",
                            "description": "거래 시점의 사용자 세션 경과 시간(밀리초)입니다. CamelCase 별칭: sessionAgeMs."
                          },
                          "network_context": {
                            "type": "object",
                            "description": "IP 주소 및 지리적 위치가 포함된 네트워크 컨텍스트입니다. 최상위 ipInfo 블록도 이 객체에 병합됩니다.",
                            "properties": {
                              "ip_address": {
                                "type": "string",
                                "description": "클라이언트 IP 주소입니다. CamelCase 별칭: ip."
                              },
                              "ip_country_code": {
                                "type": "string",
                                "description": "IP의 지리적 위치로 확인된 국가(ISO 3166-1 alpha-3)입니다. CamelCase 별칭: countryCode3."
                              },
                              "latitude": {
                                "type": "number",
                                "description": "IP의 지리적 위도입니다. CamelCase 별칭: lat."
                              },
                              "longitude": {
                                "type": "number",
                                "description": "IP의 지리적 경도입니다. CamelCase 별칭: lon."
                              }
                            }
                          }
                        }
                      },
                      "payment_method": {
                        "type": "object",
                        "description": "주체가 사용하는 결제 수단입니다.",
                        "properties": {
                          "method_type": {
                            "type": "string",
                            "description": "결제 수단 유형: `bank_card`, `bank_account`, `crypto_wallet`, `ewallet`, `unhosted_wallet`, `other`."
                          },
                          "account_id": {
                            "type": "string",
                            "description": "계정 식별자(예: IBAN, 지갑 주소). 가상자산 스크리닝의 경우 이 참여자의 지갑 주소가 포함되어야 합니다. 인바운드 트랜잭션 해시 스크리닝에는 대상자의 서비스/고객 입금 주소가 필요합니다. 아웃바운드 스크리닝은 거래 상대방의 대상 지갑을 사용합니다. 비트코인 또는 Lightning에서의 가상자산 전송 시 Lightning 결제 요청(BOLT11 인보이스, BOLT12 오퍼, LNURL) 또는 Lightning Address일 수 있습니다. Didit은 지정된 수취인을 계정으로 저장하고(지정되지 않은 경우 \"\") 요청 내용을 Travel Rule 전송의 `chain_details.lightning`에 저장합니다. 저장 시 최대 255자입니다. 비트코인 또는 Lightning에서의 가상자산 전송 시 Lightning 결제 요청(BOLT11 인보이스, BOLT12 오퍼, LNURL) 또는 Lightning Address일 수 있습니다. Didit은 지정된 수취인을 계정으로 저장하고(지정되지 않은 경우 \"\") 요청 내용을 Travel Rule 전송의 `chain_details.lightning`에 저장합니다. 저장 시 최대 255자입니다."
                          },
                          "memo": {
                            "type": "string",
                            "maxLength": 256,
                            "description": "메모 네트워크(XRP, XLM, EOS, ATOM, HBAR)에서 지갑의 일부인 대상 태그 또는 메모입니다. 하나의 공유 거래소 주소에서 각 메모는 고유한 결제 수단입니다. XRP: 대상 태그, 0부터 4294967295까지의 정수(JSON 숫자 허용). XLM: 최대 28바이트의 텍스트 메모, 64비트 id 또는 16진수 32바이트 해시. EOS: 최대 256바이트. ATOM: 최대 256자. HBAR: 최대 100바이트. Bitcoin, EVM, Solana, Tron, Litecoin, Bitcoin Cash, Dogecoin 및 Lightning 지갑은 메모를 지원하지 않으며, 입력 시 `400`이 반환됩니다. 별칭: `destinationTag` 또는 `destination_tag`."
                          },
                          "issuing_country": {
                            "type": "string",
                            "description": "발급처의 ISO 3166-1 alpha-3 국가 코드입니다."
                          }
                        }
                      }
                    }
                  },
                  "counterparty": {
                    "type": "object",
                    "description": "거래의 거래 상대방(선택 사항)입니다.",
                    "properties": {
                      "entity_type": {
                        "type": "string",
                        "description": "엔티티 유형: `individual` 또는 `company`."
                      },
                      "vendor_data": {
                        "type": "string",
                        "description": "거래 상대방에 대한 귀하의 내부 식별자입니다."
                      },
                      "full_name": {
                        "type": "string",
                        "description": "거래 상대방의 성명입니다."
                      },
                      "first_name": {
                        "type": "string"
                      },
                      "last_name": {
                        "type": "string"
                      },
                      "date_of_birth": {
                        "type": "string",
                        "format": "date"
                      },
                      "address": {
                        "type": "object",
                        "description": "`country`(ISO 3166-1 alpha-3)를 포함하는 주소 객체입니다."
                      },
                      "institution_details": {
                        "type": "object"
                      },
                      "device_context": {
                        "type": "object",
                        "description": "거래 상대방의 기기 컨텍스트입니다. browser_family 및 platform은 명시적인 최상위 키로 전송해야 하며, user_agent에서 파생되지 않습니다.",
                        "properties": {
                          "fingerprint": {
                            "type": "string",
                            "description": "고유 기기 핑거프린트입니다."
                          },
                          "persistent_device_id": {
                            "type": "string",
                            "description": "세션 간 유지되는 고유 기기 식별자(v2 핑거프린트 스키마)입니다."
                          },
                          "user_agent": {
                            "type": "string",
                            "description": "브라우저 또는 앱 사용자 에이전트 문자열입니다. CamelCase 별칭: userAgent."
                          },
                          "browser_family": {
                            "type": "string",
                            "description": "브라우저 계열(예: Chrome, Firefox, Safari)입니다. 명시적으로 전송해야 하며, user_agent에서 파생되지 않습니다. CamelCase 별칭: browserFamily."
                          },
                          "browser_version": {
                            "type": "string",
                            "description": "브라우저 버전 문자열입니다. 명시적으로 전송해야 합니다. CamelCase 별칭: browserVersion."
                          },
                          "platform": {
                            "type": "string",
                            "description": "플랫폼 식별자(web, ios, android, macos, windows, linux)입니다. user_agent에서 파생되지 않으므로 반드시 명시적으로 전송해야 합니다."
                          },
                          "os_family": {
                            "type": "string",
                            "description": "운영체제 제품군(예: iOS, Android, Windows). CamelCase 별칭: osFamily."
                          },
                          "os_version": {
                            "type": "string",
                            "description": "운영체제 버전 문자열입니다. CamelCase 별칭: osVersion."
                          },
                          "accept_language": {
                            "type": "string",
                            "description": "Accept-Language 헤더 값입니다. 카멜 표기법 별칭: acceptLang."
                          },
                          "session_id": {
                            "type": "string",
                            "description": "거래 상대방 세션의 세션 식별자입니다. 메타데이터에 저장됩니다. CamelCase 별칭: sessionId."
                          },
                          "session_age_ms": {
                            "type": "number",
                            "description": "거래 시점의 사용자 세션 경과 시간(밀리초)입니다. CamelCase 별칭: sessionAgeMs."
                          },
                          "network_context": {
                            "type": "object",
                            "description": "IP 주소 및 지리적 위치가 포함된 네트워크 컨텍스트입니다. 최상위 ipInfo 블록도 이 객체에 병합됩니다.",
                            "properties": {
                              "ip_address": {
                                "type": "string",
                                "description": "클라이언트 IP 주소입니다. CamelCase 별칭: ip."
                              },
                              "ip_country_code": {
                                "type": "string",
                                "description": "IP의 지리적 위치로 확인된 국가(ISO 3166-1 alpha-3)입니다. CamelCase 별칭: countryCode3."
                              },
                              "latitude": {
                                "type": "number",
                                "description": "IP의 지리적 위도입니다. CamelCase 별칭: lat."
                              },
                              "longitude": {
                                "type": "number",
                                "description": "IP의 지리적 경도입니다. CamelCase 별칭: lon."
                              }
                            }
                          }
                        }
                      },
                      "payment_method": {
                        "type": "object",
                        "description": "거래 상대방이 사용하는 결제 수단입니다. travelRule 거래에서 `method_type: \"unhosted_wallet\"`은 거래 상대방 지갑을 자체 보관 지갑으로 신고합니다. 이체는 거래 상대방 VASP 라우팅을 건너뛰고 `UNCONFIRMED_OWNERSHIP` 상태로 직접 생성되며, (`auto_wallet_verification`이 활성화된 경우) 지갑 소유권 위젯 세션이 자동으로 생성되어 거래의 `action_required` 블록에 반환됩니다.",
                        "properties": {
                          "method_type": {
                            "type": "string",
                            "description": "결제 수단 유형: `bank_card`, `bank_account`, `crypto_wallet`, `ewallet`, `unhosted_wallet`, `other`. Travel Rule에 자체 보관 지갑을 선언하려면 `unhosted_wallet`을 사용하십시오."
                          },
                          "account_id": {
                            "type": "string",
                            "description": "계정 식별자(예: IBAN 또는 지갑 주소). 비트코인 또는 Lightning에서의 가상자산 전송 시 Lightning 결제 요청(BOLT11 인보이스, BOLT12 오퍼, LNURL) 또는 Lightning Address일 수 있습니다. Didit은 지정된 수취인을 계정으로 저장하고(지정되지 않은 경우 \"\") 요청 내용을 Travel Rule 전송의 `chain_details.lightning`에 저장합니다. 저장 시 최대 255자입니다. 비트코인 또는 Lightning에서의 가상자산 전송 시 Lightning 결제 요청(BOLT11 인보이스, BOLT12 오퍼, LNURL) 또는 Lightning Address일 수 있습니다. Didit은 지정된 수취인을 계정으로 저장하고(지정되지 않은 경우 \"\") 요청 내용을 Travel Rule 전송의 `chain_details.lightning`에 저장합니다. 저장 시 최대 255자입니다."
                          },
                          "memo": {
                            "type": "string",
                            "maxLength": 256,
                            "description": "메모 네트워크(XRP, XLM, EOS, ATOM, HBAR)에서 지갑의 일부인 대상 태그 또는 메모입니다. 하나의 공유 거래소 주소에서 각 메모는 고유한 결제 수단입니다. XRP: 대상 태그, 0부터 4294967295까지의 정수(JSON 숫자 허용). XLM: 최대 28바이트의 텍스트 메모, 64비트 id 또는 16진수 32바이트 해시. EOS: 최대 256바이트. ATOM: 최대 256자. HBAR: 최대 100바이트. Bitcoin, EVM, Solana, Tron, Litecoin, Bitcoin Cash, Dogecoin 및 Lightning 지갑은 메모를 지원하지 않으며, 입력 시 `400`이 반환됩니다. 별칭: `destinationTag` 또는 `destination_tag`."
                          },
                          "issuing_country": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  },
                  "custom_properties": {
                    "type": "object",
                    "description": "거래에 연결된 임의의 키-값 쌍입니다. 각 키는 `custom_values.<key>` 필드 경로를 통해 규칙 조건에서 참조할 수 있습니다.",
                    "additionalProperties": true,
                    "example": {
                      "merchant_id": "test",
                      "bank_name": "test_2"
                    }
                  },
                  "travel_rule_details": {
                    "type": "object",
                    "description": "Travel Rule 데이터입니다. Travel Rule이 활성화되어 있고 transaction_category가 travel_rule인 경우 Didit이 직접 정보 교환을 실행합니다. status, protocol, required, obligations_count는 무시되며 originator_data, beneficiary_data, metadata가 사용됩니다. 그렇지 않은 경우 Didit은 이 값들을 수동적 Travel Rule 기록으로 저장합니다. Travel Rule이 켜져 있는 동안 임계값 이상의 아웃바운드 이체는 해당 규제 체계(EU TFR 또는 FATF 권고안 16)에서 요구하는 내용을 포함해야 하며, 전송하는 측에서 확인됩니다. 누락된 필드가 있는 경우 `travel_rule_details.originator_data` 또는 `travel_rule_details.beneficiary_data` 아래에 400 응답이 반환됩니다(예: \"EU TFR requires the originator name.\").",
                    "required": [
                      "status"
                    ],
                    "properties": {
                      "status": {
                        "type": "string",
                        "description": "travel_rule_details를 보낼 때마다 필수입니다. Travel Rule 전송 상태 중 하나(예: AWAITING_COUNTERPARTY, COMPLETED, NOT_APPLICABLE)여야 합니다. 소문자 및 camelCase 표기와 레거시 값인 UNKNOWN, COMPLIANT, PENDING_ACTION, PENDING_COUNTERPARTY, FAILED, EXEMPT도 허용되며 매핑됩니다. 그 외의 값은 400을 반환합니다."
                      },
                      "protocol": {
                        "type": "string"
                      },
                      "required": {
                        "type": "boolean"
                      },
                      "obligations_count": {
                        "type": "integer"
                      },
                      "originator_data": {
                        "type": "object",
                        "description": "송금인 당사자 정보로, 평면 필드 또는 하나의 IVMS 101 개인 객체입니다. 승인된 KYC 인증을 보유한 사용자의 경우, Didit은 인증이 보유한 필드를 검증된 값으로 대체합니다(`metadata.originator_provenance` 참조). 객체여야 하며, 그 외의 모든 것은 `400`을 반환합니다. 메모 네트워크에서는 `memo` 키가 송금인 지갑의 메모 또는 태그를 지정합니다."
                      },
                      "beneficiary_data": {
                        "type": "object",
                        "description": "단일 계층 필드 또는 단일 IVMS 101 개인 형태의 수취인 당사자 정보입니다. 반드시 객체여야 하며, 그렇지 않으면 `400` 오류가 발생합니다. Didit은 전송 경로를 지정하기 위해 `wallet_address`(비어 있는 경우 `counterparty.payment_method.account_id`의 값으로 채워짐), `chain`(`transaction_details.crypto_params.crypto_chain` 또는 지원되는 네트워크를 나타내는 `currency` 값으로 채워짐), `name`(`counterparty.full_name`으로 대체됨), `travel_address`, `counterparty_vasp_name`, `counterparty_vasp_lei`, `counterparty_vasp_email`을 읽습니다. 메모 네트워크에서는 `memo`가 수취인 지갑의 메모 또는 태그를 지정하며, `wallet_address` 및 `memo`가 거래 상대방의 결제 수단보다 우선합니다."
                      },
                      "metadata": {
                        "type": "object"
                      },
                      "utxo": {
                        "allOf": [
                          {
                            "$ref": "#/components/schemas/TravelRuleUtxo"
                          }
                        ],
                        "description": "선택 사항이며 UTXO 체인 전용입니다(BTC, LTC, BCH, DOGE). 사용자가 직접 선언하지 않은 경우 Didit이 송금인 지갑과 수취인 출력을 유추하는 트랜잭션의 입력과 출력입니다."
                      },
                      "originator": {
                        "type": "object",
                        "description": "IVMS 101 송금인 블록: `originatorPersons`(`naturalPerson` 또는 `legalPerson` 하나. 법인의 경우 거래 당사자가 기업이 됨) 및 `accountNumber`(지갑 주소). 해당 객체가 비어 있을 때 `originator_data`에 사용됩니다. 형식이 잘못된 블록은 해당 경로(예: `originator.originatorPersons`)를 키로 하여 400 응답을 반환합니다."
                      },
                      "beneficiary": {
                        "type": "object",
                        "description": "IVMS 101 수취인 블록: `beneficiaryPersons`(`naturalPerson` 또는 `legalPerson` 하나. 법인의 경우 거래 당사자가 기업이 됨) 및 `accountNumber`(지갑 주소). 해당 객체가 비어 있을 때 `beneficiary_data`에 사용됩니다. 형식이 잘못된 블록은 해당 경로(예: `beneficiary.beneficiaryPersons`)를 키로 하여 400 응답을 반환합니다."
                      },
                      "ivms101": {
                        "type": "object",
                        "description": "하나의 IVMS 101 객체로 래핑된 `originator` 및 `beneficiary` 블록입니다(`IVMS101`도 허용됨). 최상위 블록이 래퍼의 블록보다 우선합니다."
                      }
                    }
                  },
                  "network_snapshot": {
                    "type": "object",
                    "description": "미리 계산된 네트워크 그래프 스냅샷입니다.",
                    "properties": {
                      "nodes": {
                        "type": "array",
                        "items": {
                          "type": "object"
                        }
                      },
                      "edges": {
                        "type": "array",
                        "items": {
                          "type": "object"
                        }
                      },
                      "metrics": {
                        "type": "object"
                      }
                    }
                  },
                  "include_crypto_screening": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "암호화폐 블록체인 분석 스크리닝에 대한 거래별 재정의입니다. `true`인 경우 애플리케이션 기본값과 관계없이 암호화폐 스크리닝이 수행됩니다. `false`인 경우 애플리케이션 설정에서 활성화되어 있더라도 암호화폐 스크리닝을 건너뜁니다. 생략되거나 `null`인 경우 Console에 구성된 애플리케이션 수준 기본값이 사용됩니다. 암호화폐 스크리닝에는 `transaction_details.direction`, `currency_kind: \"crypto\"`, 체인/통화, 그리고 방향에 따라 선택된 지갑 주소가 필요합니다. 인바운드 전송 전 스크리닝은 `counterparty.payment_method.account_id`를 사용하고, 인바운드 트랜잭션 해시 스크리닝은 `subject.payment_method.account_id`를 사용하며, 아웃바운드 스크리닝은 `counterparty.payment_method.account_id`를 사용합니다. `transaction_details.payment_reference_id`에 블록체인 트랜잭션 해시가 포함되어 있으면 Didit은 트랜잭션 스크리닝을 수행하고 가능한 경우 트랜잭션 요약 강화 정보를 반환합니다."
                  }
                },
                "required": [
                  "transaction_id",
                  "transaction_category",
                  "transaction_details",
                  "subject"
                ]
              },
              "examples": {
                "Minimal fiat withdrawal": {
                  "summary": "법정화폐 외부 송금에 허용되는 최소 payload",
                  "value": {
                    "transaction_id": "your-txn-2026-05-17-001",
                    "transaction_category": "finance",
                    "transaction_details": {
                      "direction": "outbound",
                      "amount": 1500,
                      "currency": "EUR",
                      "action_type": "withdrawal"
                    },
                    "subject": {
                      "entity_type": "individual",
                      "vendor_data": "user-12345",
                      "full_name": "Maria Garcia"
                    }
                  }
                },
                "Crypto outbound with screening": {
                  "summary": "자체 보관 지갑으로의 아웃바운드 가상자산 출금, 옵트인 스크리닝",
                  "value": {
                    "transaction_id": "your-txn-2026-05-17-002",
                    "transaction_category": "finance",
                    "include_crypto_screening": true,
                    "transaction_details": {
                      "direction": "outbound",
                      "amount": 0.5,
                      "currency": "BTC",
                      "currency_kind": "crypto",
                      "amount_in_default_currency": 32500,
                      "default_currency": "USD",
                      "action_type": "withdrawal"
                    },
                    "subject": {
                      "entity_type": "individual",
                      "vendor_data": "user-12345",
                      "full_name": "Maria Garcia",
                      "payment_method": {
                        "method_type": "crypto_wallet",
                        "account_id": "bc1qexampleexchangewalletaddressxyz",
                        "issuing_country": "ESP"
                      }
                    },
                    "counterparty": {
                      "entity_type": "individual",
                      "payment_method": {
                        "method_type": "unhosted_wallet",
                        "account_id": "bc1qexampleexternalwalletaddressabc"
                      }
                    }
                  }
                },
                "Travel Rule transfer": {
                  "summary": "Travel Rule 송금인/수취인 데이터가 포함된 아웃바운드 가상자산 전송",
                  "value": {
                    "transaction_id": "your-txn-2026-05-17-003",
                    "transaction_category": "travel_rule",
                    "transaction_details": {
                      "direction": "outbound",
                      "amount": 25000,
                      "currency": "USDT",
                      "currency_kind": "crypto",
                      "action_type": "transfer"
                    },
                    "subject": {
                      "entity_type": "individual",
                      "vendor_data": "user-12345",
                      "full_name": "Maria Garcia",
                      "date_of_birth": "1992-03-14",
                      "address": {
                        "country": "ESP",
                        "town": "Madrid",
                        "street": "Calle Mayor 1",
                        "post_code": "28013"
                      }
                    },
                    "counterparty": {
                      "entity_type": "individual",
                      "full_name": "John Beneficiary",
                      "institution_details": {
                        "name": "Beneficiary VASP, Inc.",
                        "code": "BVASP-US"
                      }
                    },
                    "travel_rule_details": {
                      "status": "AWAITING_COUNTERPARTY",
                      "protocol": "IVMS101",
                      "required": true,
                      "originator_data": {
                        "name": "Maria Garcia"
                      },
                      "beneficiary_data": {
                        "name": "John Beneficiary"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "거래가 제출되고 모니터링되었습니다. 본문은 이미 적용된 모든 규칙 결과를 반영한 전체 거래 세부 정보(`GET /v3/transactions/{transaction_id}/`와 동일한 형태)입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionDetail"
                },
                "examples": {
                  "Approved with no rule hits": {
                    "value": {
                      "uuid": "abcdef12-3456-4890-abcd-ef1234567890",
                      "environment": "live",
                      "transaction_number": 4123,
                      "txn_id": "your-txn-2026-05-17-001",
                      "txn_date": "2026-05-17T08:42:00Z",
                      "zone_id": "Europe/Madrid",
                      "transaction_type": "finance",
                      "action_type": "withdrawal",
                      "direction": "OUTBOUND",
                      "status": "APPROVED",
                      "source": "LIVE",
                      "amount": "1500",
                      "currency": "EUR",
                      "currency_type": "fiat",
                      "amount_in_default_currency": "1620.45",
                      "default_currency_code": "USD",
                      "preferred_currency_amount": "1620.45",
                      "preferred_currency_code": "USD",
                      "payment_details": "Withdrawal to crypto wallet",
                      "payment_txn_id": null,
                      "score": 0,
                      "severity": null,
                      "decision_reason_code": null,
                      "decision_reason_label": null,
                      "vendor_data": "user-12345",
                      "metadata": {
                        "subject": {
                          "entity_type": "individual",
                          "vendor_data": "user-12345",
                          "full_name": "Maria Garcia",
                          "address": {},
                          "institution_details": {},
                          "device_context": {}
                        },
                        "counterparty": {}
                      },
                      "props": {},
                      "tags": [],
                      "parties": [
                        {
                          "uuid": "b1111111-2222-4333-8444-555555555555",
                          "role": "APPLICANT",
                          "entity_type": "individual",
                          "kind": "USER",
                          "vendor_data": "user-12345",
                          "full_name": "Maria Garcia",
                          "first_name": null,
                          "last_name": null,
                          "country_code": null,
                          "dob": null,
                          "address": {},
                          "institution_info": {},
                          "device": {},
                          "external_party_snapshot": null
                        }
                      ],
                      "payment_methods": [],
                      "documents": [],
                      "activities": [
                        {
                          "uuid": "d4e5f6a7-8901-4bcd-9ef0-123456789abc",
                          "activity_type": "TRANSACTION_CREATED",
                          "source": "TRANSACTION",
                          "status": "APPROVED",
                          "title": "withdrawal",
                          "description": "Transaction recorded.",
                          "metadata": {},
                          "occurred_at": "2026-05-17T08:42:11Z"
                        }
                      ],
                      "alerts": [],
                      "rule_runs": [],
                      "provider_results": [],
                      "travel_rule": null,
                      "network_snapshot": null,
                      "remediation": null,
                      "action_required": null,
                      "cost_breakdown": null
                    }
                  },
                  "Flagged for review": {
                    "value": {
                      "uuid": "abcdef12-3456-4890-abcd-ef1234567891",
                      "environment": "live",
                      "transaction_number": 4124,
                      "txn_id": "your-txn-2026-05-17-002",
                      "txn_date": "2026-05-17T08:42:00Z",
                      "zone_id": "Europe/Madrid",
                      "transaction_type": "finance",
                      "action_type": "withdrawal",
                      "direction": "OUTBOUND",
                      "status": "IN_REVIEW",
                      "source": "LIVE",
                      "amount": "0.5",
                      "currency": "BTC",
                      "currency_type": "crypto",
                      "amount_in_default_currency": "32500",
                      "default_currency_code": "USD",
                      "preferred_currency_amount": "32500",
                      "preferred_currency_code": "USD",
                      "payment_details": "Withdrawal to crypto wallet",
                      "payment_txn_id": null,
                      "score": 78,
                      "severity": "HIGH",
                      "decision_reason_code": "WALLET_HIGH_RISK",
                      "decision_reason_label": "Destination wallet flagged as high risk",
                      "vendor_data": "user-12345",
                      "metadata": {
                        "subject": {
                          "entity_type": "individual",
                          "vendor_data": "user-12345",
                          "full_name": "Maria Garcia",
                          "address": {},
                          "institution_details": {},
                          "device_context": {}
                        },
                        "counterparty": {}
                      },
                      "props": {
                        "order_id": "ord-9988"
                      },
                      "tags": [],
                      "parties": [
                        {
                          "uuid": "b1111111-2222-4333-8444-555555555555",
                          "role": "APPLICANT",
                          "entity_type": "individual",
                          "kind": "USER",
                          "vendor_data": "user-12345",
                          "full_name": "Maria Garcia",
                          "first_name": null,
                          "last_name": null,
                          "country_code": null,
                          "dob": null,
                          "address": {},
                          "institution_info": {},
                          "device": {},
                          "external_party_snapshot": null
                        }
                      ],
                      "payment_methods": [],
                      "documents": [],
                      "activities": [],
                      "alerts": [
                        {
                          "uuid": "a7b8c9d0-1234-4abc-9def-567890abcdef",
                          "title": "Destination wallet flagged as high risk",
                          "description": "Provider risk score exceeded the configured threshold.",
                          "severity": "HIGH",
                          "status": "OPEN",
                          "source": "RULE",
                          "metadata": {},
                          "created_at": "2026-05-17T08:42:12Z",
                          "due_at": null
                        }
                      ],
                      "rule_runs": [
                        {
                          "uuid": "e5f6a7b8-9012-4cde-af01-23456789abcd",
                          "rule": "f6a7b8c9-0123-4def-b012-3456789abcde",
                          "rule_title": "High-risk wallet screening",
                          "rule_description": null,
                          "rule_category": "crypto",
                          "matched": true,
                          "is_test": false,
                          "mode": "ACTIVE",
                          "severity": "HIGH",
                          "score_delta": 78,
                          "status_target": "IN_REVIEW",
                          "action_summary": "score +78; change_status:IN_REVIEW",
                          "metadata": {},
                          "created_at": "2026-05-17T08:42:12Z"
                        }
                      ],
                      "provider_results": [],
                      "travel_rule": null,
                      "network_snapshot": null,
                      "remediation": null,
                      "action_required": null,
                      "cost_breakdown": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 실패(필수 필드 누락, 중복된 `transaction_id`, 알 수 없는 열거형(enum) 값, 유효하지 않은 통화 등).",
            "content": {
              "application/json": {
                "examples": {
                  "Missing required field": {
                    "value": {
                      "transaction_details": {
                        "amount": [
                          "This field is required."
                        ]
                      }
                    }
                  },
                  "Duplicate transaction_id": {
                    "value": {
                      "transaction_id": [
                        "A transaction with this transaction_id already exists."
                      ]
                    }
                  },
                  "Invalid category": {
                    "value": {
                      "non_field_errors": [
                        "Unsupported transaction category."
                      ]
                    }
                  },
                  "Missing subject identity": {
                    "value": {
                      "subject": [
                        "subject.vendor_data and subject.full_name are required."
                      ]
                    }
                  },
                  "Blocklisted participant": {
                    "value": {
                      "vendor_data": [
                        "The individual 'user-12345' is in the blocklist and cannot participate in transactions."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 폐기되었거나, 해당 키에 이 애플리케이션에 거래를 제출할 수 있는 권한이 없습니다. 누락된 키는 `403`을 반환하며, 잘못되었거나 폐기되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "이 요청이 처리되는 동안 동일한 `transaction_id`를 가진 다른 요청이 거래를 생성했으므로 두 개의 동시 제출 중 하나만 성공합니다. 다시 제출하는 대신 기존 거래를 조회하십시오.",
            "content": {
              "application/json": {
                "examples": {
                  "Concurrent duplicate": {
                    "value": {
                      "detail": "A transaction with this transaction_id already exists."
                    }
                  }
                }
              }
            }
          },
          "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-didit-sdk": {
          "resource": "transactions",
          "method": "create",
          "auth": "api_key",
          "server": true
        }
      }
    },
    "/v3/transactions/{transaction_id}/": {
      "get": {
        "summary": "거래 가져오기",
        "description": "단일 거래의 전체 모니터링 기록(당사자, 점수/심각도, 규칙 실행, 알림, Travel Rule 결과, 조치 세션)을 조회합니다.",
        "operationId": "getTransaction",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "Didit 고유 거래 UUID(생성/조회 시 반환된 `uuid`이며, 귀하의 `txn_id`가 **아님**).",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "abcdef12-3456-7890-abcd-ef1234567890"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/abcdef12-3456-7890-abcd-ef1234567890/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.retrieve(\n    \"abcdef12-3456-7890-abcd-ef1234567890\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.retrieve(\"abcdef12-3456-7890-abcd-ef1234567890\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Retrieve(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().retrieve(\"abcdef12-3456-7890-abcd-ef1234567890\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->retrieve('abcdef12-3456-7890-abcd-ef1234567890');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.retrieve(\"abcdef12-3456-7890-abcd-ef1234567890\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.RetrieveAsync(\"abcdef12-3456-7890-abcd-ef1234567890\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "전체 거래 세부정보입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionDetail"
                },
                "examples": {
                  "In review with an alert": {
                    "value": {
                      "uuid": "abcdef12-3456-4890-abcd-ef1234567890",
                      "environment": "live",
                      "transaction_number": 4123,
                      "txn_id": "your-txn-2026-05-17-001",
                      "txn_date": "2026-05-17T08:42:00Z",
                      "zone_id": "Europe/Madrid",
                      "transaction_type": "finance",
                      "action_type": "withdrawal",
                      "direction": "OUTBOUND",
                      "status": "IN_REVIEW",
                      "source": "LIVE",
                      "amount": "1500",
                      "currency": "EUR",
                      "currency_type": "fiat",
                      "amount_in_default_currency": "1620.45",
                      "default_currency_code": "USD",
                      "preferred_currency_amount": "1620.45",
                      "preferred_currency_code": "USD",
                      "payment_details": "Withdrawal to crypto wallet",
                      "payment_txn_id": null,
                      "score": 78,
                      "severity": "HIGH",
                      "decision_reason_code": "WALLET_HIGH_RISK",
                      "decision_reason_label": "Destination wallet flagged as high risk",
                      "vendor_data": "user-12345",
                      "metadata": {
                        "subject": {
                          "entity_type": "individual",
                          "vendor_data": "user-12345",
                          "full_name": "Maria Garcia",
                          "address": {},
                          "institution_details": {},
                          "device_context": {}
                        },
                        "counterparty": {}
                      },
                      "props": {
                        "order_id": "ord-9988"
                      },
                      "tags": [],
                      "parties": [
                        {
                          "uuid": "b1111111-2222-4333-8444-555555555555",
                          "role": "APPLICANT",
                          "entity_type": "individual",
                          "kind": "USER",
                          "vendor_data": "user-12345",
                          "full_name": "Maria Garcia",
                          "first_name": null,
                          "last_name": null,
                          "country_code": null,
                          "dob": null,
                          "address": {},
                          "institution_info": {},
                          "device": {},
                          "external_party_snapshot": null
                        }
                      ],
                      "payment_methods": [],
                      "documents": [],
                      "activities": [],
                      "alerts": [
                        {
                          "uuid": "a7b8c9d0-1234-4abc-9def-567890abcdef",
                          "title": "Destination wallet flagged as high risk",
                          "description": "Provider risk score exceeded the configured threshold.",
                          "severity": "HIGH",
                          "status": "OPEN",
                          "source": "RULE",
                          "metadata": {},
                          "created_at": "2026-05-17T08:42:12Z",
                          "due_at": null
                        }
                      ],
                      "rule_runs": [],
                      "provider_results": [],
                      "travel_rule": null,
                      "network_snapshot": null,
                      "remediation": null,
                      "action_required": null,
                      "cost_breakdown": null
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 폐기되었거나, 해당 키에 이 애플리케이션의 거래 정보를 읽을 수 있는 권한이 없습니다. 누락된 키는 `403`을 반환하며, 잘못되었거나 폐기되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 이 UUID를 가진 거래가 존재하지 않습니다(삭제되었거나, 생성된 적이 없거나, 다른 애플리케이션에 속해 있거나, 경로 세그먼트가 유효한 UUID가 아님).",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/transactions/sdk-token/": {
      "post": {
        "summary": "SDK 거래 token 발급",
        "description": "앱이 Didit SDK에 전달할 수 있는 단기 범위 지정 token을 발급하여, SDK가 `POST /v1/transactions/`를 통해 최종 사용자의 기기에서 직접 거래를 제출할 수 있도록 합니다. 이 token은 하나의 `vendor_data`(사용자 ID)에 바인딩됩니다. 해당 token으로 제출된 모든 거래는 해당 바인딩을 통해 서버 측에서 주체 신원이 강제 적용되므로, 변조된 클라이언트가 다른 사용자를 대신하여 제출할 수 없습니다. token은 반드시 백엔드에서 발급하십시오. API 키 자체를 앱에 포함하여 배포해서는 안 됩니다. 카멜 표기법 별칭(`vendorData`, `ttlSeconds`, `maxUses`)도 지원됩니다.",
        "operationId": "createTransactionSdkToken",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "create_sdk_token",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "vendor_data": {
                    "type": "string",
                    "description": "이 token의 범위가 지정된 최종 사용자에 대한 귀하의 내부 식별자입니다. 해당 token으로 제출되는 모든 거래의 주체 ID로 적용됩니다.",
                    "example": "user-042"
                  },
                  "ttl_seconds": {
                    "type": "integer",
                    "default": 900,
                    "maximum": 86400,
                    "description": "token 유효 기간(초 단위)입니다. 기본값은 900(15분), 최대값은 86400(24시간)입니다."
                  },
                  "max_uses": {
                    "type": "integer",
                    "nullable": true,
                    "description": "이 token으로 허용되는 최대 성공 제출 횟수입니다. TTL 내에서 무제한으로 사용하려면 생략하거나 null로 설정하십시오."
                  }
                },
                "required": [
                  "vendor_data"
                ]
              },
              "example": {
                "vendor_data": "user-042",
                "ttl_seconds": 900,
                "max_uses": 3
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/transactions/sdk-token/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"vendor_data\": \"user-042\", \"ttl_seconds\": 900, \"max_uses\": 3}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.create_sdk_token(\n    vendor_data=\"user-042\",\n    ttl_seconds=900,\n    max_uses=3,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.createSdkToken({\n  vendor_data: \"user-042\",\n  ttl_seconds: 900,\n  max_uses: 3,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.CreateSDKToken(ctx, didit.TransactionsCreateSDKTokenParams{\n\tVendorData: \"user-042\",\n\tTTLSeconds: didit.Int(900),\n\tMaxUses:    didit.Int(3),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TransactionsCreateSdkTokenParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().createSdkToken(TransactionsCreateSdkTokenParams.builder()\n        .vendorData(\"user-042\")\n        .ttlSeconds(900L)\n        .maxUses(3L)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->createSdkToken([\n    'vendor_data' => 'user-042',\n    'ttl_seconds' => 900,\n    'max_uses' => 3,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.create_sdk_token(\n  vendor_data: \"user-042\",\n  ttl_seconds: 900,\n  max_uses: 3\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.CreateSdkTokenAsync(new TransactionsCreateSdkTokenParams\n{\n    VendorData = \"user-042\",\n    TtlSeconds = 900,\n    MaxUses = 3,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "발급된 token입니다. `sdk_token`을 앱에 전달하세요. 이 token은 `expires_at`까지 `X-Transaction-Token` 헤더를 통해 디바이스 대상 `/v1/transactions/` endpoint를 인증합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sdk_token": {
                      "type": "string",
                      "description": "SDK에 전달할 스코프가 지정된 거래 token입니다."
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "token이 더 이상 허용되지 않는 시점입니다."
                    }
                  }
                },
                "example": {
                  "sdk_token": "q7Zt...urlsafe",
                  "expires_at": "2026-07-07T12:15:00Z"
                }
              }
            }
          },
          "400": {
            "description": "검증 실패: `vendor_data`가 누락되었거나 `ttl_seconds`가 허용 범위를 벗어났습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing vendor_data": {
                    "value": {
                      "vendor_data": [
                        "This field is required."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 폐기되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid API Key": {
                    "value": {
                      "detail": "Invalid API Key."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/": {
      "post": {
        "summary": "SDK에서 거래 제출",
        "description": "최종 사용자의 기기에서 Didit SDK가 직접 거래를 제출하기 위해 호출하는 디바이스용 endpoint입니다. 인증은 API 키 대신 `X-Transaction-Token` 헤더로 전송되는 `POST /v3/transactions/sdk-token/`의 범위 지정 token을 사용하며, 브라우저가 cross-origin으로 호출할 수 있도록 endpoint에 CORS가 활성화되어 있습니다. payload는 아래에 표시된 camelCase 와이어 별칭을 사용합니다(SDK의 `submitTransaction` 메서드가 이를 자동으로 구성합니다). 세 가지 서버 측 보장 사항: 애플리케이션은 항상 token에서 가져옵니다. 주체 식별자(`externalUserId`)는 항상 token의 `vendor_data`에서 강제 적용되므로 스푸핑된 payload 값은 무시됩니다. 그리고 기기 인텔리전스(SDK 기기 핑거프린트와 서버에서 파생된 IP 및 사용자 에이전트)가 주체에 자동으로 첨부됩니다.",
        "operationId": "submitTransactionFromSdk",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "submit_from_device",
          "auth": "device_token",
          "server": false
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "TransactionTokenAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "txnId": {
                    "type": "string",
                    "description": "귀하가 지정한 해당 거래의 고유 식별자입니다(`transaction_id`에 매핑되며, 최대 128자).",
                    "example": "wd-2026-07-07-0042"
                  },
                  "txnDate": {
                    "type": "string",
                    "format": "date-time",
                    "description": "거래가 발생한 시점입니다(`transaction_at`에 매핑됨). 생략 시 현재 시간으로 기본 설정됩니다."
                  },
                  "zoneId": {
                    "type": "string",
                    "description": "IANA 표준 시간대 식별자(`time_zone`에 매핑됨, 예: `Europe/Madrid`)입니다."
                  },
                  "type": {
                    "type": "string",
                    "description": "거래 카테고리(`transaction_category`에 매핑됨)입니다. 예: `finance`, `kyc`, `travelRule`, `userPlatformEvent`, `gamblingBet`.",
                    "example": "travelRule"
                  },
                  "info": {
                    "type": "object",
                    "description": "거래의 핵심 금융 세부 정보(`transaction_details`에 매핑됨).",
                    "required": [
                      "direction",
                      "amount",
                      "currency"
                    ],
                    "properties": {
                      "direction": {
                        "type": "string",
                        "description": "주체 기준의 방향입니다. 대소문자를 구분하지 않으며, `in`/`out`을 별칭으로 사용할 수 있습니다. 대문자(`INBOUND`/`OUTBOUND`)로 에코되어 반환됩니다.",
                        "example": "out"
                      },
                      "amount": {
                        "type": "number",
                        "description": "거래 금액(소수점 이하 최대 18자리)입니다. 십진수 문자열도 허용되며 약 15자리를 초과하는 유효 숫자를 보존할 수 있는 유일한 방법입니다. JSON 숫자는 먼저 바이너리 부동소수점으로 파싱되므로 `0.123456789012345678`은 `0.12345678901234568`로 저장됩니다.",
                        "example": 0.25
                      },
                      "currency": {
                        "type": "string",
                        "description": "통화 코드입니다. 암호화폐 자산 심볼(예: `BTC`)뿐만 아니라 모든 ISO 4217 알파벳 코드(예: `EUR`, `USD`, `NGN`)를 사용할 수 있습니다. 현재 유통 중인 코드를 사용하는 것이 좋습니다. 지원되는 모든 코드에 환율이 제공되는 것은 아닙니다. 해당 코드의 환율을 사용할 수 없는 경우(예: ISO 회계 단위 `XSU` 또는 Didit에서 가격을 책정하지 않는 암호화폐 심볼), 자동 변환이 실패하며 요청에 사전 변환된 `amountInDefaultCurrency`가 제공되지 않는 한 `preferred_currency_amount`는 null로 반환됩니다.",
                        "example": "ETH"
                      },
                      "currencyType": {
                        "type": "string",
                        "description": "통화가 `fiat`인지 `crypto`인지 여부(`currency_kind`에 매핑됨)입니다."
                      },
                      "amountInDefaultCurrency": {
                        "type": "number",
                        "nullable": true,
                        "description": "기본 통화로 사전 환산된 금액입니다(`amount_in_default_currency`에 매핑됨). 생략하면 자동 환율 변환이 시도됩니다."
                      },
                      "defaultCurrencyCode": {
                        "type": "string",
                        "description": "환산 금액의 기본 통화 코드(`default_currency`에 매핑됨)입니다. 현재 유통되는 ISO 4217 코드 중 하나입니다."
                      },
                      "paymentDetails": {
                        "type": "string",
                        "nullable": true,
                        "description": "자유 형식 결제 참조 또는 메모입니다(`payment_details`에 매핑됨)."
                      },
                      "paymentTxnId": {
                        "type": "string",
                        "nullable": true,
                        "description": "외부 결제 참조(`payment_reference_id`에 매핑됨). 크립토 거래의 경우 온체인 거래 해시입니다."
                      },
                      "type": {
                        "type": "string",
                        "nullable": true,
                        "description": "거래의 하위 유형(`action_type`에 매핑됨)입니다(예: `deposit`, `withdrawal`, `transfer`)."
                      },
                      "cryptoParams": {
                        "type": "object",
                        "description": "암호화폐 관련 파라미터(예: `{\"crypto_chain\": \"ETH\"}`)입니다."
                      }
                    }
                  },
                  "subject": {
                    "type": "object",
                    "description": "거래의 주체(신청자)입니다. 여기서는 `externalUserId`가 무시되며, 주체의 신원은 항상 토큰의 `vendor_data`를 통해 적용됩니다.",
                    "required": [
                      "fullName"
                    ],
                    "properties": {
                      "type": {
                        "type": "string",
                        "description": "엔티티 유형(`entity_type`에 매핑됨): `individual`(기본값) 또는 `company`."
                      },
                      "externalUserId": {
                        "type": "string",
                        "description": "대상(subject)에서는 무시됨 - token의 `vendor_data`를 기반으로 서버 측에서 강제 적용됩니다."
                      },
                      "fullName": {
                        "type": "string",
                        "example": "Jane Doe"
                      },
                      "firstName": {
                        "type": "string"
                      },
                      "lastName": {
                        "type": "string"
                      },
                      "dob": {
                        "type": "string",
                        "format": "date",
                        "description": "생년월일(YYYY-MM-DD, `date_of_birth`에 매핑됨)."
                      },
                      "address": {
                        "type": "object",
                        "description": "`country`(ISO 3166-1 alpha-3), `town`, `state`, `street`, `post_code`를 포함하는 주소 객체입니다."
                      },
                      "institutionInfo": {
                        "type": "object",
                        "description": "기관 참여자의 기관 세부 정보(`institution_details`에 매핑됨)."
                      },
                      "device": {
                        "type": "object",
                        "description": "선택적 명시적 기기 컨텍스트입니다. 자동으로 캡처된 기기 인텔리전스와 병합되며, 충돌 시 서버에서 파생된 필드가 우선합니다."
                      },
                      "paymentMethod": {
                        "type": "object",
                        "description": "주체가 사용하는 결제 수단(`payment_method`에 매핑됨)입니다.",
                        "properties": {
                          "type": {
                            "type": "string",
                            "description": "결제 수단 종류(`method_type`에 매핑됨)입니다(예: `bank_card`, `bank_account`, `crypto_wallet`, `ewallet`, `unhosted_wallet`, `other`)."
                          },
                          "accountId": {
                            "type": "string",
                            "description": "계정 식별자(`account_id`에 매핑됨): IBAN, 카드 지문 또는 지갑 주소."
                          },
                          "issuingCountry": {
                            "type": "string",
                            "description": "발급처의 ISO 3166-1 alpha-3 국가 코드입니다(`issuing_country`에 매핑됨)."
                          }
                        }
                      }
                    }
                  },
                  "counterparty": {
                    "type": "object",
                    "description": "거래의 거래 상대방(선택 사항)입니다. `subject`와 동일한 형태이며, 여기서는 `externalUserId`가 의미를 갖습니다.",
                    "properties": {
                      "type": {
                        "type": "string",
                        "description": "엔티티 유형(`entity_type`에 매핑됨): `individual` 또는 `company`."
                      },
                      "externalUserId": {
                        "type": "string",
                        "description": "거래 상대방에 대한 귀하의 내부 식별자입니다(`vendor_data`에 매핑됨)."
                      },
                      "fullName": {
                        "type": "string"
                      },
                      "firstName": {
                        "type": "string"
                      },
                      "lastName": {
                        "type": "string"
                      },
                      "dob": {
                        "type": "string",
                        "format": "date"
                      },
                      "address": {
                        "type": "object"
                      },
                      "institutionInfo": {
                        "type": "object"
                      },
                      "device": {
                        "type": "object"
                      },
                      "paymentMethod": {
                        "type": "object",
                        "description": "거래 상대방이 사용하는 결제 수단(`payment_method`에 매핑됨)입니다. travelRule 거래에서 `type: \"unhosted_wallet\"`은 거래 상대방 지갑을 자체 보관 지갑으로 신고합니다. 이체는 거래 상대방 VASP 라우팅을 건너뛰고 `UNCONFIRMED_OWNERSHIP` 상태로 직접 생성되며, (`auto_wallet_verification`이 활성화된 경우) 지갑 소유권 위젯 세션이 자동으로 생성되어 SDK가 실행할 수 있도록 `action_required`에 반환됩니다.",
                        "properties": {
                          "type": {
                            "type": "string",
                            "description": "결제 수단 종류(`method_type`에 매핑됨)입니다(예: `bank_card`, `bank_account`, `crypto_wallet`, `ewallet`, `unhosted_wallet`, `other`). Travel Rule을 위한 자체 보관 지갑을 신고하려면 `unhosted_wallet`을 사용하세요."
                          },
                          "accountId": {
                            "type": "string",
                            "description": "계정 식별자(`account_id`에 매핑됨): IBAN, 카드 지문 또는 지갑 주소."
                          },
                          "issuingCountry": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  },
                  "props": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "커스텀 키-값 쌍(`custom_properties`에 매핑됨)입니다. 각 키는 규칙 조건에서 `custom_values.<key>`로 참조할 수 있습니다."
                  },
                  "travelRule": {
                    "type": "object",
                    "description": "Travel Rule 세부 정보(`travel_rule_details`에 매핑됨). 애플리케이션에 Travel Rule이 활성화되어 있으면 Didit은 전송된 `status`를 무시하고 직접 정보 교환을 진행합니다.",
                    "required": [
                      "status"
                    ],
                    "properties": {
                      "status": {
                        "type": "string"
                      },
                      "protocol": {
                        "type": "string"
                      },
                      "required": {
                        "type": "boolean"
                      },
                      "obligationsCount": {
                        "type": "integer"
                      },
                      "originatorData": {
                        "type": "object"
                      },
                      "beneficiaryData": {
                        "type": "object"
                      },
                      "metadata": {
                        "type": "object"
                      }
                    }
                  },
                  "includeCryptoScreening": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "암호화폐 블록체인 분석 스크리닝에 대한 거래별 재정의입니다(`include_crypto_screening`에 매핑됨)."
                  },
                  "fingerprint_v2": {
                    "type": "object",
                    "description": "`didit-fp-v2` 기기 지문 payload입니다. SDK에 의해 자동으로 주입되며, wire API를 직접 호출할 때만 관련이 있습니다."
                  }
                },
                "required": [
                  "txnId",
                  "type",
                  "info",
                  "subject"
                ]
              },
              "example": {
                "txnId": "wd-2026-07-07-0042",
                "type": "travelRule",
                "info": {
                  "direction": "out",
                  "amount": "0.25",
                  "currency": "ETH",
                  "currencyType": "crypto",
                  "cryptoParams": {
                    "crypto_chain": "ETH"
                  }
                },
                "subject": {
                  "fullName": "Jane Doe"
                },
                "counterparty": {
                  "fullName": "Ana Diaz",
                  "paymentMethod": {
                    "type": "unhosted_wallet",
                    "accountId": "0xBeneficiaryWallet01"
                  }
                },
                "travelRule": {
                  "status": "AWAITING_COUNTERPARTY",
                  "beneficiaryData": {
                    "wallet_address": "0xBeneficiaryWallet01",
                    "name": "Ana Diaz"
                  }
                },
                "includeCryptoScreening": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v1/transactions/ \\\n  -H 'X-Transaction-Token: SDK_TOKEN' -H 'Content-Type: application/json' \\\n  -d '{\"txnId\": \"wd-2026-07-07-0042\", \"type\": \"travelRule\", \"info\": {\"direction\": \"out\", \"amount\": \"0.25\", \"currency\": \"ETH\", \"currencyType\": \"crypto\"}, \"subject\": {\"fullName\": \"Jane Doe\"}, \"counterparty\": {\"fullName\": \"Ana Diaz\", \"paymentMethod\": {\"type\": \"unhosted_wallet\", \"accountId\": \"0xBeneficiaryWallet01\"}}, \"travelRule\": {\"status\": \"AWAITING_COUNTERPARTY\", \"beneficiaryData\": {\"wallet_address\": \"0xBeneficiaryWallet01\", \"name\": \"Ana Diaz\"}}, \"includeCryptoScreening\": true}'"
          },
          {
            "lang": "javascript",
            "label": "Web SDK",
            "source": "import { DiditSdk } from '@didit-protocol/sdk-web';\n\nconst result = await DiditSdk.shared.submitTransaction({\n  transactionToken: sdkToken,\n  transaction: {\n    txnId: 'wd-2026-07-07-0042',\n    category: 'travelRule',\n    details: { direction: 'out', amount: '0.25', currency: 'ETH', currencyType: 'crypto' },\n    subject: { fullName: 'Jane Doe' },\n    counterparty: { fullName: 'Ana Diaz', paymentMethod: { type: 'unhosted_wallet', accountId: '0xBeneficiaryWallet01' } },\n    travelRule: { status: 'AWAITING_COUNTERPARTY', beneficiaryData: { wallet_address: '0xBeneficiaryWallet01', name: 'Ana Diaz' } },\n    includeCryptoScreening: true\n  },\n  onActionCompleted: (refreshed) => console.log(refreshed.status)\n});"
          }
        ],
        "responses": {
          "201": {
            "description": "거래가 제출되고 모니터링되었습니다. 최종 사용자가 후속 작업을 완료해야 할 때 포함되는 `action_required` 블록을 포함하여 `GET /v3/transactions/{transaction_id}/`와 동일한 세부 정보 형태입니다(SDK는 기본적으로 이를 자동으로 실행합니다).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionDetail"
                },
                "examples": {
                  "Wallet ownership required": {
                    "value": {
                      "uuid": "22222222-3333-4444-5555-666666666666",
                      "txn_id": "wd-2026-07-07-0042",
                      "transaction_type": "travelRule",
                      "direction": "OUTBOUND",
                      "status": "APPROVED",
                      "amount": "0.25",
                      "currency": "ETH",
                      "travel_rule": {
                        "uuid": "33333333-4444-5555-6666-777777777777",
                        "status": "UNCONFIRMED_OWNERSHIP",
                        "required": true
                      },
                      "action_required": {
                        "type": "wallet_ownership",
                        "url": "https://verify.didit.me/wallet-ownership/3s9x...urlsafe",
                        "widget_session_id": "77777777-8888-9999-aaaa-bbbbbbbbbbbb",
                        "expires_at": "2026-07-07T13:00:00Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 실패(필수 필드 누락, 중복된 `txnId`, 알 수 없는 카테고리).",
            "content": {
              "application/json": {
                "examples": {
                  "Missing fields": {
                    "value": {
                      "transaction_details": {
                        "currency": [
                          "This field is required."
                        ]
                      }
                    }
                  },
                  "Duplicate txnId": {
                    "value": {
                      "transaction_id": [
                        "A transaction with this transaction_id already exists."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "거래 토큰이 거부되었습니다: 누락되었거나, 알 수 없거나, 폐기되었거나, `max_uses`를 초과했거나, 만료되었습니다. 만료된 토큰 응답은 세부 정보에 항상 `expired`라는 단어를 포함하며, SDK는 이를 통해 `expired_token`과 `invalid_token` 오류를 구분합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "Invalid transaction token."
                    }
                  },
                  "Expired token": {
                    "value": {
                      "detail": "Transaction token expired."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "이 요청이 처리되는 동안 동일한 `txnId`를 가진 다른 요청이 거래를 생성했으므로 두 개의 동시 제출 중 하나만 성공합니다. 다시 제출하는 대신 기존 거래를 조회하십시오.",
            "content": {
              "application/json": {
                "examples": {
                  "Concurrent duplicate": {
                    "value": {
                      "detail": "A transaction with this transaction_id already exists."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/{transaction_id}/": {
      "get": {
        "summary": "SDK에서 거래 조회",
        "description": "제출 시 사용된 것과 동일한 `X-Transaction-Token`으로 인증되는 디바이스용 읽기 endpoint입니다. 자동 실행된 작업 흐름이 완료되거나 창이 닫힌 후 SDK가 이를 폴링하므로, 최종 상태가 단일 알림에만 의존하지 않습니다. 제출 응답과 동일한 거래 세부 정보를 반환하며, 현재 `action_required` 블록(작업이 해결되면 `null`)이 포함됩니다.",
        "operationId": "getTransactionFromSdk",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "retrieve_from_device",
          "auth": "device_token",
          "server": false
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "Didit 고유 거래 UUID(제출 응답의 `uuid`이며, 귀하의 `txnId`가 **아님**).",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "22222222-3333-4444-5555-666666666666"
          }
        ],
        "security": [
          {
            "TransactionTokenAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v1/transactions/22222222-3333-4444-5555-666666666666/' \\\n  -H 'X-Transaction-Token: SDK_TOKEN'"
          }
        ],
        "responses": {
          "200": {
            "description": "`action_required`(대기 중인 작업이 해결되면 `null`)를 포함한 전체 거래 세부 정보입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionDetail"
                }
              }
            }
          },
          "401": {
            "description": "거래 토큰이 거부되었습니다: 누락되었거나, 알 수 없거나, 폐기되었거나, `max_uses`를 초과했거나, 만료되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired token": {
                    "value": {
                      "detail": "Transaction token expired."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "token의 애플리케이션에 이 UUID를 가진 거래가 존재하지 않거나, 경로 세그먼트가 유효한 UUID가 아닙니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/businesses/": {
      "get": {
        "summary": "기업 목록 조회",
        "description": "동일한 `vendor_data`(UUID가 아닌 자유 형식 문자열)를 공유하는 KYB 세션으로부터 Didit이 취합한 [기업](/entities/businesses) 및 API를 통해 생성된 기업 목록을 조회합니다. 페이지네이션이 적용되며, `last_session_at` 기준 내림차순으로 정렬됩니다. 이 endpoint는 필터링이나 검색 파라미터를 지원하지 않으므로 페이지를 가져온 후 클라이언트 측에서 필터링하십시오.",
        "operationId": "list_businesses",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "description": "페이지 크기입니다. 생략 시 기본값은 50입니다. 강제된 최댓값은 없으나 지연 시간을 줄이려면 페이지를 작게 유지하십시오."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "description": "반환할 첫 번째 레코드의 0부터 시작하는 오프셋입니다. 직접 계산하기보다는 이전 페이지의 `next` URL을 따르는 것이 좋습니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/businesses/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.businesses.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.businesses.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Businesses.ListAutoPaging(ctx, didit.BusinessesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.businesses().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->businesses->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.businesses.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Businesses.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "상태, 세션 수 및 기능 분석 정보가 포함된 페이지 단위로 제공되는 기업 목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "일치하는 행 수입니다. 최대 100개까지 정확하며, 성능을 위해 그 이상은 100개로 제한됩니다. 마지막 페이지를 감지하는 데 사용하지 마십시오. 대신 `next`가 `null`인지 확인하십시오."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "다음 페이지의 절대 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "이전 페이지의 절대 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BusinessListItem"
                      }
                    }
                  }
                },
                "examples": {
                  "Example": {
                    "value": {
                      "count": 1,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "didit_internal_id": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
                          "vendor_data": "company-123",
                          "display_name": null,
                          "legal_name": "Acme Trading Ltd",
                          "registration_number": "12345678",
                          "country_code": "GB",
                          "effective_name": "Acme Trading Ltd",
                          "status": "ACTIVE",
                          "session_count": 2,
                          "approved_count": 1,
                          "declined_count": 0,
                          "in_review_count": 1,
                          "features": {
                            "KYB": "Approved"
                          },
                          "features_list": [
                            {
                              "feature": "KYB",
                              "status": "Approved"
                            }
                          ],
                          "last_session_at": "2026-03-15T10:30:00Z",
                          "last_activity_at": "2026-03-15T10:30:00Z",
                          "first_session_at": "2026-01-10T08:00:00Z",
                          "tags": [
                            {
                              "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                              "name": "VIP",
                              "color": "#2567FF"
                            }
                          ],
                          "created_at": "2026-01-10T08:00:00Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 폐기되었거나, 해당 키에 이 애플리케이션의 기업을 조회할 수 있는 권한이 없습니다. 누락된 키는 `403`을 반환하며, 잘못되었거나 폐기되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/customization/": {
      "get": {
        "summary": "브랜딩 맞춤 설정 조회",
        "description": "API 키를 통해 확인된 애플리케이션의 화이트 라벨 브랜딩(색상, 글꼴, 모서리 곡률, 로고 URL 및 UI/UX 옵션)을 반환합니다. 커스텀 도메인 및 화이트 라벨 이메일 설정은 Business Console에서만 관리되며 이 응답에는 포함되지 않습니다.",
        "operationId": "get_customization",
        "x-didit-sdk": {
          "resource": "customization",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Customization"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/customization/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.customization.retrieve()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.customization.retrieve();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Customization.Retrieve(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.customization().retrieve();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->customization->retrieve();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.customization.retrieve\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Customization.RetrieveAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "애플리케이션의 현재 브랜딩 맞춤 설정입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingCustomization"
                },
                "examples": {
                  "Default branding": {
                    "value": {
                      "color_primary": "#000000",
                      "color_secondary": "#9DA1A1",
                      "color_background": "#FFFFFF",
                      "color_panel": "#2567FF",
                      "color_panel_10": "#1A1A1A",
                      "color_on_panel_1": "#9DA1A1",
                      "color_on_panel_2": "#F4F4F6",
                      "color_on_background": "#000000",
                      "color_button_1": "#2567FF",
                      "color_button_2": "#F8F8F8",
                      "color_button_text_1": "#FFFFFF",
                      "color_button_text_2": "#000000",
                      "color_pill_text": "#111827",
                      "border_radius_panel": 10,
                      "border_radius_buttons": 12,
                      "font_family": "Inter",
                      "font_weight": "regular",
                      "font_url": "https://fonts.googleapis.com/css2?family=Inter",
                      "logo_square": null,
                      "logo_rectangular": null,
                      "logo_rectangular_dark": null,
                      "favicon": null,
                      "app_public_name": "Acme Verify",
                      "privacy_policy_url": "https://acme.com/privacy",
                      "skip_welcome_screen": false,
                      "disable_login_with_didit": false,
                      "hide_progress_bar": false,
                      "callback_seconds": 3
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나, 형식이 잘못되었거나, 만료되었거나, 다른 애플리케이션으로 범위가 지정되었습니다. 키가 누락된 경우 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. 지수 백오프로 재시도하세요."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "브랜딩 커스터마이징 업데이트",
        "description": "애플리케이션 화이트 라벨 브랜딩의 부분 업데이트입니다. 색상, 글꼴, 곡률 및 UI 옵션을 변경하려면 `application/json`을 전송하고, 로고 이미지를 업로드하려면 `multipart/form-data`를 전송하십시오. 포함된 필드만 변경됩니다. 커스텀 도메인 및 화이트 라벨 이메일은 이 endpoint를 통해 설정할 수 없으며, Business Console을 사용하십시오.",
        "operationId": "update_customization",
        "x-didit-sdk": {
          "resource": "customization",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Customization"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BrandingCustomizationUpdate"
              },
              "examples": {
                "Update colors and font": {
                  "summary": "브랜딩 색상 및 글꼴 변경",
                  "value": {
                    "color_primary": "#123456",
                    "color_button_1": "#2567FF",
                    "font_family": "AR One Sans",
                    "border_radius_buttons": 16
                  }
                },
                "Update UI options": {
                  "summary": "공개 이름 및 플로우 옵션 변경",
                  "value": {
                    "app_public_name": "Acme Verify",
                    "privacy_policy_url": "https://acme.com/privacy",
                    "skip_welcome_screen": true,
                    "hide_progress_bar": true,
                    "callback_seconds": 5
                  }
                },
                "Remove a logo": {
                  "summary": "현재 직사각형 로고 삭제",
                  "value": {
                    "delete_logo_rectangular": true
                  }
                },
                "Remove the dark-mode logo": {
                  "summary": "현재 다크 모드 로고 삭제",
                  "value": {
                    "delete_logo_rectangular_dark": true
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "description": "로고 이미지를 업로드할 때만 multipart/form-data를 사용하십시오. 위의 브랜딩 필드도 동일한 요청에서 폼 필드로 전송할 수 있습니다.",
                "properties": {
                  "image_square": {
                    "type": "string",
                    "format": "binary",
                    "description": "정사각형 로고(1:1 가로세로 비율)입니다. PNG, JPG 또는 WebP 형식이어야 하며, 긴 쪽 기준 최소 512 px, 최대 **1 MB**여야 합니다."
                  },
                  "image_rectangular": {
                    "type": "string",
                    "format": "binary",
                    "description": "직사각형 로고(2:1 가로세로 비율). PNG, JPG 또는 WebP, 긴 쪽 기준 최소 512px, 최대 **1MB**."
                  },
                  "image_rectangular_dark": {
                    "type": "string",
                    "format": "binary",
                    "description": "다크 모드용 직사각형 로고(2:1 가로세로 비율)로, 어두운 배경에 표시됩니다. PNG, JPG 또는 WebP, 긴 쪽 기준 최소 512px, 최대 **1MB**. `logo_rectangular_dark`로 반환됩니다."
                  },
                  "image_favicon": {
                    "type": "string",
                    "format": "binary",
                    "description": "파비콘 이미지. 최대 **500 KB**."
                  }
                }
              },
              "example": {
                "image_rectangular": "(binary PNG logo, 2:1)",
                "image_rectangular_dark": "(binary PNG logo for dark mode, 2:1)",
                "image_favicon": "(binary favicon)"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/customization/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"color_primary\": \"#123456\", \"font_family\": \"AR One Sans\"}'"
          },
          {
            "lang": "curl",
            "label": "curl (logo upload)",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/customization/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'image_rectangular=@logo.png' \\\n  -F 'image_rectangular_dark=@logo-dark.png' \\\n  -F 'image_favicon=@favicon.ico'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.customization.update(\n    image_rectangular=open(\"image_rectangular.jpg\", \"rb\"),\n    image_rectangular_dark=open(\"image_rectangular_dark.jpg\", \"rb\"),\n    image_favicon=open(\"image_favicon.jpg\", \"rb\"),\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.customization.update({\n  image_rectangular: await fileFromPath(\"image_rectangular.jpg\"),\n  image_rectangular_dark: await fileFromPath(\"image_rectangular_dark.jpg\"),\n  image_favicon: await fileFromPath(\"image_favicon.jpg\"),\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Customization.Update(ctx, didit.CustomizationUpdateParams{\n\tImageRectangular:     didit.Some(didit.FileFromPath(\"image_rectangular.jpg\")),\n\tImageRectangularDark: didit.Some(didit.FileFromPath(\"image_rectangular_dark.jpg\")),\n\tImageFavicon:         didit.Some(didit.FileFromPath(\"image_favicon.jpg\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.CustomizationUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.customization().update(CustomizationUpdateParams.builder()\n        .imageRectangular(Path.of(\"image_rectangular.jpg\"))\n        .imageRectangularDark(Path.of(\"image_rectangular_dark.jpg\"))\n        .imageFavicon(Path.of(\"image_favicon.jpg\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->customization->update([\n    'image_rectangular' => File::fromPath('image_rectangular.jpg'),\n    'image_rectangular_dark' => File::fromPath('image_rectangular_dark.jpg'),\n    'image_favicon' => File::fromPath('image_favicon.jpg'),\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.customization.update(\n  image_rectangular: Pathname(\"image_rectangular.jpg\"),\n  image_rectangular_dark: Pathname(\"image_rectangular_dark.jpg\"),\n  image_favicon: Pathname(\"image_favicon.jpg\")\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Customization.UpdateAsync(new CustomizationUpdateParams\n{\n    ImageRectangular = FileUpload.FromPath(\"image_rectangular.jpg\"),\n    ImageRectangularDark = FileUpload.FromPath(\"image_rectangular_dark.jpg\"),\n    ImageFavicon = FileUpload.FromPath(\"image_favicon.jpg\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "브랜딩이 업데이트되었습니다. 전체 브랜딩 객체가 반환됩니다(변경된 필드뿐만 아니라 모든 필드 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingCustomization"
                },
                "examples": {
                  "Updated": {
                    "value": {
                      "color_primary": "#123456",
                      "color_secondary": "#9DA1A1",
                      "color_background": "#FFFFFF",
                      "color_panel": "#2567FF",
                      "color_panel_10": "#1A1A1A",
                      "color_on_panel_1": "#9DA1A1",
                      "color_on_panel_2": "#F4F4F6",
                      "color_on_background": "#000000",
                      "color_button_1": "#2567FF",
                      "color_button_2": "#F8F8F8",
                      "color_button_text_1": "#FFFFFF",
                      "color_button_text_2": "#000000",
                      "color_pill_text": "#111827",
                      "border_radius_panel": 10,
                      "border_radius_buttons": 16,
                      "font_family": "AR One Sans",
                      "font_weight": "400",
                      "font_url": "https://fonts.googleapis.com/css2?family=AR+One+Sans",
                      "logo_square": null,
                      "logo_rectangular": "https://cdn.didit.me/white_label/logo_rectangular/...",
                      "logo_rectangular_dark": null,
                      "favicon": null,
                      "app_public_name": "Acme Verify",
                      "privacy_policy_url": "https://acme.com/privacy",
                      "skip_welcome_screen": true,
                      "disable_login_with_didit": false,
                      "hide_progress_bar": false,
                      "callback_seconds": 3
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 본문입니다. 예: 잘못된 형식의 16진수 색상 코드, 알 수 없는 글꼴 모음 또는 굵기, Business Console 전용 필드(`domain`, `from_email`, `verify_domain`, `force_remove_domain`, `verify_email_domain`, `force_remove_email_domain` 및 관련 읽기 전용 필드), 또는 로고 업로드 파일이 PNG, JPG, WebP 이미지가 아니거나, 긴 쪽의 길이가 512 px 미만이거나, 1 MB를 초과하거나, 가로세로 비율이 올바르지 않은 경우입니다. 또한 사용자 지정 도메인이 구성된 상태에서 `disable_login_with_didit`을 `false`로 설정할 때도 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Bad color": {
                    "value": {
                      "color_primary": [
                        "Invalid color format. Use '#RRGGBB' or '#RRGGBBAA' format."
                      ]
                    }
                  },
                  "Bad logo": {
                    "value": {
                      "image_rectangular": [
                        "Image aspect ratio must be 2:1. Got 1024x1024 image dimensions"
                      ]
                    }
                  },
                  "Unsupported logo format": {
                    "summary": "PNG, JPG 또는 WebP 이미지가 아님(예: SVG)",
                    "value": {
                      "image_rectangular_dark": [
                        "Upload a PNG, JPG or WebP image."
                      ]
                    }
                  },
                  "Logo too small": {
                    "summary": "긴 변 기준 512 px 미만",
                    "value": {
                      "image_rectangular": [
                        "Image must be at least 512 px on its long side. Got 400x200 image dimensions"
                      ]
                    }
                  },
                  "Logo too large": {
                    "summary": "1MB 초과",
                    "value": {
                      "image_square": [
                        "File size should not exceed 1 MB"
                      ]
                    }
                  },
                  "Console-only field": {
                    "value": {
                      "domain": [
                        "Manage this field in the Business Console."
                      ]
                    }
                  },
                  "Bad font weight": {
                    "value": {
                      "font_weight": [
                        "Font weight 950 is not available for Inter. Available weights are: 100, 200, 300, 400, 500, 600, 700, 800, 900"
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나, 형식이 잘못되었거나, 만료되었거나, 다른 애플리케이션으로 범위가 지정되었습니다. 키가 누락된 경우 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. 지수 백오프로 재시도하세요."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/businesses/{vendor_data}/": {
      "get": {
        "summary": "기업 조회",
        "description": "`vendor_data`(정확히 일치)로 특정 [기업](/entities/businesses)을 가져옵니다. 목록 뷰에 `metadata` 및 `updated_at`을 추가합니다. 삭제된 기업은 404를 반환합니다.",
        "operationId": "get_business",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "귀하가 지정한 기업의 고유 식별자입니다. 자유 형식 문자열(UUID 아님)이며, 전송된 값과 정확히 일치해야 합니다.",
            "example": "company-123"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/businesses/company-123/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.retrieve(\n    \"company-123\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.retrieve(\"company-123\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.Retrieve(ctx, \"company-123\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().retrieve(\"company-123\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->businesses->retrieve('company-123');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.retrieve(\"company-123\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.RetrieveAsync(\"company-123\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "메타데이터 및 집계된 세션 데이터를 포함한 전체 기업 상세 정보입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessDetailItem"
                },
                "examples": {
                  "Active business": {
                    "value": {
                      "didit_internal_id": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
                      "vendor_data": "company-123",
                      "display_name": null,
                      "legal_name": "Acme Trading Ltd",
                      "registration_number": "12345678",
                      "country_code": "GB",
                      "effective_name": "Acme Trading Ltd",
                      "status": "ACTIVE",
                      "session_count": 2,
                      "approved_count": 1,
                      "declined_count": 0,
                      "in_review_count": 1,
                      "features": {
                        "KYB": "Approved"
                      },
                      "features_list": [
                        {
                          "feature": "KYB",
                          "status": "Approved"
                        }
                      ],
                      "last_session_at": "2026-03-15T10:30:00Z",
                      "last_activity_at": "2026-03-15T10:30:00Z",
                      "first_session_at": "2026-01-10T08:00:00Z",
                      "tags": [
                        {
                          "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                          "name": "VIP",
                          "color": "#2567FF"
                        }
                      ],
                      "created_at": "2026-01-10T08:00:00Z",
                      "metadata": {
                        "industry": "fintech"
                      },
                      "updated_at": "2026-03-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 폐기되었거나, 해당 키에 이 애플리케이션의 기업 정보를 읽을 수 있는 권한이 없습니다. 누락된 키는 `403`을 반환하며, 잘못되었거나 폐기되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "제공된 `vendor_data`를 가진 (삭제되지 않은) 기업이 이 애플리케이션에 존재하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "기업 업데이트",
        "description": "기업 정보의 부분 업데이트: `display_name`, `legal_name`, `registration_number`, `country_code`, `status`, `metadata`. `metadata`는 전체가 대체됩니다. `status`를 `BLOCKED`로 설정하면 `vendor_data`가 시스템 차단 목록에 추가되며, `BLOCKED`에서 다른 상태로 변경하면 해당 항목이 제거됩니다. 모든 수정 사항은 기업 활동에 기록됩니다. 상태 변경은 선택적 `reason`과 함께 기록되며, `display_name`, `legal_name`, `registration_number`, `country_code` 또는 `metadata` 변경은 프로필 업데이트로 기록됩니다.",
        "operationId": "update_business",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "귀하가 지정한 기업의 고유 식별자입니다(자유 형식 문자열, UUID 아님).",
            "example": "company-123"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "부분 업데이트 본문입니다. 변경하려는 필드만 제공하십시오.",
                "properties": {
                  "display_name": {
                    "type": "string",
                    "nullable": true,
                    "description": "콘솔에 표시되는 친숙한 표시 이름입니다(UI 표시 시 `legal_name`보다 우선 적용됨)."
                  },
                  "legal_name": {
                    "type": "string",
                    "nullable": true,
                    "description": "등기부 또는 직접 입력에서 가져온 공식 법인명입니다."
                  },
                  "registration_number": {
                    "type": "string",
                    "nullable": true,
                    "description": "기업 등록번호 또는 법인 설립 번호입니다."
                  },
                  "country_code": {
                    "type": "string",
                    "nullable": true,
                    "description": "설립 국가(ISO 3166-1 alpha-2, 예: `GB`, `US`)."
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "ACTIVE",
                      "FLAGGED",
                      "BLOCKED"
                    ],
                    "description": "기업 수명 주기 상태입니다. `BLOCKED`로 설정하면 `vendor_data`가 시스템 차단 목록에 자동으로 추가되며, `BLOCKED`가 아닌 상태로 변경하면 해당 차단 목록 항목이 제거됩니다."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "기업에 연결하는 임의의 JSON 객체입니다. 업데이트 시 기존 메타데이터를 **완전히 대체**합니다. 키만 추가하려면 클라이언트 측에서 병합하십시오."
                  },
                  "reason": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 1000,
                    "description": "상태가 변경된 이유입니다. 상태가 실제로 변경될 때만 Business Console의 회사 **Activity** 상태 변경 항목에 기록됩니다. webhook에는 포함되지 않습니다."
                  }
                }
              },
              "examples": {
                "Update name": {
                  "summary": "표시 이름 업데이트",
                  "value": {
                    "display_name": "Acme Corp"
                  }
                },
                "Flag for review": {
                  "summary": "상태 전환",
                  "value": {
                    "status": "FLAGGED"
                  }
                },
                "Add metadata": {
                  "summary": "메타데이터 JSON 대체",
                  "value": {
                    "metadata": {
                      "industry": "fintech",
                      "risk_level": "low"
                    }
                  }
                },
                "Fix registry data": {
                  "summary": "정확하게 추출된 필드",
                  "value": {
                    "legal_name": "Acme Trading International Ltd",
                    "registration_number": "12345678",
                    "country_code": "GB"
                  }
                },
                "Flag with reason": {
                  "summary": "기업 플래그 지정 및 사유 기록",
                  "value": {
                    "status": "FLAGGED",
                    "reason": "Ownership structure under review"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/businesses/company-123/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"display_name\": \"Acme Corp\", \"status\": \"FLAGGED\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.update(\n    \"company-123\",\n    display_name=\"Acme Corp\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.update(\"company-123\", {\n  display_name: \"Acme Corp\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.Update(ctx, \"company-123\", didit.BusinessesUpdateParams{\n\tDisplayName: didit.String(\"Acme Corp\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BusinessesUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().update(\"company-123\", BusinessesUpdateParams.builder()\n        .displayName(\"Acme Corp\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->businesses->update('company-123', [\n    'display_name' => 'Acme Corp',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.update(\n  \"company-123\",\n  display_name: \"Acme Corp\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.UpdateAsync(\"company-123\", new BusinessesUpdateParams\n{\n    DisplayName = \"Acme Corp\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "기업이 업데이트되었습니다. 업데이트된 전체 기업 레코드가 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessDetailItem"
                },
                "examples": {
                  "Updated": {
                    "value": {
                      "didit_internal_id": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
                      "vendor_data": "company-123",
                      "display_name": "Acme Corp",
                      "legal_name": "Acme Trading Ltd",
                      "registration_number": "12345678",
                      "country_code": "GB",
                      "effective_name": "Acme Corp",
                      "status": "FLAGGED",
                      "session_count": 2,
                      "approved_count": 1,
                      "declined_count": 0,
                      "in_review_count": 1,
                      "features": {
                        "KYB": "Approved"
                      },
                      "features_list": [
                        {
                          "feature": "KYB",
                          "status": "Approved"
                        }
                      ],
                      "last_session_at": "2026-03-15T10:30:00Z",
                      "last_activity_at": "2026-03-15T10:30:00Z",
                      "first_session_at": "2026-01-10T08:00:00Z",
                      "tags": [
                        {
                          "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                          "name": "VIP",
                          "color": "#2567FF"
                        }
                      ],
                      "created_at": "2026-01-10T08:00:00Z",
                      "metadata": {
                        "industry": "fintech",
                        "risk_level": "low"
                      },
                      "updated_at": "2026-03-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 본문: 일반적으로 알 수 없는 `status`, 잘못된 형식의 `metadata`, 또는 1000자를 초과하는 `reason`입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Bad status": {
                    "value": {
                      "status": [
                        "Invalid status. Valid options are: ACTIVE, FLAGGED, BLOCKED"
                      ]
                    }
                  },
                  "Bad metadata": {
                    "value": {
                      "metadata": [
                        "Metadata must be a JSON object."
                      ]
                    }
                  },
                  "Reason too long": {
                    "value": {
                      "reason": [
                        "Ensure this field has no more than 1000 characters."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 폐기되었거나, 해당 키에 이 애플리케이션의 기업을 업데이트할 수 있는 권한이 없습니다. 누락된 키는 `403`을 반환하며, 잘못되었거나 폐기되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "제공된 `vendor_data`를 가진 (삭제되지 않은) 기업이 이 애플리케이션에 존재하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/businesses/{vendor_data}/update-status/": {
      "patch": {
        "summary": "기업 상태 업데이트",
        "description": "기업의 수명 주기 `status`만 전환합니다: `ACTIVE`, `FLAGGED` 또는 `BLOCKED`(세션 상태 아님). `BLOCKED`는 `vendor_data`를 시스템 차단 목록에 추가하며, `BLOCKED`에서 다른 상태로 변경하면 해당 항목이 제거됩니다. 각 변경 사항은 선택 사항인 `reason`과 함께 기업의 활동에 기록됩니다. 현재 상태를 그대로 전송하면 아무것도 변경되지 않으며 `reason`도 기록되지 않습니다. `business.status.updated` webhook에는 `reason`이 포함되지 않습니다.",
        "operationId": "update_business_status",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "update_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "귀하가 지정한 기업의 고유 식별자입니다(자유 형식 문자열, UUID 아님).",
            "example": "company-123"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/EntityStatusUpdateRequest"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "reason": {
                        "type": "string",
                        "nullable": true,
                        "maxLength": 1000,
                        "description": "상태가 변경된 이유입니다. 상태가 실제로 변경될 때만 Business Console의 회사 **Activity** 상태 변경 항목에 기록됩니다. webhook에는 포함되지 않습니다."
                      }
                    }
                  }
                ]
              },
              "examples": {
                "Flag": {
                  "summary": "검토를 위해 기업 플래그 지정",
                  "value": {
                    "status": "FLAGGED"
                  }
                },
                "Block": {
                  "summary": "해당 기업 차단(시스템 차단 목록에 추가)",
                  "value": {
                    "status": "BLOCKED"
                  }
                },
                "Reactivate": {
                  "summary": "기업 재활성화",
                  "value": {
                    "status": "ACTIVE"
                  }
                },
                "Block with reason": {
                  "summary": "해당 기업 차단 및 사유 기록",
                  "value": {
                    "status": "BLOCKED",
                    "reason": "Registry shows the company dissolved"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/businesses/company-123/update-status/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"status\": \"BLOCKED\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.update_status(\n    \"company-123\",\n    status=\"FLAGGED\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.updateStatus(\"company-123\", {\n  status: \"FLAGGED\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.UpdateStatus(ctx, \"company-123\", didit.BusinessesUpdateStatusParams{\n\tStatus: \"FLAGGED\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BusinessesUpdateStatusParams;\nimport me.didit.types.EntityStatusUpdateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().updateStatus(\"company-123\", BusinessesUpdateStatusParams.builder()\n        .status(EntityStatusUpdateRequest.Status.of(\"FLAGGED\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->businesses->updateStatus('company-123', [\n    'status' => 'FLAGGED',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.update_status(\n  \"company-123\",\n  status: \"FLAGGED\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.UpdateStatusAsync(\"company-123\", new BusinessesUpdateStatusParams\n{\n    Status = \"FLAGGED\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "기업 상태가 업데이트되었습니다. 전체 기업 레코드가 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessDetailItem"
                },
                "examples": {
                  "Blocked": {
                    "value": {
                      "didit_internal_id": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
                      "vendor_data": "company-123",
                      "display_name": null,
                      "legal_name": "Acme Trading Ltd",
                      "registration_number": "12345678",
                      "country_code": "GB",
                      "effective_name": "Acme Trading Ltd",
                      "status": "BLOCKED",
                      "session_count": 2,
                      "approved_count": 1,
                      "declined_count": 0,
                      "in_review_count": 1,
                      "features": {
                        "KYB": "Approved"
                      },
                      "features_list": [
                        {
                          "feature": "KYB",
                          "status": "Approved"
                        }
                      ],
                      "last_session_at": "2026-03-15T10:30:00Z",
                      "last_activity_at": "2026-03-15T10:30:00Z",
                      "first_session_at": "2026-01-10T08:00:00Z",
                      "tags": [
                        {
                          "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                          "name": "VIP",
                          "color": "#2567FF"
                        }
                      ],
                      "created_at": "2026-01-10T08:00:00Z",
                      "metadata": {
                        "industry": "fintech"
                      },
                      "updated_at": "2026-03-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`status`가 누락되었거나 유효하지 않습니다. 또는 `reason`이 1000자를 초과합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing status": {
                    "value": {
                      "status": [
                        "This field is required."
                      ]
                    }
                  },
                  "Bad status": {
                    "value": {
                      "status": [
                        "Invalid status. Valid options are: ACTIVE, FLAGGED, BLOCKED"
                      ]
                    }
                  },
                  "Reason too long": {
                    "value": {
                      "reason": [
                        "Ensure this field has no more than 1000 characters."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 폐기되었거나, 해당 키에 이 애플리케이션의 기업을 업데이트할 수 있는 권한이 없습니다. 누락된 키는 `403`을 반환하며, 잘못되었거나 폐기되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "제공된 `vendor_data`를 가진 (삭제되지 않은) 기업이 이 애플리케이션에 존재하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/businesses/delete/": {
      "post": {
        "summary": "기업 일괄 삭제",
        "description": "기업을 **영구 삭제**합니다. 이 작업은 취소할 수 없습니다. 차단하려면 `BLOCKED` 상태로 [Update Business Status](#patch-/v3/businesses/-vendor_data-/update-status/)를 사용하는 것이 좋습니다.\n\n**제출된 규제 보고서:** 선택한 데이터가 최종 확정된 규제 보고서에 포함되어 있는 경우 전체 요청이 `409`로 거부되며 아무것도 삭제되지 않습니다. 응답 본문은 `code: in_filed_report`를 사용하며 `uuid`, `report_number`, `report_type`, `case_uuid`로 각 보고서를 지정합니다. 해당 보고서를 삭제한 후 요청을 다시 시도하십시오.",
        "operationId": "batch_delete_businesses",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "batch_delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Businesses"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "`vendor_data_list`, `didit_internal_id_list` 또는 `delete_all: true`를 제공하세요. 여러 항목이 전송될 때의 우선순위는 `delete_all` > `vendor_data_list` > `didit_internal_id_list`입니다(가장 높은 우선순위의 선택자만 사용됨).",
                "properties": {
                  "vendor_data_list": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "삭제할 귀하 고유의 식별자 목록이며, 전송된 내용과 정확히 일치합니다."
                  },
                  "didit_internal_id_list": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "삭제할 Didit 내부 UUID(`didit_internal_id`)입니다."
                  },
                  "delete_all": {
                    "type": "boolean",
                    "default": false,
                    "description": "`true`인 경우 애플리케이션의 모든 기업을 삭제합니다. 목록 선택기와 함께 사용할 수 없습니다."
                  }
                }
              },
              "examples": {
                "Specific businesses": {
                  "summary": "vendor_data로 삭제",
                  "value": {
                    "vendor_data_list": [
                      "company-123",
                      "company-456"
                    ]
                  }
                },
                "Specific internal IDs": {
                  "summary": "didit_internal_id로 삭제",
                  "value": {
                    "didit_internal_id_list": [
                      "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                      "b2c3d4e5-f6a7-8901-bcde-f12345678901"
                    ]
                  }
                },
                "All businesses": {
                  "summary": "이 애플리케이션의 모든 기업 삭제",
                  "value": {
                    "delete_all": true
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/businesses/delete/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"vendor_data_list\": [\"company-123\", \"company-456\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.batch_delete(\n    vendor_data_list=[\"company-123\", \"company-456\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.batchDelete({\n  vendor_data_list: [\"company-123\", \"company-456\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.BatchDelete(ctx, didit.BusinessesBatchDeleteParams{\n\tVendorDataList: didit.Some([]string{\"company-123\", \"company-456\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.BusinessesBatchDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().batchDelete(BusinessesBatchDeleteParams.builder()\n        .vendorDataList(List.of(\"company-123\", \"company-456\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->businesses->batchDelete([\n    'vendor_data_list' => ['company-123', 'company-456'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.batch_delete(vendor_data_list: [\"company-123\", \"company-456\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.BatchDeleteAsync(new BusinessesBatchDeleteParams\n{\n    VendorDataList = new string[] { \"company-123\", \"company-456\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "기업이 삭제되었습니다. 실제로 제거된 행 수를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "integer",
                      "description": "삭제된 기업 수입니다(일치하는 항목이 없는 vendor_data 값은 제외됩니다)."
                    }
                  }
                },
                "examples": {
                  "Deleted some": {
                    "value": {
                      "deleted": 2
                    }
                  },
                  "Nothing matched": {
                    "value": {
                      "deleted": 0
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "선택자가 제공되지 않았습니다(`vendor_data_list`, `didit_internal_id_list`, `delete_all`이 모두 누락되었거나 비어 있음). 오류 본문은 JSON 배열입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing selector": {
                    "value": [
                      "Provide vendor_data_list, didit_internal_id_list, or set delete_all=true."
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 폐기되었거나, 해당 키에 이 애플리케이션의 기업을 삭제할 수 있는 권한이 없습니다. 누락된 키는 `403`을 반환하며, 잘못되었거나 폐기되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "아무것도 삭제되지 않았습니다. `code`에 이유가 표시됩니다. 선택 항목에 제출 완료된 규제 보고서에 포함된 기업이 있는 경우 `in_filed_report`, 다른 요청이 선택된 기업 중 하나를 아직 삭제 중인 경우 `subject_deletion_in_progress`입니다. 해당 삭제가 완료된 후 요청을 다시 시도하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/InFiledReportError"
                    },
                    {
                      "$ref": "#/components/schemas/SubjectDeletionInProgressError"
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/users/aml-monitoring/": {
      "post": {
        "summary": "사용자에 대한 지속적인 AML 모니터링 활성화 또는 비활성화",
        "description": "선택한 사용자에 대해 Business Console과 동일한 의미 체계로 지속적인 AML 모니터링을 켜거나 끕니다. 사용자당 정확히 하나의 모니터링되는 AML 스크리닝이 유지되므로, 여러 번 인증된 프로필도 한 번만 모니터링되고 비용이 청구됩니다. 비활성화하면 프로필의 모든 스크리닝에 걸쳐 모니터링이 꺼집니다. AML 스크리닝이 전혀 없는 사용자는 필요한 성명, 생년월일 및 국가가 있는 경우 먼저 스크리닝됩니다(일반 AML 스크리닝으로 청구됨). 그렇지 않은 경우 `skipped_no_identity_data`로 보고됩니다.\n\n데이터를 쓰지 않고 개수와 비용을 미리 보려면 `estimate_only: true`로 설정하십시오. 20개 이하의 프로필 선택 항목은 인라인으로 처리되어 완료된 작업과 함께 `200`을 반환합니다. 더 큰 선택 항목은 `202`를 반환하고 백그라운드에서 실행되므로 반환된 `job_id`를 사용하여 [AML 모니터링 작업 조회](#get-/v3/aml-monitoring/jobs/-job_id-/)를 폴링하십시오. 조직 잔액이 예상 금액을 충당하지 못하는 경우 활성화가 `403`으로 거부됩니다. 일치하는 대상이 없는 식별자는 `unmatched`에 나열되며 요청을 실패 처리하지 않습니다. 일치하는 항목이 없는 선택은 빈 작업(`total` 0)으로 완료되며, 이는 일괄 삭제 endpoint와 동일한 규칙입니다.",
        "operationId": "toggle_users_aml_monitoring",
        "x-didit-sdk": {
          "resource": "users",
          "method": "set_aml_monitoring",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "AML Ongoing Monitoring"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "is_enabled"
                ],
                "description": "`vendor_data_list`, `didit_internal_id_list` 또는 둘 다를 사용하여 사용자를 선택합니다(두 목록은 OR 조건으로 결합됨). 두 목록을 합쳐 요청당 최대 1,000개의 식별자까지 가능합니다.",
                "properties": {
                  "is_enabled": {
                    "type": "boolean",
                    "description": "모니터링을 활성화하려면 true, 비활성화하려면 false입니다."
                  },
                  "estimate_only": {
                    "type": "boolean",
                    "default": false,
                    "description": "true인 경우, 예상 비용을 반환하며 쓰기 작업(스크리닝, 결제, 작업)을 수행하지 않습니다."
                  },
                  "vendor_data_list": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "상태를 전환할 사용자들의 귀하 고유 식별자 목록이며, 전송된 내용과 정확히 일치합니다."
                  },
                  "didit_internal_id_list": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "토글할 사용자의 Didit 내부 ID입니다. 생성, 조회 및 목록 endpoint에서 반환된 `didit_internal_id`입니다."
                  }
                }
              },
              "examples": {
                "Estimate first": {
                  "summary": "쓰기 작업 없이 비용 미리보기",
                  "value": {
                    "is_enabled": true,
                    "estimate_only": true,
                    "vendor_data_list": [
                      "user-123",
                      "user-456"
                    ]
                  }
                },
                "Enable": {
                  "summary": "사용자 2명에 대한 모니터링 활성화",
                  "value": {
                    "is_enabled": true,
                    "vendor_data_list": [
                      "user-123",
                      "user-456"
                    ]
                  }
                },
                "Disable": {
                  "summary": "Didit 내부 id로 모니터링 비활성화",
                  "value": {
                    "is_enabled": false,
                    "didit_internal_id_list": [
                      "3f1c0d3e-8f0a-4c2e-9a3d-9b1f5f4a2c11"
                    ]
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/users/aml-monitoring/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"is_enabled\": true, \"vendor_data_list\": [\"user-123\", \"user-456\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.set_aml_monitoring(\n    is_enabled=True,\n    estimate_only=True,\n    vendor_data_list=[\"user-123\", \"user-456\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.setAmlMonitoring({\n  is_enabled: true,\n  estimate_only: true,\n  vendor_data_list: [\"user-123\", \"user-456\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.SetAMLMonitoring(ctx, didit.UsersSetAMLMonitoringParams{\n\tIsEnabled:      true,\n\tEstimateOnly:   didit.Bool(true),\n\tVendorDataList: didit.Some([]string{\"user-123\", \"user-456\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.UsersSetAmlMonitoringParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().setAmlMonitoring(UsersSetAmlMonitoringParams.builder()\n        .isEnabled(true)\n        .estimateOnly(true)\n        .vendorDataList(List.of(\"user-123\", \"user-456\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->users->setAmlMonitoring([\n    'is_enabled' => true,\n    'estimate_only' => true,\n    'vendor_data_list' => ['user-123', 'user-456'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.set_aml_monitoring(\n  is_enabled: true,\n  estimate_only: true,\n  vendor_data_list: [\"user-123\", \"user-456\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.SetAmlMonitoringAsync(new UsersSetAmlMonitoringParams\n{\n    IsEnabled = true,\n    EstimateOnly = true,\n    VendorDataList = new string[] { \"user-123\", \"user-456\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "견적(`estimate_only`가 true인 경우) 또는 인라인으로 처리된 선택 항목에 대한 완료된 작업입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AMLMonitoringToggleResult"
                }
              }
            }
          },
          "202": {
            "description": "대규모 선택 항목은 백그라운드에서 실행됩니다. `job_id`로 작업 endpoint를 폴링하세요. 프로필이 처리됨에 따라 `results`가 채워집니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AMLMonitoringJob"
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류: `is_enabled`가 누락되었거나, 선택자가 없거나, 두 목록을 합쳐 식별자가 1000개를 초과합니다."
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "이 선택 항목에 대한 모니터링을 활성화하기 위한 잔액이 부족합니다. 적절한 금액을 충전할 수 있도록 응답에 `estimate`가 포함됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "estimate": {
                      "type": "object",
                      "description": "예상 비용입니다. estimate_only가 true인 경우 직접 반환됩니다(아무것도 기록되지 않음).",
                      "properties": {
                        "users_total": {
                          "type": "integer",
                          "description": "선택 조건과 일치하는 프로필 수입니다."
                        },
                        "already_enabled": {
                          "type": "integer",
                          "description": "이미 모니터링 중인 프로필(활성화 시 수행할 작업 없음. 비활성화 시 해제되는 대상임)."
                        },
                        "with_existing_aml": {
                          "type": "integer",
                          "description": "기존 AML 스크리닝이 모니터링 상태로 전환될 프로필 수(신규 스크리닝 없음)."
                        },
                        "needing_screening": {
                          "type": "integer",
                          "description": "AML 스크리닝 이력이 없어 먼저 스크리닝을 진행할 프로필 수(일반 AML 스크리닝으로 청구됨)."
                        },
                        "skipped_no_identity_data": {
                          "type": "integer",
                          "description": "신원 데이터가 누락되어 스크리닝할 수 없는 프로필 수입니다."
                        },
                        "skipped_blocked": {
                          "type": "integer",
                          "description": "건너뛸 차단된 사용자 수입니다(기업의 경우 항상 0)."
                        },
                        "estimated_screening_cost_usd": {
                          "type": "number",
                          "example": 0.2,
                          "description": "새 스크리닝의 일회성 비용입니다."
                        },
                        "estimated_annual_monitoring_cost_usd": {
                          "type": "number",
                          "example": 0.07,
                          "description": "모니터링 대상이 될 프로필의 연간 모니터링 비용입니다."
                        },
                        "balance_sufficient": {
                          "type": "boolean",
                          "description": "조직 잔액이 스크리닝과 첫해 모니터링 비용을 충당할 수 있는지 여부입니다."
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/businesses/aml-monitoring/": {
      "post": {
        "summary": "기업에 대한 지속적인 AML 모니터링 활성화 또는 비활성화",
        "description": "선택한 기업에 대해 Business Console과 동일한 의미 체계로 지속적인 AML 모니터링을 켜거나 끕니다. 기업당 정확히 하나의 모니터링되는 AML 스크리닝이 유지되므로, 여러 번 인증된 프로필도 한 번만 모니터링되고 비용이 청구됩니다. 비활성화하면 프로필의 모든 스크리닝에 걸쳐 모니터링이 꺼집니다. AML 스크리닝이 전혀 없는 기업은 필요한 법인명 또는 표시 이름이 있는 경우 먼저 스크리닝됩니다(일반 AML 스크리닝으로 청구됨). 그렇지 않은 경우 `skipped_no_identity_data`로 보고됩니다.\n\n데이터를 쓰지 않고 개수와 비용을 미리 보려면 `estimate_only: true`로 설정하십시오. 20개 이하의 프로필 선택 항목은 인라인으로 처리되어 완료된 작업과 함께 `200`을 반환합니다. 더 큰 선택 항목은 `202`를 반환하고 백그라운드에서 실행되므로 반환된 `job_id`를 사용하여 [AML 모니터링 작업 조회](#get-/v3/aml-monitoring/jobs/-job_id-/)를 폴링하십시오. 조직 잔액이 예상 금액을 충당하지 못하는 경우 활성화가 `403`으로 거부됩니다. 일치하는 대상이 없는 식별자는 `unmatched`에 나열되며 요청을 실패 처리하지 않습니다. 일치하는 항목이 없는 선택은 빈 작업(`total` 0)으로 완료되며, 이는 일괄 삭제 endpoint와 동일한 규칙입니다.",
        "operationId": "toggle_businesses_aml_monitoring",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "set_aml_monitoring",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "AML Ongoing Monitoring"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "is_enabled"
                ],
                "description": "`vendor_data_list`, `didit_internal_id_list` 또는 둘 다를 사용하여 기업을 선택합니다(두 목록은 OR 조건으로 결합됨). 두 목록을 합쳐 요청당 최대 1,000개의 식별자까지 가능합니다.",
                "properties": {
                  "is_enabled": {
                    "type": "boolean",
                    "description": "모니터링을 활성화하려면 true, 비활성화하려면 false입니다."
                  },
                  "estimate_only": {
                    "type": "boolean",
                    "default": false,
                    "description": "true인 경우, 예상 비용을 반환하며 쓰기 작업(스크리닝, 결제, 작업)을 수행하지 않습니다."
                  },
                  "vendor_data_list": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "상태를 전환할 기업들의 귀하 고유 식별자 목록이며, 전송된 내용과 정확히 일치합니다."
                  },
                  "didit_internal_id_list": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "토글할 기업의 Didit 내부 ID입니다. 생성, 조회 및 목록 endpoint에서 반환된 `didit_internal_id`입니다."
                  }
                }
              },
              "examples": {
                "Estimate first": {
                  "summary": "쓰기 작업 없이 비용 미리보기",
                  "value": {
                    "is_enabled": true,
                    "estimate_only": true,
                    "vendor_data_list": [
                      "company-123",
                      "company-456"
                    ]
                  }
                },
                "Enable": {
                  "summary": "기업 2곳에 대한 모니터링 활성화",
                  "value": {
                    "is_enabled": true,
                    "vendor_data_list": [
                      "company-123",
                      "company-456"
                    ]
                  }
                },
                "Disable": {
                  "summary": "Didit 내부 id로 모니터링 비활성화",
                  "value": {
                    "is_enabled": false,
                    "didit_internal_id_list": [
                      "3f1c0d3e-8f0a-4c2e-9a3d-9b1f5f4a2c11"
                    ]
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/businesses/aml-monitoring/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"is_enabled\": true, \"vendor_data_list\": [\"company-123\", \"company-456\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.set_aml_monitoring(\n    is_enabled=True,\n    estimate_only=True,\n    vendor_data_list=[\"company-123\", \"company-456\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.setAmlMonitoring({\n  is_enabled: true,\n  estimate_only: true,\n  vendor_data_list: [\"company-123\", \"company-456\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.SetAMLMonitoring(ctx, didit.BusinessesSetAMLMonitoringParams{\n\tIsEnabled:      true,\n\tEstimateOnly:   didit.Bool(true),\n\tVendorDataList: didit.Some([]string{\"company-123\", \"company-456\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.BusinessesSetAmlMonitoringParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().setAmlMonitoring(BusinessesSetAmlMonitoringParams.builder()\n        .isEnabled(true)\n        .estimateOnly(true)\n        .vendorDataList(List.of(\"company-123\", \"company-456\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->businesses->setAmlMonitoring([\n    'is_enabled' => true,\n    'estimate_only' => true,\n    'vendor_data_list' => ['company-123', 'company-456'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.set_aml_monitoring(\n  is_enabled: true,\n  estimate_only: true,\n  vendor_data_list: [\"company-123\", \"company-456\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.SetAmlMonitoringAsync(new BusinessesSetAmlMonitoringParams\n{\n    IsEnabled = true,\n    EstimateOnly = true,\n    VendorDataList = new string[] { \"company-123\", \"company-456\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "견적(`estimate_only`가 true인 경우) 또는 인라인으로 처리된 선택 항목에 대한 완료된 작업입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AMLMonitoringToggleResult"
                }
              }
            }
          },
          "202": {
            "description": "대규모 선택 항목은 백그라운드에서 실행됩니다. `job_id`로 작업 endpoint를 폴링하세요. 프로필이 처리됨에 따라 `results`가 채워집니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AMLMonitoringJob"
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류: `is_enabled`가 누락되었거나, 선택자가 없거나, 두 목록을 합쳐 식별자가 1000개를 초과합니다."
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "이 선택 항목에 대한 모니터링을 활성화하기 위한 잔액이 부족합니다. 적절한 금액을 충전할 수 있도록 응답에 `estimate`가 포함됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "estimate": {
                      "type": "object",
                      "description": "예상 비용입니다. estimate_only가 true인 경우 직접 반환됩니다(아무것도 기록되지 않음).",
                      "properties": {
                        "users_total": {
                          "type": "integer",
                          "description": "선택 조건과 일치하는 프로필 수입니다."
                        },
                        "already_enabled": {
                          "type": "integer",
                          "description": "이미 모니터링 중인 프로필(활성화 시 수행할 작업 없음. 비활성화 시 해제되는 대상임)."
                        },
                        "with_existing_aml": {
                          "type": "integer",
                          "description": "기존 AML 스크리닝이 모니터링 상태로 전환될 프로필 수(신규 스크리닝 없음)."
                        },
                        "needing_screening": {
                          "type": "integer",
                          "description": "AML 스크리닝 이력이 없어 먼저 스크리닝을 진행할 프로필 수(일반 AML 스크리닝으로 청구됨)."
                        },
                        "skipped_no_identity_data": {
                          "type": "integer",
                          "description": "신원 데이터가 누락되어 스크리닝할 수 없는 프로필 수입니다."
                        },
                        "skipped_blocked": {
                          "type": "integer",
                          "description": "건너뛸 차단된 사용자 수입니다(기업의 경우 항상 0)."
                        },
                        "estimated_screening_cost_usd": {
                          "type": "number",
                          "example": 0.2,
                          "description": "새 스크리닝의 일회성 비용입니다."
                        },
                        "estimated_annual_monitoring_cost_usd": {
                          "type": "number",
                          "example": 0.07,
                          "description": "모니터링 대상이 될 프로필의 연간 모니터링 비용입니다."
                        },
                        "balance_sufficient": {
                          "type": "boolean",
                          "description": "조직 잔액이 스크리닝과 첫해 모니터링 비용을 충당할 수 있는지 여부입니다."
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/aml-monitoring/jobs/{job_id}/": {
      "get": {
        "summary": "지속적인 AML 모니터링 작업 조회",
        "description": "`POST /v3/users/aml-monitoring/` 또는 `POST /v3/businesses/aml-monitoring/`에서 시작된 모니터링 토글 작업의 상태, 결과 카운터 및 레코드별 결과입니다. `status`가 `PENDING` 또는 `PROCESSING`인 동안 몇 초마다 폴링하십시오. `COMPLETED`가 되면 `results`가 완료됩니다.",
        "operationId": "get_aml_monitoring_job",
        "x-didit-sdk": {
          "resource": "aml_monitoring",
          "method": "retrieve_job",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "AML Ongoing Monitoring"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "토글 endpoint에서 반환된 `job_id`입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl 'https://verification.didit.me/v3/aml-monitoring/jobs/JOB_ID/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.aml_monitoring.retrieve_job(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.amlMonitoring.retrieveJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.AMLMonitoring.RetrieveJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.amlMonitoring().retrieveJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->amlMonitoring->retrieveJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.aml_monitoring.retrieve_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.AmlMonitoring.RetrieveJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "작업입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "PENDING",
                        "PROCESSING",
                        "COMPLETED",
                        "FAILED"
                      ]
                    },
                    "is_enabled": {
                      "type": "boolean",
                      "description": "작업이 모니터링을 활성화하면 true, 비활성화하면 false입니다."
                    },
                    "target_type": {
                      "type": "string",
                      "enum": [
                        "user",
                        "business"
                      ],
                      "description": "작업이 전환하는 프로필 패밀리입니다."
                    },
                    "total": {
                      "type": "integer",
                      "description": "작업이 처리하는 프로필 수입니다."
                    },
                    "processed": {
                      "type": "integer",
                      "description": "지금까지 처리된 프로필 수입니다."
                    },
                    "outcomes": {
                      "type": "object",
                      "description": "레코드별 결과 카운터입니다. 선택된 모든 프로필은 정확히 하나의 카운터에 해당하며, 암묵적으로 건너뛰는 프로필은 없습니다.",
                      "properties": {
                        "enabled": {
                          "type": "integer",
                          "description": "기존 AML 스크리닝에서 모니터링이 활성화되었습니다."
                        },
                        "screened_and_enabled": {
                          "type": "integer",
                          "description": "새로운 AML 스크리닝이 생성되었으며(청구됨) 모니터링이 활성화되었습니다."
                        },
                        "already_enabled": {
                          "type": "integer",
                          "description": "모니터링이 이미 활성화되어 있었으며, 변경된 사항이 없고 청구되지 않았습니다."
                        },
                        "disabled": {
                          "type": "integer",
                          "description": "프로필의 모든 AML 스크리닝에서 모니터링이 꺼졌습니다."
                        },
                        "skipped_no_identity_data": {
                          "type": "integer",
                          "description": "건너뜀: 프로필에 스크리닝에 필요한 성명, 생년월일, 국가(사용자) 또는 이름(기업)이 없습니다."
                        },
                        "skipped_blocked": {
                          "type": "integer",
                          "description": "건너뜀: 사용자가 차단되었습니다."
                        },
                        "skipped_sandbox": {
                          "type": "integer",
                          "description": "건너뜀: 샌드박스 애플리케이션으로 스크리닝이 생성되지 않습니다."
                        },
                        "failed_provider": {
                          "type": "integer",
                          "description": "스크리닝을 완료할 수 없습니다. 나중에 다시 시도하세요."
                        },
                        "failed_insufficient_balance": {
                          "type": "integer",
                          "description": "작업이 실행되는 동안 잔액이 소진되었습니다."
                        }
                      }
                    },
                    "results": {
                      "type": "array",
                      "description": "처리 순서에 따른 처리된 프로필당 항목 1개입니다. 작업이 실행되는 동안 증가하며 상태가 COMPLETED가 되면 완료됩니다. API를 통해 시작된 작업에 대해 기록되며, Business Console에서 시작된 작업은 카운터만 보고합니다.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "didit_internal_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "프로필의 Didit 내부 ID입니다."
                          },
                          "vendor_data": {
                            "type": "string",
                            "nullable": true,
                            "description": "프로필에 대한 귀하 고유의 식별자입니다."
                          },
                          "outcome": {
                            "type": "string",
                            "enum": [
                              "enabled",
                              "screened_and_enabled",
                              "already_enabled",
                              "disabled",
                              "skipped_no_identity_data",
                              "skipped_blocked",
                              "skipped_sandbox",
                              "failed_provider",
                              "failed_insufficient_balance"
                            ]
                          }
                        }
                      }
                    },
                    "error": {
                      "type": "string",
                      "nullable": true,
                      "description": "상태가 FAILED일 때의 일반 실패 메시지입니다. 자세한 원인은 플랫폼 측에 보관됩니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "completed_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "404": {
            "description": "이 애플리케이션에 해당 작업이 없습니다."
          }
        }
      }
    },
    "/v3/users/{vendor_data}/update-status/": {
      "patch": {
        "summary": "사용자 상태 업데이트",
        "description": "사용자의 수명 주기 `status`만 전환합니다: `ACTIVE`, `FLAGGED` 또는 `BLOCKED`(세션 상태 아님). `BLOCKED`는 `vendor_data`를 시스템 차단 목록에 추가하며, `BLOCKED`에서 다른 상태로 변경하면 해당 항목이 제거됩니다. 각 변경 사항은 사용자의 `STATUS_CHANGED` 활동으로 기록되며, 선택 사항인 `reason`은 `comment`로 기록됩니다. 현재 상태를 그대로 전송하면 아무것도 변경되지 않으며 `reason`도 기록되지 않습니다. `user.status.updated` webhook에는 `reason`이 포함되지 않습니다.",
        "operationId": "update_user_status",
        "x-didit-sdk": {
          "resource": "users",
          "method": "update_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "귀하가 지정한 사용자의 고유 식별자입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/EntityStatusUpdateRequest"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "reason": {
                        "type": "string",
                        "nullable": true,
                        "maxLength": 1000,
                        "description": "상태가 변경된 이유입니다. 상태가 실제로 변경될 때만 사용자 활동(`comments[].comment` 및 Business Console의 **Activity**)의 상태 변경 항목에 기록됩니다. webhook에는 포함되지 않습니다."
                      }
                    }
                  }
                ]
              },
              "examples": {
                "Activate": {
                  "summary": "사용자 재활성화",
                  "value": {
                    "status": "ACTIVE"
                  }
                },
                "Flag": {
                  "summary": "검토를 위해 사용자 플래그 지정",
                  "value": {
                    "status": "FLAGGED"
                  }
                },
                "Block": {
                  "summary": "해당 사용자 차단(시스템 차단 목록에 추가)",
                  "value": {
                    "status": "BLOCKED"
                  }
                },
                "Block with reason": {
                  "summary": "해당 사용자 차단 및 사유 기록",
                  "value": {
                    "status": "BLOCKED",
                    "reason": "Chargeback fraud pattern confirmed"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/users/user-abc-123/update-status/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"status\": \"BLOCKED\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.update_status(\n    \"user-123\",\n    status=\"ACTIVE\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.updateStatus(\"user-123\", {\n  status: \"ACTIVE\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.UpdateStatus(ctx, \"user-123\", didit.UsersUpdateStatusParams{\n\tStatus: \"ACTIVE\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.EntityStatusUpdateRequest;\nimport me.didit.types.UsersUpdateStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().updateStatus(\"user-123\", UsersUpdateStatusParams.builder()\n        .status(EntityStatusUpdateRequest.Status.of(\"ACTIVE\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->users->updateStatus('user-123', [\n    'status' => 'ACTIVE',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.update_status(\n  \"user-123\",\n  status: \"ACTIVE\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.UpdateStatusAsync(\"user-123\", new UsersUpdateStatusParams\n{\n    Status = \"ACTIVE\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "사용자 상태가 업데이트되었습니다. 전체 사용자 레코드가 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDetailItem"
                },
                "examples": {
                  "Blocked": {
                    "value": {
                      "didit_internal_id": "f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418",
                      "vendor_data": "user-abc-123",
                      "display_name": null,
                      "full_name": "John Michael Doe",
                      "date_of_birth": "1990-05-15",
                      "effective_name": "John Michael Doe",
                      "status": "BLOCKED",
                      "metadata": {
                        "tier": "premium",
                        "source": "website"
                      },
                      "portrait_image_url": "https://<media-host>/...",
                      "session_count": 3,
                      "approved_count": 2,
                      "declined_count": 0,
                      "in_review_count": 1,
                      "issuing_states": [
                        "USA"
                      ],
                      "approved_emails": [
                        "john@example.com"
                      ],
                      "approved_phones": [
                        "+14155551234"
                      ],
                      "features": {
                        "ID_VERIFICATION": "Approved",
                        "LIVENESS": "Approved",
                        "FACE_MATCH": "Approved",
                        "AML": "Approved"
                      },
                      "features_list": [
                        {
                          "feature": "ID_VERIFICATION",
                          "status": "Approved"
                        },
                        {
                          "feature": "LIVENESS",
                          "status": "Approved"
                        },
                        {
                          "feature": "FACE_MATCH",
                          "status": "Approved"
                        },
                        {
                          "feature": "AML",
                          "status": "Approved"
                        }
                      ],
                      "last_session_at": "2025-06-15T10:30:00Z",
                      "last_activity_at": "2025-06-15T10:30:00Z",
                      "first_session_at": "2025-06-01T08:00:00Z",
                      "tags": [
                        {
                          "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                          "tag": {
                            "uuid": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
                            "name": "VIP",
                            "color": "#2567FF",
                            "description": null,
                            "source": "custom",
                            "created_at": "2025-05-01T09:00:00Z",
                            "updated_at": "2025-05-01T09:00:00Z"
                          },
                          "added_by_email": "analyst@acme.com",
                          "added_by_name": "Jane Analyst",
                          "created_at": "2025-06-02T11:00:00Z"
                        }
                      ],
                      "comments": [
                        {
                          "uuid": "c1111111-2222-4333-8444-555555555555",
                          "comment_type": "STATUS_CHANGED",
                          "comment": "Chargeback fraud pattern confirmed",
                          "actor_email": null,
                          "actor_name": null,
                          "previous_status": "ACTIVE",
                          "new_status": "BLOCKED",
                          "previous_value": null,
                          "new_value": null,
                          "changed_fields": [],
                          "metadata": null,
                          "mentioned_emails": [],
                          "created_at": "2025-06-15T10:30:00Z"
                        }
                      ],
                      "created_at": "2025-06-01T08:00:00Z",
                      "updated_at": "2025-06-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`status`가 누락되었거나 유효하지 않습니다. 또는 `reason`이 1000자를 초과합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing status": {
                    "value": {
                      "status": [
                        "This field is required."
                      ]
                    }
                  },
                  "Bad status": {
                    "value": {
                      "status": [
                        "Invalid status. Valid options are: ACTIVE, FLAGGED, BLOCKED"
                      ]
                    }
                  },
                  "Reason too long": {
                    "value": {
                      "reason": [
                        "Ensure this field has no more than 1000 characters."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "자격 증명이 제공되지 않았습니다. `x-api-key` 헤더(또는 `Authorization: Bearer` token)가 없는 `/v3/users/*` 경로에 대한 요청은 API에 도달하기 전에 인증 미들웨어에 의해 거부됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "키가 이 애플리케이션의 사용자를 업데이트할 수 없습니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "제공된 `vendor_data`를 가진 (삭제되지 않은) 사용자가 이 애플리케이션에 존재하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/businesses/create/": {
      "post": {
        "summary": "기업 생성",
        "description": "KYB 세션 *없이* [기업](/entities/businesses)을 사전 생성합니다. 모든 필드는 선택 사항이지만, `vendor_data`는 항상 전송해야 합니다. 이 값이 없으면 해당 레코드를 세션이나 거래에 연결할 수 없습니다. 제공 시 `vendor_data`는 삭제되지 않은 기업 간에 고유해야 합니다(정확히 일치해야 하며, 충돌 시 400 반환). 멱등성이 적용되지 않습니다.",
        "operationId": "create_business",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Businesses"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "vendor_data": {
                    "type": "string",
                    "nullable": true,
                    "description": "귀하가 지정한 해당 기업의 고유 식별자입니다(자유 형식 문자열, UUID 아님). 선택 사항이지만 적극 권장됩니다. 제공되는 경우 해당 애플리케이션의 삭제되지 않은 기업 간에 고유해야 하며, 전송된 값과 정확히 일치해야 합니다."
                  },
                  "display_name": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 255,
                    "description": "콘솔에 표시되는 친숙한 표시 이름입니다(UI 표시 시 `legal_name`보다 우선 적용됨)."
                  },
                  "legal_name": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 255,
                    "description": "기업의 공식 법인명입니다."
                  },
                  "registration_number": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 100,
                    "description": "기업 등록번호 또는 법인 설립 번호입니다."
                  },
                  "country_code": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 10,
                    "description": "설립 국가(ISO 3166-1 alpha-2, 예: `GB`, `US`)."
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "ACTIVE",
                      "FLAGGED",
                      "BLOCKED"
                    ],
                    "default": "ACTIVE",
                    "description": "초기 라이프사이클 상태입니다. 기본값은 `ACTIVE`입니다."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "기업에 연결하는 임의의 JSON 객체입니다. 기본값은 `{}`입니다."
                  }
                }
              },
              "examples": {
                "Basic": {
                  "summary": "권장 최소값",
                  "value": {
                    "vendor_data": "company-456",
                    "legal_name": "New Corp Ltd",
                    "country_code": "US"
                  }
                },
                "Full": {
                  "summary": "모든 필드",
                  "value": {
                    "vendor_data": "company-789",
                    "display_name": "New Corp",
                    "legal_name": "New Corp International Ltd",
                    "registration_number": "98765432",
                    "country_code": "DE",
                    "status": "ACTIVE",
                    "metadata": {
                      "industry": "fintech",
                      "tier": "enterprise"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/businesses/create/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"vendor_data\": \"company-456\", \"legal_name\": \"New Corp Ltd\", \"country_code\": \"US\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.create(\n    vendor_data=\"company-456\",\n    legal_name=\"New Corp Ltd\",\n    country_code=\"US\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.create({\n  vendor_data: \"company-456\",\n  legal_name: \"New Corp Ltd\",\n  country_code: \"US\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.Create(ctx, didit.BusinessesCreateParams{\n\tVendorData:  didit.String(\"company-456\"),\n\tLegalName:   didit.String(\"New Corp Ltd\"),\n\tCountryCode: didit.String(\"US\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BusinessesCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().create(BusinessesCreateParams.builder()\n        .vendorData(\"company-456\")\n        .legalName(\"New Corp Ltd\")\n        .countryCode(\"US\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->businesses->create([\n    'vendor_data' => 'company-456',\n    'legal_name' => 'New Corp Ltd',\n    'country_code' => 'US',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.create(\n  vendor_data: \"company-456\",\n  legal_name: \"New Corp Ltd\",\n  country_code: \"US\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.CreateAsync(new BusinessesCreateParams\n{\n    VendorData = \"company-456\",\n    LegalName = \"New Corp Ltd\",\n    CountryCode = \"US\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "기업이 생성되었습니다. 전체 기업 레코드가 반환됩니다(기업 조회와 동일한 형식).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessDetailItem"
                },
                "examples": {
                  "Created": {
                    "value": {
                      "didit_internal_id": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
                      "vendor_data": "company-456",
                      "display_name": null,
                      "legal_name": "New Corp Ltd",
                      "registration_number": null,
                      "country_code": "US",
                      "effective_name": "New Corp Ltd",
                      "status": "ACTIVE",
                      "session_count": 0,
                      "approved_count": 0,
                      "declined_count": 0,
                      "in_review_count": 0,
                      "features": {},
                      "features_list": [],
                      "last_session_at": null,
                      "last_activity_at": "2026-03-15T10:30:00Z",
                      "first_session_at": null,
                      "tags": [],
                      "created_at": "2026-03-15T10:30:00Z",
                      "metadata": {},
                      "updated_at": "2026-03-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 본문 — 일반적으로 중복된 `vendor_data`, 알 수 없는 `status`, 또는 잘못된 형식의 `metadata`입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Duplicate": {
                    "value": {
                      "vendor_data": [
                        "A business with this vendor_data already exists."
                      ]
                    }
                  },
                  "Bad status": {
                    "value": {
                      "status": [
                        "Invalid status. Valid options are: ACTIVE, FLAGGED, BLOCKED"
                      ]
                    }
                  },
                  "Bad metadata": {
                    "value": {
                      "metadata": [
                        "Metadata must be a JSON object."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 취소되었습니다. 또는 키가 이 애플리케이션에 대한 기업을 생성할 수 없습니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/users/create/": {
      "post": {
        "summary": "사용자 생성",
        "description": "인증 세션을 만들기 전에 또는 인증 세션 없이 `vendor_data`로 [사용자](/entities/users)를 생성합니다. `vendor_data`는 애플리케이션의 사용자 간에 고유해야 합니다(중복 시 `400` 반환). 멱등성이 없습니다.\n\n**연락처 세부 정보:** `email` 및 `phone_number`는 `metadata.contact`에 저장되며, `country`는 `metadata.address`에 저장됩니다. `full_name` 없이 `first_name` 또는 `last_name`을 전송하면 Didit이 이를 `full_name`으로 결합합니다.\n\n**인증 링크:** `send_verification_link: true`를 지정하면 Didit은 `workflow_id`에 해당하는 대상자의 인증 세션도 생성하고 `email`로 링크를 이메일 전송합니다. 해당 세션은 차단 목록 및 크레딧 잔액 확인과 같이 [세션 생성](/ko/sessions-api/create-session)과 동일한 검사를 실행합니다. 대상자와 세션은 함께 생성되거나 전혀 생성되지 않습니다. 검사 중 하나라도 실패하면 아무것도 기록되지 않고 이메일도 전송되지 않습니다. 응답의 `verification_link`는 세션을 설명하며, 링크를 요청하지 않은 경우 `null`입니다.\n\n**API 키 접근 권한:** 범위가 지정된 API 키에는 `users` 쓰기 권한이 필요합니다. `send_verification_link: true`인 경우 `sessions` 쓰기 권한도 필요하며, 그렇지 않으면 아무것도 기록되기 전에 호출에 `403`으로 응답합니다. 전체 접근 키에는 영향이 없습니다. [API 키](/ko/console/api-keys)를 참조하십시오.",
        "operationId": "create_user",
        "x-didit-sdk": {
          "resource": "users",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "vendor_data"
                ],
                "properties": {
                  "vendor_data": {
                    "type": "string",
                    "description": "귀하가 지정한 해당 사용자의 고유 식별자입니다(자유 형식 문자열, UUID 아님). 애플리케이션의 사용자 간에 고유해야 하며, 전송된 값과 정확히 일치해야 합니다."
                  },
                  "full_name": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 512,
                    "description": "사용자의 법적 성명입니다."
                  },
                  "display_name": {
                    "type": "string",
                    "nullable": true,
                    "description": "콘솔에 표시되는 친숙한 표시 이름입니다(UI 표시 시 `full_name`보다 우선 적용됨).",
                    "maxLength": 255
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "`YYYY-MM-DD` 형식의 생년월일입니다."
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "ACTIVE",
                      "FLAGGED",
                      "BLOCKED"
                    ],
                    "default": "ACTIVE",
                    "description": "초기 라이프사이클 상태입니다. 기본값은 `ACTIVE`입니다."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "사용자에게 연결하는 임의의 JSON 객체입니다. 기본값은 `{}`입니다."
                  },
                  "approved_emails": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "이 사용자에 대해 사전 신뢰된 이메일 주소 목록입니다(예: `[\"john@example.com\"]`)."
                  },
                  "approved_phones": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "이 사용자에 대해 사전 신뢰된 전화번호 목록입니다(예: `[\"+14155551234\"]`)."
                  },
                  "issuing_states": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "사전 기록된 발급 국가(ISO 3166-1 alpha-3) 목록입니다(예: `[\"USA\"]`)."
                  },
                  "first_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "이름. `full_name`을 전송하지 않으면 Didit은 `first_name`과 `last_name`을 공백으로 결합하여 `full_name`으로 만듭니다. 별도의 필드로 반환되지 않습니다."
                  },
                  "last_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "성. `full_name`이 전송되지 않은 경우 `first_name`과 결합되어 `full_name`이 됩니다. 별도의 필드로 반환되지 않습니다."
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "`metadata.contact.email`에 저장되는 연락처 이메일입니다(`metadata.contact` 내에 전송한 `email`을 대체함). `send_verification_link`가 `true`인 경우 필수이며, 인증 링크가 이 주소로 전송됩니다. `metadata.contact`가 JSON 객체가 아닌 경우, 호출 시 이 필드에 대해 `400`으로 응답합니다."
                  },
                  "phone_number": {
                    "type": "string",
                    "maxLength": 32,
                    "description": "`metadata.contact.phone_number`에 저장되는 연락처 전화번호입니다. `metadata.contact`가 JSON 객체가 아닌 경우 이 필드에 대해 호출 시 `400`을 반환합니다."
                  },
                  "country": {
                    "type": "string",
                    "maxLength": 3,
                    "description": "ISO 3166 코드(alpha-2 또는 alpha-3, 예: `ES` 또는 `ESP`)로 표현된 국가입니다. `metadata.address.country`에 대문자로 저장됩니다. `metadata.address`가 JSON 객체가 아닌 경우, 호출 시 이 필드에 대해 `400`을 반환합니다."
                  },
                  "send_verification_link": {
                    "type": "boolean",
                    "default": false,
                    "description": "`true`인 경우 Didit은 해당 사용자를 위해 `workflow_id`에 대한 인증 세션을 생성하고 `email` 주소로 링크를 이메일로 전송합니다. `email` 및 `workflow_id`가 필요합니다. 범위가 지정된 API 키에는 `sessions` 쓰기 권한도 필요합니다."
                  },
                  "workflow_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "인증 세션의 워크플로입니다. `send_verification_link`가 `true`일 때 필수입니다. 개인을 인증해야 하며, 기업 확인(KYB) 워크플로는 거부됩니다. 그렇지 않은 경우 무시됩니다."
                  },
                  "language": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "인증 이메일 언어로, [지원 언어](/ko/integration/supported-languages) 코드 형태입니다. 생략 시 영어로 설정됩니다. `send_verification_link`가 `true`가 아니면 무시됩니다."
                  }
                }
              },
              "examples": {
                "Basic": {
                  "summary": "기본 정보로 생성",
                  "value": {
                    "vendor_data": "user-abc-123",
                    "full_name": "John Doe"
                  }
                },
                "Full": {
                  "summary": "모든 필드",
                  "value": {
                    "vendor_data": "user-abc-456",
                    "full_name": "Jane Smith",
                    "display_name": "Jane S.",
                    "date_of_birth": "1990-05-15",
                    "status": "ACTIVE",
                    "metadata": {
                      "tier": "premium",
                      "source": "api"
                    },
                    "approved_emails": [
                      "jane@example.com"
                    ]
                  }
                },
                "Contact details": {
                  "summary": "이름, 이메일, 전화번호 및 국가",
                  "value": {
                    "vendor_data": "user-abc-789",
                    "first_name": "Julia",
                    "last_name": "Martin",
                    "email": "julia.martin@example.com",
                    "phone_number": "+34600000000",
                    "country": "ES"
                  }
                },
                "With verification link": {
                  "summary": "사람을 생성하고 인증 링크를 이메일로 전송",
                  "value": {
                    "vendor_data": "user-abc-789",
                    "first_name": "Julia",
                    "last_name": "Martin",
                    "email": "julia.martin@example.com",
                    "send_verification_link": true,
                    "workflow_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "language": "es"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/users/create/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"vendor_data\": \"user-abc-123\", \"full_name\": \"John Doe\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.create(\n    vendor_data=\"user-abc-123\",\n    full_name=\"John Doe\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.create({\n  vendor_data: \"user-abc-123\",\n  full_name: \"John Doe\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.Create(ctx, didit.UsersCreateParams{\n\tVendorData: \"user-abc-123\",\n\tFullName:   didit.String(\"John Doe\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.UsersCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().create(UsersCreateParams.builder()\n        .vendorData(\"user-abc-123\")\n        .fullName(\"John Doe\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->users->create([\n    'vendor_data' => 'user-abc-123',\n    'full_name' => 'John Doe',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.create(\n  vendor_data: \"user-abc-123\",\n  full_name: \"John Doe\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.CreateAsync(new UsersCreateParams\n{\n    VendorData = \"user-abc-123\",\n    FullName = \"John Doe\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "사용자가 생성되었습니다. 전체 사용자 레코드(Get User와 동일한 형식)와 함께 `verification_link`가 반환됩니다. `send_verification_link`가 `true`인 경우 Didit이 이메일로 전송한 인증 세션이며, 그렇지 않으면 `null`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/UserDetailItem"
                    },
                    {
                      "type": "object",
                      "required": [
                        "verification_link"
                      ],
                      "properties": {
                        "verification_link": {
                          "type": "object",
                          "nullable": true,
                          "description": "Didit이 생성하여 해당 사용자에게 이메일로 전송한 인증 세션입니다. 항상 존재하며, `send_verification_link`가 `true`가 아닌 경우 `null`입니다.",
                          "required": [
                            "session_id",
                            "session_number",
                            "status",
                            "url",
                            "workflow_id",
                            "email"
                          ],
                          "properties": {
                            "session_id": {
                              "type": "string",
                              "format": "uuid",
                              "description": "인증 세션의 ID입니다."
                            },
                            "session_number": {
                              "type": "integer",
                              "description": "애플리케이션 내 세션의 순차 번호입니다."
                            },
                            "status": {
                              "type": "string",
                              "description": "세션의 상태로, 방금 생성된 세션의 경우 `Not Started`입니다."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri",
                              "description": "Didit이 해당 사용자에게 이메일로 전송한 인증 링크입니다."
                            },
                            "workflow_id": {
                              "type": "string",
                              "format": "uuid",
                              "nullable": true,
                              "description": "세션에서 실행되는 워크플로입니다."
                            },
                            "email": {
                              "type": "string",
                              "format": "email",
                              "description": "링크가 전송된 주소입니다."
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "Created": {
                    "value": {
                      "didit_internal_id": "f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418",
                      "vendor_data": "user-abc-123",
                      "display_name": null,
                      "full_name": "John Doe",
                      "date_of_birth": null,
                      "effective_name": "John Doe",
                      "status": "ACTIVE",
                      "metadata": {},
                      "portrait_image_url": null,
                      "session_count": 0,
                      "approved_count": 0,
                      "declined_count": 0,
                      "in_review_count": 0,
                      "issuing_states": [],
                      "approved_emails": [],
                      "approved_phones": [],
                      "features": {},
                      "features_list": [],
                      "last_session_at": null,
                      "last_activity_at": "2025-06-15T10:30:00Z",
                      "first_session_at": null,
                      "tags": [],
                      "comments": [],
                      "created_at": "2025-06-15T10:30:00Z",
                      "updated_at": "2025-06-15T10:30:00Z",
                      "verification_link": null
                    }
                  },
                  "Created with verification link": {
                    "value": {
                      "didit_internal_id": "9b2f6c1e-3d4a-4e5f-8a7b-1c2d3e4f5a6b",
                      "vendor_data": "user-abc-789",
                      "display_name": null,
                      "full_name": "Julia Martin",
                      "date_of_birth": null,
                      "effective_name": "Julia Martin",
                      "status": "ACTIVE",
                      "metadata": {
                        "contact": {
                          "email": "julia.martin@example.com"
                        }
                      },
                      "portrait_image_url": null,
                      "session_count": 1,
                      "approved_count": 0,
                      "declined_count": 0,
                      "in_review_count": 0,
                      "issuing_states": [],
                      "approved_emails": [],
                      "approved_phones": [],
                      "features": {},
                      "features_list": [],
                      "last_session_at": "2025-06-15T10:30:00Z",
                      "last_activity_at": "2025-06-15T10:30:00Z",
                      "first_session_at": "2025-06-15T10:30:00Z",
                      "tags": [],
                      "comments": [],
                      "created_at": "2025-06-15T10:30:00Z",
                      "updated_at": "2025-06-15T10:30:00Z",
                      "verification_link": {
                        "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa7",
                        "session_number": 43762,
                        "status": "Not Started",
                        "url": "https://verify.didit.me/en/session/3FaJ9wLqX2Mz",
                        "workflow_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                        "email": "julia.martin@example.com"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "필드별로 구분된 유효하지 않은 본문: 일반적으로 중복된 `vendor_data`, 필수 필드 누락 또는 잘못된 형식의 값입니다. `send_verification_link: true`인 경우 `email` 또는 `workflow_id` 누락, 알 수 없거나 기업 확인(KYB) 워크플로, 지원되지 않는 `language`(`contact_details.email_lang` 키), 차단 목록에 포함된 `vendor_data`, 또는 세션을 시작하기에 크레딧이 부족한 경우도 포함됩니다. 아무것도 기록되지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Duplicate": {
                    "value": {
                      "vendor_data": [
                        "A user with this vendor_data already exists."
                      ]
                    }
                  },
                  "Missing vendor_data": {
                    "value": {
                      "vendor_data": [
                        "This field is required."
                      ]
                    }
                  },
                  "Bad metadata": {
                    "value": {
                      "metadata": [
                        "Metadata must be a JSON object."
                      ]
                    }
                  },
                  "Bad status": {
                    "value": {
                      "status": [
                        "Invalid status. Valid options are: ACTIVE, FLAGGED, BLOCKED"
                      ]
                    }
                  },
                  "Bad country": {
                    "value": {
                      "country": [
                        "Use an ISO 3166 country code, like ES or ESP."
                      ]
                    }
                  },
                  "Contact not an object": {
                    "value": {
                      "email": [
                        "metadata.contact must be a JSON object to store this value."
                      ]
                    }
                  },
                  "Address not an object": {
                    "value": {
                      "country": [
                        "metadata.address must be a JSON object to store this value."
                      ]
                    }
                  },
                  "Link without email or workflow": {
                    "value": {
                      "email": [
                        "An email address is required to send a verification link."
                      ],
                      "workflow_id": [
                        "Pick the workflow to send a verification link for."
                      ]
                    }
                  },
                  "Unknown workflow": {
                    "value": {
                      "workflow_id": [
                        "Invalid workflow_id."
                      ]
                    }
                  },
                  "Business workflow": {
                    "value": {
                      "workflow_id": [
                        "This workflow verifies a business. Pick a workflow that verifies a person to send them a verification link."
                      ]
                    }
                  },
                  "Blocklisted vendor_data": {
                    "value": {
                      "vendor_data": "This user or business has been blocked and cannot create new verification sessions."
                    }
                  },
                  "Insufficient credits": {
                    "value": {
                      "detail": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "자격 증명이 제공되지 않았습니다. `x-api-key` 헤더(또는 `Authorization: Bearer` token)가 없는 `/v3/users/*` 경로에 대한 요청은 API에 도달하기 전에 인증 미들웨어에 의해 거부됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "유효하지 않거나 해지된 API 키이거나, 키에 이 애플리케이션의 사용자를 생성할 권한이 없습니다. 범위가 지정된 API 키에는 `users` 쓰기 권한이 필요하며, `send_verification_link`가 `true`인 경우 `sessions` 쓰기 권한도 필요합니다. 아무것도 기록되지 않습니다. 키가 누락되면 `403`을 반환하며, 잘못되었거나 해지되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "No sessions write": {
                    "summary": "스코프 지정 키가 sessions 쓰기 권한 없이 인증 링크를 요청함",
                    "value": {
                      "detail": "This API key has no write access to sessions."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 `Retry-After`에 지정된 시간 간격이 지난 뒤 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/vendor-users/by-id/{didit_internal_id}/faces/upload/": {
      "post": {
        "summary": "사용자 얼굴 업로드",
        "description": "신뢰할 수 있는 가져온 얼굴 이미지를 기존 사용자 프로필에 첨부합니다. `vendor_data`로 사용자를 생성하거나 조회한 후 해당 `didit_internal_id`를 확인하여 이 기능을 사용하십시오. 업로드된 얼굴은 사용자 프로필에 저장되며 중복 감지 및 얼굴 검색을 위해 색인화됩니다. 얼굴 차단 목록에는 추가되지 않습니다.",
        "operationId": "upload_user_face",
        "x-didit-sdk": {
          "resource": "users",
          "method": "upload_face",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션을 소유한 조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "사용자 프로필을 소유한 애플리케이션 UUID입니다."
          },
          {
            "name": "didit_internal_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "`GET /v3/users/{vendor_data}/` 및 `POST /v3/users/create/`에서 `didit_internal_id`로 반환되는 Didit 내부 사용자 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "image"
                ],
                "properties": {
                  "image": {
                    "type": "string",
                    "format": "byte",
                    "description": "원시 base64 인코딩된 JPG 또는 PNG 얼굴 이미지입니다. `data:image/...;base64,` 접두사를 포함하지 마세요. 디코딩된 최대 크기: 2 MB."
                  },
                  "comment": {
                    "type": "string",
                    "description": "업로드된 얼굴에 대해 운영자에게 표시되는 선택적 메모입니다.",
                    "default": ""
                  }
                }
              },
              "examples": {
                "Imported face": {
                  "summary": "이전 공급업체에서 가져온 얼굴을 첨부합니다",
                  "value": {
                    "image": "/9j/4AAQSkZJRgABAQEA...",
                    "comment": "Imported from previous KYC provider"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/vendor-users/by-id/f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418/faces/upload/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"image\": \"/9j/4AAQSkZJRgABAQEA...\", \"comment\": \"Imported from previous KYC provider\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.users.upload_face(\n    \"11111111-2222-3333-4444-555555555555\",\n    image=\"/9j/4AAQSkZJRgABAQEA...\",\n    comment=\"Imported from previous KYC provider\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.users.uploadFace(\"11111111-2222-3333-4444-555555555555\", {\n  image: \"/9j/4AAQSkZJRgABAQEA...\",\n  comment: \"Imported from previous KYC provider\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Users.UploadFace(ctx, \"11111111-2222-3333-4444-555555555555\", didit.UsersUploadFaceParams{\n\tImage:   \"/9j/4AAQSkZJRgABAQEA...\",\n\tComment: didit.String(\"Imported from previous KYC provider\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.UsersUploadFaceParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.users().uploadFace(\"11111111-2222-3333-4444-555555555555\", UsersUploadFaceParams.builder()\n        .image(\"/9j/4AAQSkZJRgABAQEA...\")\n        .comment(\"Imported from previous KYC provider\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->users->uploadFace('11111111-2222-3333-4444-555555555555', [\n    'image' => '/9j/4AAQSkZJRgABAQEA...',\n    'comment' => 'Imported from previous KYC provider',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.users.upload_face(\n  \"11111111-2222-3333-4444-555555555555\",\n  image: \"/9j/4AAQSkZJRgABAQEA...\",\n  comment: \"Imported from previous KYC provider\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Users.UploadFaceAsync(\"11111111-2222-3333-4444-555555555555\", new UsersUploadFaceParams\n{\n    Image = \"/9j/4AAQSkZJRgABAQEA...\",\n    Comment = \"Imported from previous KYC provider\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "얼굴이 업로드되어 사용자 프로필에 첨부되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "uuid",
                    "image_url",
                    "comment",
                    "uploaded_by",
                    "created_at"
                  ],
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "업로드된 사용자 얼굴 레코드의 UUID입니다."
                    },
                    "image_url": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "업로드된 얼굴 이미지의 서명된 URL입니다."
                    },
                    "comment": {
                      "type": "string",
                      "nullable": true,
                      "description": "얼굴을 업로드할 때 제공된 코멘트입니다."
                    },
                    "uploaded_by": {
                      "type": "string",
                      "nullable": true,
                      "description": "가능한 경우 업로더의 이메일 또는 행위자 식별자입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "업로드 타임스탬프입니다."
                    }
                  }
                },
                "examples": {
                  "Uploaded": {
                    "value": {
                      "uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                      "image_url": "https://signed-url.example/face.jpg",
                      "comment": "Imported from previous KYC provider",
                      "uploaded_by": "api",
                      "created_at": "2026-05-18T12:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 요청 본문 또는 이미지입니다. 일반적인 원인: 유효하지 않은 base64, 유효하지 않은 이미지, 감지 가능한 얼굴 없음, 2 MB 초과 이미지, 임베딩 누락, 또는 사용자가 이미 5개의 업로드된 얼굴을 보유한 경우입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "No face": {
                    "value": {
                      "image": "No face detected in the image. Please upload a clear photo with a visible face."
                    }
                  },
                  "Too many faces": {
                    "value": {
                      "detail": "Maximum of 5 faces per user reached."
                    }
                  },
                  "Too large": {
                    "value": {
                      "image": "Image exceeds maximum size of 2 MB."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing key": {
                    "value": {
                      "detail": "Authentication credentials were not provided."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 유효하지만 이 애플리케이션의 사용자 프로필을 작성할 수 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 해당 `didit_internal_id`를 가진 사용자가 존재하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과. 대기 후 재시도하세요.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/update-data/": {
      "patch": {
        "summary": "인증 세션의 신분증 문서에서 추출한 KYC 데이터 업데이트",
        "description": "인증이 완료된 후 사용자의 신분증 문서에서 추출된(OCR / NFC) 신원 필드(잘못 읽은 이름, 날짜, 문서 번호 등)를 수정합니다. 주로 자체 백오피스에서 작업하는 컴플라이언스 분석가 또는 자동화된 대사 작업에서 호출합니다. 본문의 모든 필드는 선택 사항입니다. 전송한 키만 기록되며, 그 외의 모든 항목은 변경되지 않은 상태로 유지됩니다(`PATCH` 방식).\n\n세션은 반드시 귀하의 애플리케이션에 속해야 하며 `Approved`, `Declined`, `In Review` 또는 `Kyc Expired` 상태여야 합니다. 다른 상태(예: 여전히 `In Progress`)에 있는 세션은 `404`와 함께 `\"No Session matches the given query.\"`를 반환합니다. 이는 알 수 없거나 삭제된 `sessionId`에 대해 반환되는 `\"Not found.\"`와 구별됩니다. 또한 세션에는 신분증 인증(KYC) 기록이 포함되어 있어야 합니다. 워크플로에서 신분증 인증 단계를 실행하지 않은 세션은 `404`(`\"The session does not have a KYC.\"` )를 반환합니다. 신분증 인증 단계가 여러 개 포함된 그래프 워크플로의 경우 `node_id`(쿼리 파라미터 또는 본문 필드)를 통해 특정 단계를 지정하세요. 생략하면 가장 최근의 KYC 기록이 수정됩니다.\n\n두 개의 파생 필드는 호출할 때마다 다시 계산됩니다. `full_name`(`first_name` + `last_name` 기준) 및 `issuing_state_name`(`issuing_state` 기준)입니다. 자유 형식 텍스트인 `address`가 변경되면 서버에서 이를 다시 지오코딩하고 `parsed_address`를 새로 고칠 수도 있습니다(샌드박스 세션에서는 건너뜀). `extra_fields` 및 `parsed_address`는 완전히 대체되지 않고 키별로 병합됩니다. 삭제를 위한 `null` 처리 방식은 필드별 설명을 참조하세요.\n\n유효한 필드를 하나 이상 제출하면 제출된 값이 저장된 값과 동일하더라도 `data.updated` [webhook](/ko/integration/webhooks)(트리거 `manual_review`)이 실행됩니다. 값이 실제로 변경되면 이전 값과 새 값이 포함된 변경 필드를 기록하는 `KYC_DATA_UPDATED` 활동 항목이 세션의 `reviews`에 추가되며, 이는 [Get Decision](#get-/v3/session/-sessionId-/decision/) 및 콘솔 활동 타임라인에서 확인할 수 있습니다. 세션의 상태와 결정은 다시 평가되지 **않습니다**. 결과를 변경하려면 [Update Status](#patch-/v3/session/-sessionId-/update-status/)를 사용하세요. 빈 JSON 본문(`{}`)도 허용되며, webhook을 실행하지 않고 현재 KYC 데이터를 단순히 반환합니다.\n\nAPI 키 또는 콘솔 사용자 token을 사용할 수 있습니다. 어떤 방식이든 자격 증명에 `write:sessions` 권한이 필요합니다. 인증 및 권한 실패는 모두 `403`을 반환하며, 이 API는 절대로 `401`로 응답하지 않습니다. 자격 증명 확인 전에 세션 조회가 먼저 실행되므로 자격 증명이 없더라도 알 수 없는 `sessionId`의 경우 `404`를 반환합니다. 이 endpoint에는 API 키당 분당 10건의 전용 속도 제한이 적용되며(잘못된 요청도 포함됨), 분당 300건의 공유 쓰기 한도도 함께 적용됩니다.",
        "operationId": "patch_v3_session_update_data",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_data",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "추출된 문서 데이터를 수정할 사용자 인증(KYC) 세션의 UUID입니다. 기업(KYB) 세션 ID는 여기에서 유효하지 않습니다. 기업 데이터의 경우 [Update KYB Company Data](#patch-/v3/session/-sessionId-/kyb/-companyUuid-/update-data/)를 사용하십시오.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "여러 신분증 인증 단계가 포함된 그래프 워크플로에서 패치할 KYC 기록의 워크플로 그래프 노드입니다(`node_id` 본문 필드로도 허용됨). 생략하면 세션의 가장 최근 KYC 기록이 패치됩니다. 지정된 노드에 대한 KYC가 없으면 호출 시 `404`(`\"The session does not have a KYC for node '<node_id>'.\"`)가 반환됩니다.",
            "schema": {
              "type": "string",
              "example": "feature_ocr"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "모든 필드는 선택 사항입니다. 변경하려는 내용만 전송하십시오.",
                "properties": {
                  "document_type": {
                    "type": "string",
                    "description": "문서 유형 코드입니다. enum에 나열된 짧은 코드와 검증 전 서버 측에서 정규화되는 6개의 긴 형식 별칭(`Passport` → `P`, `Identity Card` → `ID`, `Driver's License` → `DL`, `Residence Permit` → `RP`, `Health Insurance Card` → `HIC`, `Tax Card` → `TC`)을 허용합니다. 그 외의 모든 값(대문자 `PASSPORT` 포함)은 `400`을 반환합니다.",
                    "enum": [
                      "P",
                      "DL",
                      "ID",
                      "RP",
                      "SSC",
                      "HIC",
                      "WP",
                      "TC",
                      "VISA",
                      "PSC",
                      "BC",
                      "OTHER"
                    ],
                    "nullable": true,
                    "example": "P"
                  },
                  "document_subtype": {
                    "type": "string",
                    "maxLength": 128,
                    "nullable": true,
                    "description": "등기부에서 가져온 문서 하위 유형이며, 등기부에서 지역 변형을 구분하는 경우 지역 접두사를 포함합니다."
                  },
                  "document_number": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "신분증에 인쇄된 문서 번호입니다.",
                    "example": "PAB123456"
                  },
                  "personal_number": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "문서에 기재되어 있는 경우 개인/국가 식별 번호(예: 여권의 스페인 DNI).",
                    "example": "99999999R"
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "`YYYY-MM-DD` 형식의 생년월일입니다. 다른 형식은 `400`을 반환합니다.",
                    "example": "1980-01-01"
                  },
                  "date_of_issue": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "`YYYY-MM-DD` 형식의 문서 발급일입니다."
                  },
                  "expiration_date": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "`YYYY-MM-DD` 형식의 문서 만료일입니다."
                  },
                  "issuing_state": {
                    "type": "string",
                    "nullable": true,
                    "description": "ISO 3166-1 alpha-3 코드 형식의 발급 국가입니다. 대소문자를 구분하지 않으며(`esp`는 `ESP`로 저장됨), [결정 조회](#get-/v3/session/-sessionId-/decision/)에 표시되는 사람이 읽을 수 있는 `issuing_state_name`은 이 값으로부터 다시 계산됩니다. 유효하지 않은 코드는 `400`을 반환합니다.",
                    "example": "ESP"
                  },
                  "first_name": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "이름. 저장된 `full_name`은 이 endpoint를 호출할 때마다 `first_name + ' ' + last_name`으로 다시 계산됩니다.",
                    "example": "Carmen"
                  },
                  "last_name": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "성(들). 재계산된 `full_name`에도 반영됩니다.",
                    "example": "Espanola Espanola"
                  },
                  "gender": {
                    "type": "string",
                    "enum": [
                      "M",
                      "F",
                      "U"
                    ],
                    "nullable": true,
                    "description": "문서에 인쇄된 성별: `M`(남성), `F`(여성) 또는 `U`(알 수 없음)입니다. `X`를 포함한 다른 값은 `400`을 반환합니다."
                  },
                  "address": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "문서에 인쇄된 그대로의 자유 텍스트 주소입니다. 이 값이 변경되고(비샌드박스 세션 전용) 구조화된 주소가 여전히 누락되었거나 불완전한 경우, 서버는 응답하기 전에 동기식으로 지오코딩을 다시 수행하며, 200 본문에는 갱신된 `parsed_address`가 이미 반영되어 있습니다. 재지오코딩을 수행하려면 KYC 레코드에 `issuing_state`도 있어야 합니다."
                  },
                  "place_of_birth": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "문서에 인쇄된 출생지입니다."
                  },
                  "nationality": {
                    "type": "string",
                    "maxLength": 32,
                    "nullable": true,
                    "description": "문서에 인쇄된 국적입니다. 최대 32자의 자유 텍스트이며, 일반적으로 ISO 3166-1 alpha-3 코드(예: `ESP`)이지만 해당 형식으로 유효성을 검증하지는 않습니다."
                  },
                  "marital_status": {
                    "type": "string",
                    "enum": [
                      "SINGLE",
                      "MARRIED",
                      "DIVORCED",
                      "WIDOWED",
                      "UNKNOWN"
                    ],
                    "description": "문서에 기재된 혼인 여부입니다. 다른 값은 `400`을 반환합니다."
                  },
                  "extra_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "nullable": true,
                    "description": "문서별 추가 필드(예: `blood_group`, `dl_categories`, `mrz_string`)에 대한 키별 재정의입니다. 키는 기존 재정의 맵에 병합됩니다. 키에 값을 지정하여 전송하면 해당 값이 설정되고, `null` 또는 `\"\"`로 전송하면 병합된 뷰에서 해당 키가 제거됩니다. 필드 전체를 `null`로 전송하면 이전에 적용된 모든 재정의가 지워집니다. JSON 객체여야 하며, 그렇지 않으면 `400`이 반환됩니다. 응답에는 항상 병합된 뷰(OCR로 추출된 값에 재정의가 적용된 결과)가 반환됩니다."
                  },
                  "parsed_address": {
                    "type": "object",
                    "nullable": true,
                    "description": "구조화된 주소입니다. 중첩된 키 중 `address_type`, `city`, `region`, `street_1`, `street_2`, `postal_code`, `country`만 허용되며, 다른 키는 `400`을 반환합니다. 키별 동작: 값이 있으면 해당 키를 설정하고, `null`이면 제거합니다. `formatted_address`는 서버 측에서 `street_1`, `street_2`, `city`, `region`, `postal_code`, `country`를 결합하여 다시 계산되어 응답에 반환되므로 직접 설정할 수 없습니다.",
                    "properties": {
                      "address_type": {
                        "type": "string",
                        "nullable": true,
                        "description": "자유 형식 주소 분류(예: `home`)입니다."
                      },
                      "city": {
                        "type": "string",
                        "nullable": true,
                        "example": "Madrid"
                      },
                      "region": {
                        "type": "string",
                        "nullable": true,
                        "description": "주 / 도 / 자치 지역입니다."
                      },
                      "street_1": {
                        "type": "string",
                        "nullable": true,
                        "example": "Avda de Madrid 34"
                      },
                      "street_2": {
                        "type": "string",
                        "nullable": true
                      },
                      "postal_code": {
                        "type": "string",
                        "nullable": true,
                        "example": "28013"
                      },
                      "country": {
                        "type": "string",
                        "nullable": true,
                        "description": "ISO 3166-1 alpha-2 국가 코드입니다. 소문자 입력은 대문자로 정규화되며, alpha-3 코드는 `400`으로 거부됩니다.",
                        "example": "ES"
                      }
                    }
                  }
                }
              },
              "examples": {
                "Correct name and DOB": {
                  "summary": "OCR로 잘못 인식된 성명, 생년월일, 구조화된 주소 수정",
                  "value": {
                    "first_name": "Carmen",
                    "last_name": "Espanola Espanola",
                    "date_of_birth": "1980-01-01",
                    "issuing_state": "ESP",
                    "marital_status": "MARRIED",
                    "extra_fields": {
                      "blood_group": "O+"
                    },
                    "parsed_address": {
                      "street_1": "Avda de Madrid 34",
                      "city": "Madrid",
                      "postal_code": "28013",
                      "country": "ES"
                    }
                  }
                },
                "Remove an extra field": {
                  "summary": "추가 필드 키 하나를 삭제하고 나머지는 유지",
                  "value": {
                    "extra_fields": {
                      "blood_group": null
                    }
                  }
                },
                "Long-form document type": {
                  "summary": "긴 형식의 별칭은 축약 코드로 정규화됩니다(여기서는 P).",
                  "value": {
                    "document_type": "Passport"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "KYC 데이터가 업데이트되었습니다. 제출한 필드뿐만 아니라 **전체 현재 KYC 레코드**(저장된 값이 포함된 업데이트 가능한 모든 필드, 병합된 `extra_fields` 및 현재 `parsed_address`)를 반환합니다. payload에 유효한 필드가 하나 이상 포함되어 있으면 `data.updated` webhook이 트리거됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "document_type": {
                      "type": "string",
                      "description": "문서 유형 코드입니다. enum에 나열된 짧은 코드와 검증 전 서버 측에서 정규화되는 6개의 긴 형식 별칭(`Passport` → `P`, `Identity Card` → `ID`, `Driver's License` → `DL`, `Residence Permit` → `RP`, `Health Insurance Card` → `HIC`, `Tax Card` → `TC`)을 허용합니다. 그 외의 모든 값(대문자 `PASSPORT` 포함)은 `400`을 반환합니다.",
                      "enum": [
                        "P",
                        "DL",
                        "ID",
                        "RP",
                        "SSC",
                        "HIC",
                        "WP",
                        "TC",
                        "VISA",
                        "PSC",
                        "BC",
                        "OTHER"
                      ],
                      "nullable": true,
                      "example": "P"
                    },
                    "document_subtype": {
                      "type": "string",
                      "maxLength": 128,
                      "nullable": true,
                      "description": "등기부에서 가져온 문서 하위 유형이며, 등기부에서 지역 변형을 구분하는 경우 지역 접두사를 포함합니다."
                    },
                    "document_number": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "신분증에 인쇄된 문서 번호입니다.",
                      "example": "PAB123456"
                    },
                    "personal_number": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "문서에 기재되어 있는 경우 개인/국가 식별 번호(예: 여권의 스페인 DNI).",
                      "example": "99999999R"
                    },
                    "date_of_birth": {
                      "type": "string",
                      "format": "date",
                      "nullable": true,
                      "description": "`YYYY-MM-DD` 형식의 생년월일입니다. 다른 형식은 `400`을 반환합니다.",
                      "example": "1980-01-01"
                    },
                    "date_of_issue": {
                      "type": "string",
                      "format": "date",
                      "nullable": true,
                      "description": "`YYYY-MM-DD` 형식의 문서 발급일입니다."
                    },
                    "expiration_date": {
                      "type": "string",
                      "format": "date",
                      "nullable": true,
                      "description": "`YYYY-MM-DD` 형식의 문서 만료일입니다."
                    },
                    "issuing_state": {
                      "type": "string",
                      "nullable": true,
                      "description": "ISO 3166-1 alpha-3 코드 형식의 발급 국가입니다. 대소문자를 구분하지 않으며(`esp`는 `ESP`로 저장됨), [결정 조회](#get-/v3/session/-sessionId-/decision/)에 표시되는 사람이 읽을 수 있는 `issuing_state_name`은 이 값으로부터 다시 계산됩니다. 유효하지 않은 코드는 `400`을 반환합니다.",
                      "example": "ESP"
                    },
                    "first_name": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "이름. 저장된 `full_name`은 이 endpoint를 호출할 때마다 `first_name + ' ' + last_name`으로 다시 계산됩니다.",
                      "example": "Carmen"
                    },
                    "last_name": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "성(들). 재계산된 `full_name`에도 반영됩니다.",
                      "example": "Espanola Espanola"
                    },
                    "gender": {
                      "type": "string",
                      "enum": [
                        "M",
                        "F",
                        "U"
                      ],
                      "nullable": true,
                      "description": "문서에 인쇄된 성별: `M`(남성), `F`(여성) 또는 `U`(알 수 없음)입니다. `X`를 포함한 다른 값은 `400`을 반환합니다."
                    },
                    "address": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "문서에 인쇄된 그대로의 자유 텍스트 주소입니다. 이 값이 변경되고(비샌드박스 세션 전용) 구조화된 주소가 여전히 누락되었거나 불완전한 경우, 서버는 동일한 요청의 백그라운드에서 지오코딩을 다시 수행하며 `parsed_address`를 지오코더 결과로 덮어쓸 수 있습니다."
                    },
                    "place_of_birth": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "문서에 인쇄된 출생지입니다."
                    },
                    "nationality": {
                      "type": "string",
                      "maxLength": 32,
                      "nullable": true,
                      "description": "문서에 인쇄된 국적입니다. 최대 32자의 자유 텍스트이며, 일반적으로 ISO 3166-1 alpha-3 코드(예: `ESP`)이지만 해당 형식으로 유효성을 검증하지는 않습니다."
                    },
                    "marital_status": {
                      "type": "string",
                      "enum": [
                        "SINGLE",
                        "MARRIED",
                        "DIVORCED",
                        "WIDOWED",
                        "UNKNOWN"
                      ],
                      "description": "문서에 기재된 혼인 여부입니다. 다른 값은 `400`을 반환합니다."
                    },
                    "extra_fields": {
                      "type": "object",
                      "additionalProperties": true,
                      "nullable": true,
                      "description": "문서의 추가 필드에 대한 병합된 보기입니다. 모든 운영자 재정의가 적용된 OCR 추출 값입니다. `null` 재정의를 통해 제거된 키는 이 맵에 표시되지 않습니다."
                    },
                    "parsed_address": {
                      "type": "object",
                      "nullable": true,
                      "description": "현재 구조화된 주소(내부 관리용 키 제외) 또는 주소가 없는 경우 `null`입니다. 수정 가능한 7개 키와 함께 다시 계산된 `formatted_address`가 포함됩니다.",
                      "properties": {
                        "address_type": {
                          "type": "string",
                          "nullable": true,
                          "description": "자유 형식 주소 분류(예: `home`)입니다."
                        },
                        "city": {
                          "type": "string",
                          "nullable": true,
                          "example": "Madrid"
                        },
                        "region": {
                          "type": "string",
                          "nullable": true,
                          "description": "주 / 도 / 자치 지역입니다."
                        },
                        "street_1": {
                          "type": "string",
                          "nullable": true,
                          "example": "Avda de Madrid 34"
                        },
                        "street_2": {
                          "type": "string",
                          "nullable": true
                        },
                        "postal_code": {
                          "type": "string",
                          "nullable": true,
                          "example": "28013"
                        },
                        "country": {
                          "type": "string",
                          "nullable": true,
                          "description": "ISO 3166-1 alpha-2 국가 코드입니다. 소문자 입력은 대문자로 정규화되며, alpha-3 코드는 `400`으로 거부됩니다.",
                          "example": "ES"
                        },
                        "formatted_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "구조화된 주소를 결합하여 사람이 읽을 수 있는 형식으로 나타낸 주소입니다. `parsed_address`를 수정할 때마다 서버 측에서 다시 계산됩니다.",
                          "example": "Avda de Madrid 34, Madrid, 28013, ES"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Updated KYC": {
                    "summary": "수정 후 전체 KYC 레코드",
                    "value": {
                      "document_type": "P",
                      "document_subtype": null,
                      "document_number": "PAB123456",
                      "personal_number": "99999999R",
                      "date_of_birth": "1980-01-01",
                      "date_of_issue": "2021-02-09",
                      "expiration_date": "2031-02-08",
                      "issuing_state": "ESP",
                      "first_name": "Carmen",
                      "last_name": "Espanola Espanola",
                      "gender": "F",
                      "address": "AVDA DE MADRID 34, MADRID, MADRID 28013",
                      "place_of_birth": "MADRID",
                      "nationality": "ESP",
                      "marital_status": "MARRIED",
                      "extra_fields": {
                        "mrz_string": "P<ESPESPANOLA<<CARMEN<<<<<",
                        "blood_group": "O+"
                      },
                      "parsed_address": {
                        "city": "Madrid",
                        "street_1": "Avda de Madrid 34",
                        "postal_code": "28013",
                        "country": "ES",
                        "formatted_address": "Avda de Madrid 34, Madrid, 28013, ES"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 필드 오류는 `{\"<field>\": [\"<message>\"]}`로 전달되며, 중첩된 `parsed_address` / `extra_fields` 키의 오류는 객체 값을 사용합니다: `{\"parsed_address\": {\"<key>\": \"<message>\"}}`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid gender": {
                    "summary": "gender는 M, F 또는 U여야 합니다",
                    "value": {
                      "gender": [
                        "\"X\" is not a valid choice."
                      ]
                    }
                  },
                  "Invalid document type": {
                    "summary": "단축 코드 또는 긴 형식의 별칭이 아닙니다",
                    "value": {
                      "document_type": [
                        "\"PASSPORT\" is not a valid choice."
                      ]
                    }
                  },
                  "Invalid issuing state": {
                    "summary": "issuing_state가 ISO 3166-1 alpha-3 형식이 아닙니다.",
                    "value": {
                      "issuing_state": [
                        "Invalid ISO 3166-1 alpha-3 country code for issuing_state."
                      ]
                    }
                  },
                  "Invalid marital status": {
                    "summary": "marital_status가 enum에 없습니다.",
                    "value": {
                      "marital_status": [
                        "\"ENGAGED\" is not a valid choice."
                      ]
                    }
                  },
                  "Bad date format": {
                    "summary": "날짜는 YYYY-MM-DD 형식이어야 합니다.",
                    "value": {
                      "date_of_birth": [
                        "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
                      ]
                    }
                  },
                  "Unsupported parsed_address key": {
                    "summary": "문서화된 7개의 키만 허용됩니다",
                    "value": {
                      "parsed_address": {
                        "zipcode": "Unsupported key. Allowed keys: address_type, city, region, street_1, street_2, postal_code, country"
                      }
                    }
                  },
                  "Invalid parsed_address country": {
                    "summary": "중첩된 국가는 alpha-3가 아닌 alpha-2여야 합니다",
                    "value": {
                      "parsed_address": {
                        "country": "Invalid ISO 3166-1 alpha-2 country code."
                      }
                    }
                  },
                  "extra_fields not an object": {
                    "summary": "extra_fields는 JSON 객체여야 합니다",
                    "value": {
                      "extra_fields": [
                        "This field must be a JSON object."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나 권한이 부족합니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "자격 증명에 write:sessions 권한이 없습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 세션이거나, 편집할 수 없는 상태의 세션이거나, 패치할 KYC 기록이 없습니다. 각 케이스마다 별도의 `detail` 메시지가 표시됩니다(예시 참조). 알 수 없는 세션 조회는 자격 증명 확인 전에 실행됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown session": {
                    "summary": "애플리케이션에 이 ID를 가진 세션이 없습니다(또는 삭제됨)",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Wrong session state": {
                    "summary": "세션이 존재하지만 Approved / Declined / In Review / Kyc Expired 상태가 아닙니다",
                    "value": {
                      "detail": "No Session matches the given query."
                    }
                  },
                  "No KYC record": {
                    "summary": "워크플로에서 신분증 인증 단계를 실행하지 않음",
                    "value": {
                      "detail": "The session does not have a KYC."
                    }
                  },
                  "No KYC for node": {
                    "summary": "node_id가 제공되었으나 해당 KYC가 존재하지 않음",
                    "value": {
                      "detail": "The session does not have a KYC for node 'feature_missing'."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "전용 속도 제한 초과 — API 키당 분당 10회의 KYC 데이터 업데이트(거부된 요청도 한도에 포함됨). 공유 300회/분 쓰기 한도도 자체 메시지와 함께 트리거될 수 있습니다. 재시도하기 전에 `Retry-After` 및 `X-RateLimit-*` 응답 헤더를 확인하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "KYC 업데이트 예산이 모두 소진됨",
                    "value": {
                      "detail": "Session KYC data update rate limit exceeded. You can make up to 10 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-data/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"first_name\": \"Carmen\",\n    \"last_name\": \"Espanola Espanola\",\n    \"date_of_birth\": \"1980-01-01\",\n    \"issuing_state\": \"ESP\",\n    \"parsed_address\": {\n      \"street_1\": \"Avda de Madrid 34\",\n      \"city\": \"Madrid\",\n      \"postal_code\": \"28013\",\n      \"country\": \"ES\"\n    }\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_data(\n    \"11111111-2222-3333-4444-555555555555\",\n    date_of_birth=\"1980-01-01\",\n    issuing_state=\"ESP\",\n    first_name=\"Carmen\",\n    last_name=\"Espanola Espanola\",\n    marital_status=\"MARRIED\",\n    extra_fields={\"blood_group\": \"O+\"},\n    parsed_address={\n        \"city\": \"Madrid\",\n        \"street_1\": \"Avda de Madrid 34\",\n        \"postal_code\": \"28013\",\n        \"country\": \"ES\",\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateData(\"11111111-2222-3333-4444-555555555555\", {\n  date_of_birth: \"1980-01-01\",\n  issuing_state: \"ESP\",\n  first_name: \"Carmen\",\n  last_name: \"Espanola Espanola\",\n  marital_status: \"MARRIED\",\n  extra_fields: { blood_group: \"O+\" },\n  parsed_address: {\n    city: \"Madrid\",\n    street_1: \"Avda de Madrid 34\",\n    postal_code: \"28013\",\n    country: \"ES\",\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateData(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateDataParams{\n\tDateOfBirth:   didit.String(\"1980-01-01\"),\n\tIssuingState:  didit.String(\"ESP\"),\n\tFirstName:     didit.String(\"Carmen\"),\n\tLastName:      didit.String(\"Espanola Espanola\"),\n\tMaritalStatus: didit.Some(didit.SessionsUpdateDataParamsMaritalStatus(\"MARRIED\")),\n\tExtraFields:   didit.Some(map[string]any{\"blood_group\": \"O+\"}),\n\tParsedAddress: didit.Some(didit.SessionsUpdateDataParamsParsedAddress{\n\t\tCity:       didit.String(\"Madrid\"),\n\t\tStreet1:    didit.String(\"Avda de Madrid 34\"),\n\t\tPostalCode: didit.String(\"28013\"),\n\t\tCountry:    didit.String(\"ES\"),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUpdateDataParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateData(\"11111111-2222-3333-4444-555555555555\", SessionsUpdateDataParams.builder()\n        .dateOfBirth(LocalDate.parse(\"1980-01-01\"))\n        .issuingState(\"ESP\")\n        .firstName(\"Carmen\")\n        .lastName(\"Espanola Espanola\")\n        .maritalStatus(SessionsUpdateDataParams.MaritalStatus.of(\"MARRIED\"))\n        .extraFields(Map.of(\"blood_group\", \"O+\"))\n        .parsedAddress(SessionsUpdateDataParams.ParsedAddress.builder()\n                .city(\"Madrid\")\n                .street1(\"Avda de Madrid 34\")\n                .postalCode(\"28013\")\n                .country(\"ES\")\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateData('11111111-2222-3333-4444-555555555555', [\n    'date_of_birth' => '1980-01-01',\n    'issuing_state' => 'ESP',\n    'first_name' => 'Carmen',\n    'last_name' => 'Espanola Espanola',\n    'marital_status' => 'MARRIED',\n    'extra_fields' => ['blood_group' => 'O+'],\n    'parsed_address' => [\n        'city' => 'Madrid',\n        'street_1' => 'Avda de Madrid 34',\n        'postal_code' => '28013',\n        'country' => 'ES',\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_data(\n  \"11111111-2222-3333-4444-555555555555\",\n  date_of_birth: \"1980-01-01\",\n  issuing_state: \"ESP\",\n  first_name: \"Carmen\",\n  last_name: \"Espanola Espanola\",\n  marital_status: \"MARRIED\",\n  extra_fields: { blood_group: \"O+\" },\n  parsed_address: {\n    city: \"Madrid\",\n    street_1: \"Avda de Madrid 34\",\n    postal_code: \"28013\",\n    country: \"ES\",\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateDataAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdateDataParams\n{\n    DateOfBirth = \"1980-01-01\",\n    IssuingState = \"ESP\",\n    FirstName = \"Carmen\",\n    LastName = \"Espanola Espanola\",\n    MaritalStatus = new SessionsUpdateDataParamsMaritalStatus(\"MARRIED\"),\n    ExtraFields = new Dictionary<string, object> { [\"blood_group\"] = \"O+\" },\n    ParsedAddress = new SessionsUpdateDataParamsParsedAddress\n    {\n        City = \"Madrid\",\n        Street1 = \"Avda de Madrid 34\",\n        PostalCode = \"28013\",\n        Country = \"ES\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/features/{nodeId}/update-status/": {
      "patch": {
        "summary": "개별 기능(단계) 상태 업데이트",
        "description": "세션 내 단일 인증 기능(단계)의 상태를 설정합니다. 워크플로 그래프 `nodeId`로 대상 기능을 지정합니다. 단계에 노드가 없는 비그래프 워크플로의 경우 `default`를 사용하고 어떤 단계를 의미하는지 지정하기 위해 `feature_type`도 함께 전달합니다.\n\n사용자 인증(KYC) 및 기업 확인(KYB) 세션 모두와 모든 단계 유형(신분증/OCR, 라이브니스, 얼굴 대조, NFC, AML, 주소 증명, 전화번호, 이메일, 데이터베이스 검증, 설문지 및 KYB 법인 등기부/문서/주요 인물 검사)에서 작동합니다. 이 endpoint는 독립 실행형 API 세션(`session_type = API`)에서는 사용할 수 **없습니다**.\n\n`new_status`는 `Approved`, `Declined` 또는 `In Review` 중 하나여야 하며, 해당 기능의 현재 상태와 달라야 합니다.\n\n**재정의 적용 시점.** `defer_until_flow_finishes`가 없거나 `false`인 경우 재정의는 기존과 동일하게 즉시 적용됩니다. 사용자가 아직 플로우 진행 중인 경우 `forced`로 기록됩니다. 사용자가 아직 플로우 진행 중일 때(세션이 `Not Started`, `In Progress` 또는 `Resubmitted` 상태이며 완료되지 않음) `defer_until_flow_finishes: true`로 설정하면, 재정의는 `pending_until_flow_finishes`로 저장되며 플로우가 자체 결정에 도달한 후 완료될 때 적용됩니다. 플로우가 이미 종료된 세션에서는 어느 쪽이든 즉시 적용됩니다. 대기 중인 재정의는 사용자가 완료하기 전에 해당 단계를 다시 수행하거나, 동일한 검사에 대한 최신 재정의로 대체되거나, 세션이 플로우를 완료하지 않고 종료되거나(중단됨, 만료됨 또는 플로우 도중 결정됨), `POST /v3/session/{sessionId}/features/overrides/{overrideId}/cancel/`을 통해 취소할 경우 취소 처리됩니다. 세션의 재정의 목록은 `GET /v3/session/{sessionId}/features/overrides/`로 조회할 수 있습니다.\n\n**세션에 미치는 영향.** 이미 결정이 내려진 세션은 기존 결정을 유지하며, 해당 검사만 변경됩니다. 세션에 아직 결정이 내려지지 않았고 워크플로가 정확히 이 단계를 대기 중인 경우, 재정의를 적용하면 해당 단계가 완료됩니다. 워크플로가 계속 진행되어 후속 단계가 실행되고, 상태 노드가 세션 결정을 설정하고 `status.updated`를 발생시킬 수 있습니다.\n\n**Webhook 및 활동.** `data.updated` webhook은 재정의가 적용될 때(즉시 또는 플로우 완료 시) 발생하며, 대기 중이거나 취소될 때는 발생하지 않습니다. 모든 재정의는 누가 수행했는지에 대한 정보와 함께 세션 활동에 `FEATURE_OVERRIDE_PENDING`, `FEATURE_OVERRIDE_APPLIED` 또는 `FEATURE_OVERRIDE_CANCELLED`로 기록됩니다. 요청 항목에는 작성한 `comment`가 포함됩니다.\n\nAPI 키(`x-api-key`) 또는 `write:sessions` 권한이 포함된 사용자 인증 헤더로 인증합니다. 스코프가 지정된 API 키에는 결정에 대한 쓰기 권한이 필요합니다.",
        "operationId": "patch_v3_session_update_feature_status",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_feature_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "인증 세션의 UUID입니다. 사용자(KYC) 및 기업(KYB) 세션 ID를 모두 지원하며, 서비스는 두 세션 유형 전체에서 ID를 확인합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "in": "path",
            "name": "nodeId",
            "required": true,
            "description": "업데이트할 기능의 워크플로 그래프 노드 ID입니다(예: `feature_ocr_1`). 기능에 노드 ID가 없는 비그래프(단일 단계) 워크플로의 경우 리터럴 값 `default`를 사용하십시오.",
            "schema": {
              "type": "string",
              "example": "feature_ocr_1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "new_status"
                ],
                "properties": {
                  "new_status": {
                    "type": "string",
                    "description": "이 기능의 대상 상태입니다. 현재 값과 달라야 합니다.",
                    "enum": [
                      "Approved",
                      "Declined",
                      "In Review"
                    ],
                    "example": "Approved"
                  },
                  "comment": {
                    "type": "string",
                    "description": "이 기능 변경에 대해 세션의 검토 기록에 기록되는 선택적 자유 텍스트 메모입니다.",
                    "example": "Document manually verified by compliance."
                  },
                  "feature_type": {
                    "type": "string",
                    "enum": [
                      "ID_VERIFICATION",
                      "OCR",
                      "OCR_BACK",
                      "NFC",
                      "LIVENESS",
                      "FACE",
                      "AGE_ESTIMATION",
                      "AGE_VERIFICATION",
                      "FACE_SEARCH",
                      "FACE_MATCH",
                      "IP_ANALYSIS",
                      "AML",
                      "PHONE",
                      "PHONE_VERIFICATION",
                      "EMAIL",
                      "EMAIL_VERIFICATION",
                      "POA",
                      "PROOF_OF_ADDRESS",
                      "DATABASE_VALIDATION",
                      "DATA_VALIDATION",
                      "QUESTIONNAIRE",
                      "DOCUMENT_AI",
                      "KYB_REGISTRY",
                      "KYB_DOCUMENTS",
                      "KYB_KEY_PEOPLE",
                      "BANK_VERIFICATION",
                      "GEOLOCATION"
                    ],
                    "description": "대상으로 지정할 단계의 종류입니다. 모든 단계가 노드를 공유하지 않는 비그래프 워크플로(`nodeId` = `default`)에서 필요하며, 그렇지 않은 경우 선택 사항입니다. 알 수 없는 값은 `400`을 반환합니다.",
                    "example": "LIVENESS"
                  },
                  "defer_until_flow_finishes": {
                    "type": "boolean",
                    "default": false,
                    "description": "사용자가 아직 플로우에 있는 동안 재정의를 즉시 적용하는 대신 `pending_until_flow_finishes`로 저장하고 플로우가 끝날 때 적용합니다. 생략하거나 `false`로 설정하면 재정의가 즉시 적용됩니다. 플로우가 이미 종료된 세션의 경우 어느 쪽이든 즉시 적용됩니다.",
                    "example": false
                  }
                }
              },
              "examples": {
                "Apply Now": {
                  "summary": "신분증 단계를 즉시 승인",
                  "value": {
                    "new_status": "Approved",
                    "comment": "Document manually verified by compliance."
                  }
                },
                "Wait For The Flow": {
                  "summary": "사용자가 플로우를 완료하면 라이브니스 단계 승인",
                  "value": {
                    "new_status": "Approved",
                    "comment": "Liveness retried with a reviewer present.",
                    "defer_until_flow_finishes": true
                  }
                },
                "Non-graph Workflow": {
                  "summary": "노드가 없는 워크플로의 라이브니스 단계 타겟팅(nodeId = default)",
                  "value": {
                    "new_status": "In Review",
                    "feature_type": "LIVENESS"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "오버라이드가 기록되었습니다. `new_status`는 저장된 검사 상태입니다. 오버라이드가 적용되면 요청된 상태가 되고, 흐름이 완료되기를 기다리는 동안에는 변경되지 않은 상태가 됩니다. `override`는 어떤 경우가 발생했는지를 나타냅니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "node_id": {
                      "type": "string",
                      "nullable": true,
                      "description": "업데이트된 단계의 워크플로 노드이거나, 노드가 없는 단계(비그래프 워크플로의 `default` 경로)의 경우 `null`입니다.",
                      "example": "feature_ocr_1"
                    },
                    "feature_type": {
                      "type": "string",
                      "description": "업데이트된 기능의 모델 이름입니다(예: `KYC`, `Face`, `FaceMatch`, `AML`, `POA`).",
                      "example": "KYC"
                    },
                    "new_status": {
                      "type": "string",
                      "description": "검사의 저장된 상태입니다. 재정의가 적용되면 요청된 상태가 되고, 재정의가 흐름 완료를 기다리는 동안에는 변경되지 않은 상태가 됩니다.",
                      "example": "Approved"
                    },
                    "override": {
                      "$ref": "#/components/schemas/FeatureStatusOverride"
                    }
                  },
                  "required": [
                    "session_id",
                    "node_id",
                    "feature_type",
                    "new_status",
                    "override"
                  ]
                },
                "examples": {
                  "Applied": {
                    "summary": "오버라이드가 즉시 적용되었습니다.",
                    "value": {
                      "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "node_id": "feature_ocr_1",
                      "feature_type": "KYC",
                      "new_status": "Approved",
                      "override": {
                        "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                        "node_id": "feature_ocr_1",
                        "feature_type": "",
                        "feature_model": "KYC",
                        "previous_status": "In Review",
                        "new_status": "Approved",
                        "state": "applied",
                        "forced": false,
                        "reason": "Document manually verified by compliance.",
                        "requested_by": {
                          "email": "reviewer@example.com",
                          "name": "Alex Reviewer",
                          "type": "CONSOLE_USER"
                        },
                        "requested_at": "2026-10-13T09:15:00Z",
                        "applied_at": "2026-10-13T09:15:00Z",
                        "cancelled_at": null,
                        "cancel_reason": null
                      }
                    }
                  },
                  "Waiting For The Flow": {
                    "summary": "사용자가 아직 플로우에 있는 동안 defer_until_flow_finishes",
                    "value": {
                      "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "node_id": "feature_liveness_1",
                      "feature_type": "Face",
                      "new_status": "Declined",
                      "override": {
                        "id": "9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3",
                        "node_id": "feature_liveness_1",
                        "feature_type": "",
                        "feature_model": "Face",
                        "previous_status": "Declined",
                        "new_status": "Approved",
                        "state": "pending_until_flow_finishes",
                        "forced": false,
                        "reason": "Liveness retried with a reviewer present.",
                        "requested_by": {
                          "email": "reviewer@example.com",
                          "name": "Alex Reviewer",
                          "type": "CONSOLE_USER"
                        },
                        "requested_at": "2026-10-13T09:15:00Z",
                        "applied_at": null,
                        "cancelled_at": null,
                        "cancel_reason": null
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. `new_status`가 유효하지 않거나 변경되지 않은 경우, `feature_type`을 알 수 없는 경우, 또는 세션이 독립형 API 세션인 경우 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Same Status": {
                    "summary": "new_status가 현재 상태와 동일함",
                    "value": {
                      "new_status": [
                        "The new status is the same as the current status."
                      ]
                    }
                  },
                  "API Session": {
                    "summary": "독립형 API 세션에서는 기능 상태를 변경할 수 없습니다.",
                    "value": [
                      "Cannot change feature status for API sessions."
                    ]
                  },
                  "Unknown feature_type": {
                    "summary": "feature_type이 알려진 단계 유형이 아닙니다",
                    "value": {
                      "feature_type": [
                        "Unknown feature_type 'SELFIE'."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "만료일이 지난 스코프 지정 API 키",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나 권한이 부족합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "API 키에 write:sessions 권한이 없습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped Key Without Access": {
                    "summary": "결정에 대한 쓰기 권한이 없는 스코프 지정 API 키",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션을 찾을 수 없거나 해당 `nodeId`를 가진 기능이 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Session Not Found": {
                    "summary": "알 수 없는 session_id",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "Feature Not Found": {
                    "summary": "이 node_id에 대한 기능이 없습니다",
                    "value": {
                      "detail": "No feature found with node_id 'feature_ocr_1' in this session."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/features/feature_ocr_1/update-status/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"new_status\": \"Approved\",\n    \"comment\": \"Document manually verified by compliance.\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_feature_status(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"feature_ocr_1\",\n    new_status=\"Approved\",\n    comment=\"Document manually verified by compliance.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateFeatureStatus(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_ocr_1\",\n  {\n    new_status: \"Approved\",\n    comment: \"Document manually verified by compliance.\",\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateFeatureStatus(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_ocr_1\", didit.SessionsUpdateFeatureStatusParams{\n\tNewStatus: \"Approved\",\n\tComment:   didit.String(\"Document manually verified by compliance.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateFeatureStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateFeatureStatus(\"11111111-2222-3333-4444-555555555555\", \"feature_ocr_1\", SessionsUpdateFeatureStatusParams.builder()\n        .newStatus(SessionsUpdateFeatureStatusParams.NewStatus.of(\"Approved\"))\n        .comment(\"Document manually verified by compliance.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateFeatureStatus('11111111-2222-3333-4444-555555555555', 'feature_ocr_1', [\n    'new_status' => 'Approved',\n    'comment' => 'Document manually verified by compliance.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_feature_status(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_ocr_1\",\n  new_status: \"Approved\",\n  comment: \"Document manually verified by compliance.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateFeatureStatusAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_ocr_1\", new SessionsUpdateFeatureStatusParams\n{\n    NewStatus = \"Approved\",\n    Comment = \"Document manually verified by compliance.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/update-aml-hit-status/": {
      "patch": {
        "summary": "AML 일치 항목 검토 상태 업데이트",
        "description": "전체 세션 결정을 변경하지 않고, AML 스크리닝에서 반환된 **단일 AML 일치 항목**(잠재적 제재 / 정치적 주요 인물(PEP) / 감시 목록 / 부정적 언론 보도 일치)의 검토 상태를 설정합니다. `hit_id`(AML 검사의 `hits` 배열에 있는 항목의 `id` — 세션 결정 참조)로 일치 항목을 식별합니다. 이전 형식으로 반환된 일치 항목 id도 계속 허용되며, 응답에는 항상 일치 항목의 현재 `id`가 표시됩니다.\n\n`review_status`는 `Unreviewed`, `Confirmed Match`, `False Positive`, `Inconclusive` 중 하나입니다. 검토자 결정은 지속적인 모니터링 업데이트 전반에 걸쳐 유지되므로, `False Positive`로 표시한 일치 항목은 공급자가 재스크리닝할 때도 해당 상태로 유지됩니다.\n\n호출이 성공하면 `data.updated` webhook이 발생하고 세션의 검토 기록에 활동 항목(행위자 정보 포함)이 추가됩니다. 여러 AML 검사가 포함된 그래프 워크플로의 경우 `node_id`를 전달하여 특정 검사를 지정합니다.\n\nAPI 키(`x-api-key`) 또는 사용자 인증 헤더로 인증하며, 어느 쪽을 사용하든 `write:sessions` 권한이 있어야 합니다.",
        "operationId": "patch_v3_session_update_aml_hit_status",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_aml_hit_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "인증 세션의 UUID입니다. 사용자(KYC) 및 기업(KYB) 세션 ID를 모두 지원하며, 서비스는 두 세션 유형 전체에서 ID를 확인합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "in": "query",
            "name": "node_id",
            "required": false,
            "description": "워크플로 그래프 노드 ID입니다. 세션에 여러 AML 확인(노드당 하나)이 있는 경우에만 필수이며, 단일 AML 세션의 경우 생략하십시오.",
            "schema": {
              "type": "string",
              "example": "feature_aml_1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "hit_id",
                  "review_status"
                ],
                "properties": {
                  "hit_id": {
                    "type": "string",
                    "description": "AML 스크리닝의 `hits` 배열에 있는 일치 항목의 `id`(`hit_...`)입니다. 이전 형식으로 반환된 일치 항목 id도 계속 허용됩니다.",
                    "example": "hit_7c1e9a40b2d35f86e0a4c912"
                  },
                  "review_status": {
                    "type": "string",
                    "description": "일치 항목에 대한 새로운 검토 상태입니다.",
                    "enum": [
                      "Unreviewed",
                      "Confirmed Match",
                      "False Positive",
                      "Inconclusive"
                    ],
                    "example": "False Positive"
                  },
                  "node_id": {
                    "type": "string",
                    "description": "선택적 그래프 노드 ID입니다. 세션에 여러 AML 확인이 있는 경우(여기 또는 쿼리 파라미터로) 사용합니다.",
                    "example": "feature_aml_1"
                  }
                }
              },
              "example": {
                "hit_id": "hit_7c1e9a40b2d35f86e0a4c912",
                "review_status": "False Positive"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "적발(hit) 검토 상태가 업데이트되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "message",
                    "hit_id",
                    "review_status"
                  ],
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "항상 `Hit status updated successfully`입니다."
                    },
                    "hit_id": {
                      "type": "string",
                      "description": "업데이트된 일치 항목의 `id`로, 세션 결정이 반환하는 형태이며 요청에서 이전 형식의 id로 일치 항목을 지정한 경우에도 이 형식으로 반환됩니다."
                    },
                    "review_status": {
                      "type": "string",
                      "enum": [
                        "Unreviewed",
                        "Confirmed Match",
                        "False Positive",
                        "Inconclusive"
                      ],
                      "description": "현재 일치 항목에 저장된 검토 상태입니다."
                    }
                  }
                },
                "example": {
                  "message": "Hit status updated successfully",
                  "hit_id": "hit_7c1e9a40b2d35f86e0a4c912",
                  "review_status": "False Positive"
                }
              }
            }
          },
          "400": {
            "description": "검증 오류 — `hit_id`가 비어 있거나 `review_status`가 허용된 값 중 하나가 아닙니다.",
            "content": {
              "application/json": {
                "example": {
                  "review_status": [
                    "\"Maybe\" is not a valid choice."
                  ]
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나 권한이 부족합니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "API 키에 write:sessions 권한이 없습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션을 찾을 수 없거나, 세션에 AML 검사가 없거나(선택적으로 지정된 `node_id`에 대해), `hit_id`와 일치하는 항목이 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "No AML Check": {
                    "summary": "세션에 AML 검사가 없습니다",
                    "value": {
                      "detail": "The session does not have an AML check."
                    }
                  },
                  "Hit Not Found": {
                    "summary": "알 수 없는 hit_id",
                    "value": {
                      "detail": "Hit with ID 'hit_9d2e7f41c0a8b3e65d1f0c47' not found in the AML check."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-aml-hit-status/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"hit_id\": \"abc123\",\n    \"review_status\": \"False Positive\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_aml_hit_status(\n    \"11111111-2222-3333-4444-555555555555\",\n    hit_id=\"hit_7c1e9a40b2d35f86e0a4c912\",\n    review_status=\"False Positive\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateAmlHitStatus(\"11111111-2222-3333-4444-555555555555\", {\n  hit_id: \"hit_7c1e9a40b2d35f86e0a4c912\",\n  review_status: \"False Positive\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateAMLHitStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateAMLHitStatusParams{\n\tHitID:        \"hit_7c1e9a40b2d35f86e0a4c912\",\n\tReviewStatus: \"False Positive\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateAmlHitStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateAmlHitStatus(\"11111111-2222-3333-4444-555555555555\", SessionsUpdateAmlHitStatusParams.builder()\n        .hitId(\"hit_7c1e9a40b2d35f86e0a4c912\")\n        .reviewStatus(SessionsUpdateAmlHitStatusParams.ReviewStatus.of(\"False Positive\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateAmlHitStatus('11111111-2222-3333-4444-555555555555', [\n    'hit_id' => 'hit_7c1e9a40b2d35f86e0a4c912',\n    'review_status' => 'False Positive',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_aml_hit_status(\n  \"11111111-2222-3333-4444-555555555555\",\n  hit_id: \"hit_7c1e9a40b2d35f86e0a4c912\",\n  review_status: \"False Positive\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateAmlHitStatusAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdateAmlHitStatusParams\n{\n    HitId = \"hit_7c1e9a40b2d35f86e0a4c912\",\n    ReviewStatus = \"False Positive\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/bulk-update-aml-hit-status/": {
      "patch": {
        "summary": "AML 적발 항목 검토 상태 일괄 업데이트",
        "description": "한 번의 호출로 **여러 AML 적발 건**의 검토 상태를 업데이트합니다. `{ hit_id, review_status }` 쌍의 목록인 `hit_updates`를 제공하세요. `review_status`는 `Unreviewed`, `Confirmed Match`, `False Positive`, `Inconclusive` 중 하나입니다.\n\n업데이트는 전부 성공 또는 전부 실패 방식으로 처리됩니다. AML 검사에서 어느 하나의 `hit_id`라도 찾을 수 없는 경우 요청은 `404`를 반환하며 어떤 적발 건도 변경되지 않습니다. 성공한 호출은 단일 `data.updated` webhook을 트리거하고 모든 변경 사항을 포함하는 활동 항목 하나를 기록합니다. 여러 AML 검사가 포함된 그래프 워크플로의 경우 `node_id`를 전달하여 특정 검사를 지정하세요.\n\nAPI 키(`x-api-key`) 또는 사용자 권한 부여 헤더로 인증하세요. 둘 중 하나에는 `write:sessions` 권한이 있어야 합니다.",
        "operationId": "patch_v3_session_bulk_update_aml_hit_status",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "bulk_update_aml_hit_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "인증 세션의 UUID입니다. 사용자(KYC) 및 기업(KYB) 세션 ID를 모두 지원하며, 서비스는 두 세션 유형 전체에서 ID를 확인합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "in": "query",
            "name": "node_id",
            "required": false,
            "description": "워크플로 그래프 노드 ID입니다. 세션에 여러 AML 확인(노드당 하나)이 있는 경우에만 필수이며, 단일 AML 세션의 경우 생략하십시오.",
            "schema": {
              "type": "string",
              "example": "feature_aml_1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "hit_updates"
                ],
                "properties": {
                  "hit_updates": {
                    "type": "array",
                    "description": "비어 있지 않은 일치 항목 업데이트 목록.",
                    "items": {
                      "type": "object",
                      "required": [
                        "hit_id",
                        "review_status"
                      ],
                      "properties": {
                        "hit_id": {
                          "type": "string",
                          "example": "hit_7c1e9a40b2d35f86e0a4c912",
                          "description": "AML 스크리닝의 `hits` 배열에 있는 일치 항목의 `id`(`hit_...`)입니다. 이전 형식으로 반환된 일치 항목 id도 계속 허용됩니다."
                        },
                        "review_status": {
                          "type": "string",
                          "enum": [
                            "Unreviewed",
                            "Confirmed Match",
                            "False Positive",
                            "Inconclusive"
                          ],
                          "example": "Confirmed Match"
                        }
                      }
                    }
                  },
                  "node_id": {
                    "type": "string",
                    "description": "선택적 그래프 노드 ID입니다. 세션에 여러 AML 확인이 있는 경우(여기 또는 쿼리 파라미터로) 사용합니다.",
                    "example": "feature_aml_1"
                  }
                }
              },
              "example": {
                "hit_updates": [
                  {
                    "hit_id": "hit_7c1e9a40b2d35f86e0a4c912",
                    "review_status": "Confirmed Match"
                  },
                  {
                    "hit_id": "hit_3b8f20d6a91c4e75f0b2d6a8",
                    "review_status": "False Positive"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "모든 적중 항목이 업데이트되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "message",
                    "updated_hits"
                  ],
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "`Updated {n} hit(s) successfully` (여기서 `n`은 `hit_updates`의 항목 수입니다)."
                    },
                    "updated_hits": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "`hit_updates`의 각 항목이 지정하는 일치 항목의 `id`로, 세션 결정이 반환하는 형태이며, 상태가 변경되지 않은 일치 항목을 포함하여 요청 순서대로 반환됩니다."
                    }
                  }
                },
                "example": {
                  "message": "Updated 2 hit(s) successfully",
                  "updated_hits": [
                    "hit_7c1e9a40b2d35f86e0a4c912",
                    "hit_3b8f20d6a91c4e75f0b2d6a8"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "검증 오류 — `hit_updates`가 비어 있거나, 항목에 `hit_id` / `review_status`가 누락되었거나 유효하지 않은 값이 포함되어 있습니다.",
            "content": {
              "application/json": {
                "example": {
                  "hit_updates": [
                    "hit_updates cannot be empty"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나 권한이 부족합니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "API 키에 write:sessions 권한이 없습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션을 찾을 수 없거나, 세션에 AML 검사가 없거나, 하나 이상의 `hit_id`가 존재하지 않습니다(이 경우 어떤 일치 항목도 변경되지 않음).",
            "content": {
              "application/json": {
                "example": {
                  "detail": "Hits not found: hit_9d2e7f41c0a8b3e65d1f0c47"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/bulk-update-aml-hit-status/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"hit_updates\": [\n      { \"hit_id\": \"abc123\", \"review_status\": \"Confirmed Match\" },\n      { \"hit_id\": \"def456\", \"review_status\": \"False Positive\" }\n    ]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.bulk_update_aml_hit_status(\n    \"11111111-2222-3333-4444-555555555555\",\n    hit_updates=[{\n        \"hit_id\": \"hit_7c1e9a40b2d35f86e0a4c912\",\n        \"review_status\": \"Confirmed Match\",\n    }, {\n        \"hit_id\": \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n        \"review_status\": \"False Positive\",\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.bulkUpdateAmlHitStatus(\"11111111-2222-3333-4444-555555555555\", {\n  hit_updates: [{\n    hit_id: \"hit_7c1e9a40b2d35f86e0a4c912\",\n    review_status: \"Confirmed Match\",\n  }, {\n    hit_id: \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n    review_status: \"False Positive\",\n  }],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.BulkUpdateAMLHitStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsBulkUpdateAMLHitStatusParams{\n\tHitUpdates: []didit.SessionsBulkUpdateAMLHitStatusParamsHitUpdates{{\n\t\tHitID:        \"hit_7c1e9a40b2d35f86e0a4c912\",\n\t\tReviewStatus: \"Confirmed Match\",\n\t}, {\n\t\tHitID:        \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n\t\tReviewStatus: \"False Positive\",\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsBulkUpdateAmlHitStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().bulkUpdateAmlHitStatus(\"11111111-2222-3333-4444-555555555555\", SessionsBulkUpdateAmlHitStatusParams.builder()\n        .hitUpdates(List.of(\n                SessionsBulkUpdateAmlHitStatusParams.HitUpdates.builder()\n                        .hitId(\"hit_7c1e9a40b2d35f86e0a4c912\")\n                        .reviewStatus(SessionsBulkUpdateAmlHitStatusParams.HitUpdates.ReviewStatus.of(\"Confirmed Match\"))\n                        .build(),\n                SessionsBulkUpdateAmlHitStatusParams.HitUpdates.builder()\n                        .hitId(\"hit_3b8f20d6a91c4e75f0b2d6a8\")\n                        .reviewStatus(SessionsBulkUpdateAmlHitStatusParams.HitUpdates.ReviewStatus.of(\"False Positive\"))\n                        .build()))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->bulkUpdateAmlHitStatus('11111111-2222-3333-4444-555555555555', [\n    'hit_updates' => [[\n        'hit_id' => 'hit_7c1e9a40b2d35f86e0a4c912',\n        'review_status' => 'Confirmed Match',\n    ], [\n        'hit_id' => 'hit_3b8f20d6a91c4e75f0b2d6a8',\n        'review_status' => 'False Positive',\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.bulk_update_aml_hit_status(\n  \"11111111-2222-3333-4444-555555555555\",\n  hit_updates: [{\n    hit_id: \"hit_7c1e9a40b2d35f86e0a4c912\",\n    review_status: \"Confirmed Match\",\n  }, {\n    hit_id: \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n    review_status: \"False Positive\",\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.BulkUpdateAmlHitStatusAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsBulkUpdateAmlHitStatusParams\n{\n    HitUpdates = new SessionsBulkUpdateAmlHitStatusParamsHitUpdates[]\n    {\n        new()\n        {\n            HitId = \"hit_7c1e9a40b2d35f86e0a4c912\",\n            ReviewStatus = \"Confirmed Match\",\n        },\n        new()\n        {\n            HitId = \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n            ReviewStatus = \"False Positive\",\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/update-poa-data/": {
      "patch": {
        "summary": "인증 세션의 주소 증명 문서에서 추출한 주소 증명 데이터 업데이트",
        "description": "인증이 완료된 후 사용자의 주소 증명 문서(공과금 청구서, 은행 명세서 또는 기타 주소 증빙)에서 추출된 필드(발급기관, 날짜, 인쇄된 성명, 주소 자체 및 은행 정보)를 수정합니다. 본문의 모든 필드는 선택 사항입니다. 전송한 키만 기록되며, 그 외의 모든 항목은 그대로 유지됩니다(`PATCH` 시맨틱).\n\n세션은 귀하의 애플리케이션에 속해야 하며 `Approved`, `Declined`, `In Review` 또는 `Kyc Expired` 상태여야 합니다. 그 외 다른 상태(예: 여전히 `In Progress`)인 세션은 `404`와 함께 `\"No Session matches the given query.\"`를 반환합니다. 이는 알 수 없거나 삭제된 `sessionId`에 대해 반환되는 `\"Not found.\"`와 구별됩니다. 또한 세션에는 POA 기록이 포함되어 있어야 합니다. 워크플로에서 주소 증명 단계를 실행한 적이 없는 세션은 `404`(`\"The session does not have a POA.\"`)를 반환합니다. POA 단계가 여러 개 있는 그래프 워크플로의 경우 `node_id`(쿼리 파라미터 또는 본문 필드)로 특정 단계를 지정할 수 있으며, 생략 시 가장 최근의 POA 기록이 패치됩니다.\n\n`extra_fields`는 키별로 병합됩니다. 9개의 알려진 키(`bank_iban`, `additional_names`, …)는 전용 POA 열에 직접 기록되고, 다른 모든 키는 커스텀 추가 필드로 유지되며, `null` / `\"\"`는 키를 삭제합니다. `poa_parsed_address`는 문서화된 7개의 키만 허용하며 수정할 때마다 `formatted_address` / `poa_formatted_address`를 다시 계산합니다. 자유 형식 텍스트인 `poa_address`가 변경되면 서버가 이를 다시 지오코딩하고 구조화된 주소를 갱신할 수도 있습니다(샌드박스 세션에서는 건너뜀).\n\n이 endpoint의 KYC 버전과 달리, `data.updated` [webhook](/ko/integration/webhooks)(트리거 `manual_review`)은 저장된 값 중 최소 하나가 **실제로 변경된 경우**에만 실행됩니다. 동일한 값을 다시 전송하면 아무런 동작도 수행하지 않습니다. 값이 변경되면 변경된 필드를 이전 값 및 새 값과 함께 기록하는 `POA_DATA_UPDATED` 활동 항목이 세션의 `reviews`에 추가되며, [Get Decision](#get-/v3/session/-sessionId-/decision/) 및 콘솔 활동 타임라인에서 확인할 수 있습니다. 세션의 상태와 결정은 다시 평가되지 **않습니다**. 결과를 변경하려면 [Update Status](#patch-/v3/session/-sessionId-/update-status/)를 사용하세요.\n\nAPI 키 또는 콘솔 사용자 token을 허용하며, 어떤 방식이든 자격 증명에 `write:sessions` 권한이 필요합니다. 인증 및 권한 오류는 모두 `403`을 반환하며, 이 API는 절대로 `401`로 응답하지 않습니다. 자격 증명 확인 전에 세션 조회가 먼저 실행되므로, 자격 증명이 누락되었더라도 알 수 없는 `sessionId`에 대해서는 `404`가 반환된다는 점에 유의하세요. 이 endpoint에는 API 키당 분당 10건의 전용 속도 제한이 적용되며(유효하지 않은 요청도 포함됨), 분당 300건의 공유 쓰기 예산도 함께 적용됩니다.\n\n빈 JSON 본문 `{}`은 아무 작업도 수행하지 않습니다. webhook을 트리거하지 않고(`has_changes`는 false로 유지됨) 현재 POA 기록을 에코하며 `200`을 반환합니다.",
        "operationId": "patch_v3_session_update_poa_data",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_poa_data",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "첨부된 주소 증명(POA) 기록을 수정할 사용자 인증(KYC) 세션의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "여러 주소 증명 단계가 포함된 그래프 워크플로에서 패치할 POA 기록의 워크플로 그래프 노드입니다(`node_id` 본문 필드로도 허용됨). 생략하면 세션의 가장 최근 POA 기록이 패치됩니다. 지정된 노드에 대한 POA가 없으면 호출 시 `404`(`\"The session does not have a POA for node '<node_id>'.\"`)가 반환됩니다.",
            "schema": {
              "type": "string",
              "example": "feature_poa"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "모든 필드는 선택 사항입니다. 변경하려는 내용만 전송하십시오.",
                "properties": {
                  "issuing_state": {
                    "type": "string",
                    "nullable": true,
                    "description": "주소 증명(POA) 문서를 발급한 국가, ISO 3166-1 alpha-3. 대소문자를 구분하지 않습니다(대문자로 정규화됨). 유효하지 않은 코드는 `400`을 반환합니다.",
                    "example": "ESP"
                  },
                  "document_type": {
                    "type": "string",
                    "enum": [
                      "UTILITY_BILL",
                      "BANK_STATEMENT",
                      "GOVERNMENT_ISSUED_DOCUMENT",
                      "OTHER_POA_DOCUMENT",
                      "UNKNOWN"
                    ],
                    "description": "POA 문서 카테고리입니다. 값은 대문자이며, `utility_bill`과 같은 소문자 변형은 `400`을 반환합니다.",
                    "example": "UTILITY_BILL"
                  },
                  "document_language": {
                    "type": "string",
                    "maxLength": 50,
                    "nullable": true,
                    "description": "문서의 언어로, 일반적으로 ISO 639-1 코드(예: `es`)입니다. 자유 형식 텍스트이며 언어 코드로 유효성 검사가 진행되지 않습니다.",
                    "example": "es"
                  },
                  "issuer": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "문서를 발급한 조직(공공 서비스 회사, 은행, 정부 기관)입니다.",
                    "example": "Energy Provider S.A."
                  },
                  "issue_date": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "`YYYY-MM-DD` 형식의 주소 증명 문서 발급일입니다. 다른 형식은 `400`을 반환합니다.",
                    "example": "2026-04-12"
                  },
                  "poa_address": {
                    "type": "string",
                    "nullable": true,
                    "description": "문서에 인쇄된 그대로의 자유 텍스트 주소입니다. 이 값이 변경되고(비샌드박스 세션 전용) 구조화된 주소가 여전히 누락되었거나 불완전한 경우, 서버는 동일한 요청의 백그라운드에서 지오코딩을 다시 수행하며 `poa_parsed_address` / `poa_formatted_address`를 지오코더 결과로 덮어쓸 수 있습니다. 재지오코딩을 수행하려면 POA 레코드에 `issuing_state`도 있어야 합니다.",
                    "example": "Avda de Madrid 34, 28013 Madrid"
                  },
                  "name_on_document": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "문서에 인쇄된 수취인 성명입니다.",
                    "example": "Carmen Espanola"
                  },
                  "extra_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "nullable": true,
                    "description": "키별로 병합되는 문서별 추가 정보입니다. 9개의 키는 전용 POA 열에 매핑됩니다: `bank_account_number`, `bank_iban`, `bank_sort_code`, `bank_routing_number`, `bank_swift_bic`, `bank_branch_name`, `bank_branch_address`, `document_phone_number`, `additional_names`(문자열 목록 또는 `null`이어야 하며, 그렇지 않으면 `400`). 기타 다른 키는 커스텀 추가 필드로 저장됩니다. 키별 의미: 값이 있으면 키를 설정하고, `null` 또는 `\"\"`는 삭제합니다. JSON 객체여야 하며, 그렇지 않으면 `400`이 반환됩니다."
                  },
                  "poa_parsed_address": {
                    "type": "object",
                    "nullable": true,
                    "description": "구조화된 주소입니다. 중첩된 키 중 `address_type`, `city`, `region`, `street_1`, `street_2`, `postal_code`, `country`만 허용되며, 다른 키는 `400`을 반환합니다. 키별 동작: 값이 있으면 해당 키를 설정하고, `null`이면 제거합니다. `formatted_address`(및 최상위 `poa_formatted_address`)는 서버 측에서 `street_1`, `street_2`, `city`, `region`, `postal_code`, `country`를 결합하여 다시 계산되므로 직접 설정할 수 없습니다.",
                    "properties": {
                      "address_type": {
                        "type": "string",
                        "nullable": true,
                        "description": "자유 형식 주소 분류(예: `home`)입니다."
                      },
                      "city": {
                        "type": "string",
                        "nullable": true,
                        "example": "Madrid"
                      },
                      "region": {
                        "type": "string",
                        "nullable": true,
                        "description": "주 / 도 / 자치 지역입니다."
                      },
                      "street_1": {
                        "type": "string",
                        "nullable": true,
                        "example": "Avda de Madrid 34"
                      },
                      "street_2": {
                        "type": "string",
                        "nullable": true
                      },
                      "postal_code": {
                        "type": "string",
                        "nullable": true,
                        "example": "28013"
                      },
                      "country": {
                        "type": "string",
                        "nullable": true,
                        "description": "ISO 3166-1 alpha-2 국가 코드입니다. 소문자 입력은 대문자로 정규화되며, alpha-3 코드는 `400`으로 거부됩니다.",
                        "example": "ES"
                      }
                    }
                  }
                }
              },
              "examples": {
                "Correct issuer and address": {
                  "summary": "문서 분류, 발급 기관, 구조화된 주소 수정",
                  "value": {
                    "issuing_state": "ESP",
                    "document_type": "BANK_STATEMENT",
                    "issuer": "Banco Example S.A.",
                    "issue_date": "2026-05-02",
                    "name_on_document": "Carmen Espanola",
                    "poa_address": "Avda de Madrid 34, 28013 Madrid",
                    "extra_fields": {
                      "bank_iban": "ES9121000418450200051332",
                      "additional_names": [
                        "Carmen E. Espanola"
                      ]
                    },
                    "poa_parsed_address": {
                      "street_1": "Avda de Madrid 34",
                      "city": "Madrid",
                      "postal_code": "28013",
                      "country": "ES"
                    }
                  }
                },
                "Remove a banking detail": {
                  "summary": "추가 필드 키 하나를 삭제하고 나머지는 유지",
                  "value": {
                    "extra_fields": {
                      "bank_iban": null
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "POA 데이터가 업데이트되었습니다. 제출한 필드뿐만 아니라 저장된 값이 포함된 모든 업데이트 가능한 필드와 전체 `extra_fields` 맵, `poa_parsed_address`, `poa_formatted_address`를 포함하는 **전체 현재 POA 레코드**를 반환합니다. `data.updated` webhook은 실제로 하나 이상의 값이 변경된 경우에만 트리거됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "issuing_state": {
                      "type": "string",
                      "nullable": true,
                      "description": "주소 증명(POA) 문서를 발급한 국가, ISO 3166-1 alpha-3. 대소문자를 구분하지 않습니다(대문자로 정규화됨). 유효하지 않은 코드는 `400`을 반환합니다.",
                      "example": "ESP"
                    },
                    "document_type": {
                      "type": "string",
                      "enum": [
                        "UTILITY_BILL",
                        "BANK_STATEMENT",
                        "GOVERNMENT_ISSUED_DOCUMENT",
                        "OTHER_POA_DOCUMENT",
                        "UNKNOWN"
                      ],
                      "description": "POA 문서 카테고리입니다. 값은 대문자이며, `utility_bill`과 같은 소문자 변형은 `400`을 반환합니다.",
                      "example": "UTILITY_BILL"
                    },
                    "document_language": {
                      "type": "string",
                      "maxLength": 50,
                      "nullable": true,
                      "description": "문서의 언어로, 일반적으로 ISO 639-1 코드(예: `es`)입니다. 자유 형식 텍스트이며 언어 코드로 유효성 검사가 진행되지 않습니다.",
                      "example": "es"
                    },
                    "issuer": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "문서를 발급한 조직(공공 서비스 회사, 은행, 정부 기관)입니다.",
                      "example": "Energy Provider S.A."
                    },
                    "issue_date": {
                      "type": "string",
                      "format": "date",
                      "nullable": true,
                      "description": "`YYYY-MM-DD` 형식의 주소 증명 문서 발급일입니다. 다른 형식은 `400`을 반환합니다.",
                      "example": "2026-04-12"
                    },
                    "poa_address": {
                      "type": "string",
                      "nullable": true,
                      "description": "문서에 인쇄된 그대로의 자유 텍스트 주소입니다. 이 값이 변경되고(비샌드박스 세션 전용) 구조화된 주소가 여전히 누락되었거나 불완전한 경우, 서버는 동일한 요청의 백그라운드에서 지오코딩을 다시 수행하며 `poa_parsed_address` / `poa_formatted_address`를 지오코더 결과로 덮어쓸 수 있습니다.",
                      "example": "Avda de Madrid 34, 28013 Madrid"
                    },
                    "name_on_document": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "문서에 인쇄된 수취인 성명입니다.",
                      "example": "Carmen Espanola"
                    },
                    "extra_fields": {
                      "type": "object",
                      "additionalProperties": true,
                      "nullable": true,
                      "description": "응답에 항상 존재합니다. 알려진 9개의 키(설정되지 않은 키는 `null`, `additional_names`의 기본값은 `[]`)와 이전에 저장된 커스텀 키가 포함됩니다."
                    },
                    "poa_parsed_address": {
                      "type": "object",
                      "nullable": true,
                      "description": "현재 구조화된 주소 또는 주소가 없는 경우 `null`입니다. 수정 가능한 7개 키와 함께 다시 계산된 `formatted_address`가 포함됩니다. 저장된 그대로 반환되며, 서버 측 지오코딩 후에는 수정 가능한 키와 함께 관리용 키(예: `raw_results`)가 포함될 수 있습니다.",
                      "properties": {
                        "address_type": {
                          "type": "string",
                          "nullable": true,
                          "description": "자유 형식 주소 분류(예: `home`)입니다."
                        },
                        "city": {
                          "type": "string",
                          "nullable": true,
                          "example": "Madrid"
                        },
                        "region": {
                          "type": "string",
                          "nullable": true,
                          "description": "주 / 도 / 자치 지역입니다."
                        },
                        "street_1": {
                          "type": "string",
                          "nullable": true,
                          "example": "Avda de Madrid 34"
                        },
                        "street_2": {
                          "type": "string",
                          "nullable": true
                        },
                        "postal_code": {
                          "type": "string",
                          "nullable": true,
                          "example": "28013"
                        },
                        "country": {
                          "type": "string",
                          "nullable": true,
                          "description": "ISO 3166-1 alpha-2 국가 코드입니다. 소문자 입력은 대문자로 정규화되며, alpha-3 코드는 `400`으로 거부됩니다.",
                          "example": "ES"
                        },
                        "formatted_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "구조화된 주소를 결합하여 사람이 읽을 수 있는 형식으로 나타낸 주소입니다. `poa_parsed_address`를 수정할 때마다 서버 측에서 다시 계산됩니다.",
                          "example": "Avda de Madrid 34, Madrid, 28013, ES"
                        }
                      }
                    },
                    "poa_formatted_address": {
                      "type": "string",
                      "nullable": true,
                      "description": "구조화된 주소가 변경될 때 동기화 상태가 유지되는, 다시 계산된 `formatted_address`의 최상위 복사본입니다.",
                      "example": "Avda de Madrid 34, Madrid, 28013, ES"
                    }
                  }
                },
                "examples": {
                  "Updated POA": {
                    "summary": "수정 후 전체 POA 레코드",
                    "value": {
                      "issuing_state": "ESP",
                      "document_type": "BANK_STATEMENT",
                      "document_language": "es",
                      "issuer": "Banco Example S.A.",
                      "issue_date": "2026-05-02",
                      "poa_address": "Avda de Madrid 34, 28013 Madrid",
                      "name_on_document": "Carmen Espanola",
                      "extra_fields": {
                        "bank_account_number": null,
                        "bank_iban": "ES9121000418450200051332",
                        "bank_sort_code": null,
                        "bank_routing_number": null,
                        "bank_swift_bic": null,
                        "bank_branch_name": null,
                        "bank_branch_address": null,
                        "document_phone_number": null,
                        "additional_names": [
                          "Carmen E. Espanola"
                        ]
                      },
                      "poa_parsed_address": {
                        "city": "Madrid",
                        "street_1": "Avda de Madrid 34",
                        "postal_code": "28013",
                        "country": "ES",
                        "formatted_address": "Avda de Madrid 34, Madrid, 28013, ES"
                      },
                      "poa_formatted_address": "Avda de Madrid 34, Madrid, 28013, ES"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 필드 오류는 `{\"<field>\": [\"<message>\"]}`로 전달되며, 중첩된 `poa_parsed_address` / `extra_fields` 키의 오류는 객체 값을 사용합니다: `{\"extra_fields\": {\"<key>\": \"<message>\"}}`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid document type": {
                    "summary": "Enum은 대문자입니다 — 소문자 변형은 거부됩니다.",
                    "value": {
                      "document_type": [
                        "\"utility_bill\" is not a valid choice."
                      ]
                    }
                  },
                  "Invalid issuing state": {
                    "summary": "issuing_state가 ISO 3166-1 alpha-3 형식이 아닙니다.",
                    "value": {
                      "issuing_state": [
                        "Invalid ISO 3166-1 alpha-3 country code for issuing_state."
                      ]
                    }
                  },
                  "additional_names not a list": {
                    "summary": "additional_names는 문자열 목록 또는 null을 허용합니다",
                    "value": {
                      "extra_fields": {
                        "additional_names": "Must be a list or null."
                      }
                    }
                  },
                  "Unsupported poa_parsed_address key": {
                    "summary": "문서화된 7개의 키만 허용됩니다",
                    "value": {
                      "poa_parsed_address": {
                        "zipcode": "Unsupported key. Allowed keys: address_type, city, region, street_1, street_2, postal_code, country"
                      }
                    }
                  },
                  "Bad date format": {
                    "summary": "날짜는 YYYY-MM-DD 형식이어야 합니다.",
                    "value": {
                      "issue_date": [
                        "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나 권한이 부족합니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "자격 증명에 write:sessions 권한이 없습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 세션이거나, 편집할 수 없는 상태의 세션이거나, 패치할 POA 기록이 없습니다. 각 케이스마다 별도의 `detail` 메시지가 표시됩니다(예시 참조). 알 수 없는 세션 조회는 자격 증명 확인 전에 실행됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown session": {
                    "summary": "애플리케이션에 이 ID를 가진 세션이 없습니다(또는 삭제됨)",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Wrong session state": {
                    "summary": "세션이 존재하지만 Approved / Declined / In Review / Kyc Expired 상태가 아닙니다",
                    "value": {
                      "detail": "No Session matches the given query."
                    }
                  },
                  "No POA record": {
                    "summary": "워크플로에서 주소 증명 단계를 실행하지 않음",
                    "value": {
                      "detail": "The session does not have a POA."
                    }
                  },
                  "No POA for node": {
                    "summary": "node_id가 제공되었으나 해당 POA가 존재하지 않음",
                    "value": {
                      "detail": "The session does not have a POA for node 'feature_missing'."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "전용 속도 제한 초과 — API 키당 분당 10회의 POA 데이터 업데이트(거부된 요청도 한도에 포함됨). 공유 300회/분 쓰기 한도도 자체 메시지와 함께 트리거될 수 있습니다. 재시도하기 전에 `Retry-After` 및 `X-RateLimit-*` 응답 헤더를 확인하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "POA 업데이트 예산 소진",
                    "value": {
                      "detail": "Session POA data update rate limit exceeded. You can make up to 10 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-poa-data/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"issuing_state\": \"ESP\",\n    \"document_type\": \"BANK_STATEMENT\",\n    \"issuer\": \"Banco Example S.A.\",\n    \"issue_date\": \"2026-05-02\",\n    \"name_on_document\": \"Carmen Espanola\",\n    \"poa_address\": \"Avda de Madrid 34, 28013 Madrid\",\n    \"extra_fields\": {\n      \"bank_iban\": \"ES9121000418450200051332\"\n    },\n    \"poa_parsed_address\": {\n      \"city\": \"Madrid\",\n      \"postal_code\": \"28013\",\n      \"country\": \"ES\"\n    }\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_poa_data(\n    \"11111111-2222-3333-4444-555555555555\",\n    issuing_state=\"ESP\",\n    document_type=\"BANK_STATEMENT\",\n    issuer=\"Banco Example S.A.\",\n    issue_date=\"2026-05-02\",\n    poa_address=\"Avda de Madrid 34, 28013 Madrid\",\n    name_on_document=\"Carmen Espanola\",\n    extra_fields={\"bank_iban\": \"ES9121000418450200051332\", \"additional_names\": [\"Carmen E. Espanola\"]},\n    poa_parsed_address={\n        \"city\": \"Madrid\",\n        \"street_1\": \"Avda de Madrid 34\",\n        \"postal_code\": \"28013\",\n        \"country\": \"ES\",\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updatePoaData(\"11111111-2222-3333-4444-555555555555\", {\n  issuing_state: \"ESP\",\n  document_type: \"BANK_STATEMENT\",\n  issuer: \"Banco Example S.A.\",\n  issue_date: \"2026-05-02\",\n  poa_address: \"Avda de Madrid 34, 28013 Madrid\",\n  name_on_document: \"Carmen Espanola\",\n  extra_fields: { bank_iban: \"ES9121000418450200051332\", additional_names: [\"Carmen E. Espanola\"] },\n  poa_parsed_address: {\n    city: \"Madrid\",\n    street_1: \"Avda de Madrid 34\",\n    postal_code: \"28013\",\n    country: \"ES\",\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdatePOAData(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdatePOADataParams{\n\tIssuingState:   didit.String(\"ESP\"),\n\tDocumentType:   didit.Some(didit.SessionsUpdatePOADataParamsDocumentType(\"BANK_STATEMENT\")),\n\tIssuer:         didit.String(\"Banco Example S.A.\"),\n\tIssueDate:      didit.String(\"2026-05-02\"),\n\tPOAAddress:     didit.String(\"Avda de Madrid 34, 28013 Madrid\"),\n\tNameOnDocument: didit.String(\"Carmen Espanola\"),\n\tExtraFields:    didit.Some(map[string]any{\"bank_iban\": \"ES9121000418450200051332\", \"additional_names\": []any{\"Carmen E. Espanola\"}}),\n\tPOAParsedAddress: didit.Some(didit.SessionsUpdatePOADataParamsPOAParsedAddress{\n\t\tCity:       didit.String(\"Madrid\"),\n\t\tStreet1:    didit.String(\"Avda de Madrid 34\"),\n\t\tPostalCode: didit.String(\"28013\"),\n\t\tCountry:    didit.String(\"ES\"),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUpdatePoaDataParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updatePoaData(\"11111111-2222-3333-4444-555555555555\", SessionsUpdatePoaDataParams.builder()\n        .issuingState(\"ESP\")\n        .documentType(SessionsUpdatePoaDataParams.DocumentType.of(\"BANK_STATEMENT\"))\n        .issuer(\"Banco Example S.A.\")\n        .issueDate(LocalDate.parse(\"2026-05-02\"))\n        .poaAddress(\"Avda de Madrid 34, 28013 Madrid\")\n        .nameOnDocument(\"Carmen Espanola\")\n        .extraFields(Map.of(\"bank_iban\", \"ES9121000418450200051332\", \"additional_names\", List.of(\"Carmen E. Espanola\")))\n        .poaParsedAddress(SessionsUpdatePoaDataParams.PoaParsedAddress.builder()\n                .city(\"Madrid\")\n                .street1(\"Avda de Madrid 34\")\n                .postalCode(\"28013\")\n                .country(\"ES\")\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updatePoaData('11111111-2222-3333-4444-555555555555', [\n    'issuing_state' => 'ESP',\n    'document_type' => 'BANK_STATEMENT',\n    'issuer' => 'Banco Example S.A.',\n    'issue_date' => '2026-05-02',\n    'poa_address' => 'Avda de Madrid 34, 28013 Madrid',\n    'name_on_document' => 'Carmen Espanola',\n    'extra_fields' => ['bank_iban' => 'ES9121000418450200051332', 'additional_names' => ['Carmen E. Espanola']],\n    'poa_parsed_address' => [\n        'city' => 'Madrid',\n        'street_1' => 'Avda de Madrid 34',\n        'postal_code' => '28013',\n        'country' => 'ES',\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_poa_data(\n  \"11111111-2222-3333-4444-555555555555\",\n  issuing_state: \"ESP\",\n  document_type: \"BANK_STATEMENT\",\n  issuer: \"Banco Example S.A.\",\n  issue_date: \"2026-05-02\",\n  poa_address: \"Avda de Madrid 34, 28013 Madrid\",\n  name_on_document: \"Carmen Espanola\",\n  extra_fields: { bank_iban: \"ES9121000418450200051332\", additional_names: [\"Carmen E. Espanola\"] },\n  poa_parsed_address: {\n    city: \"Madrid\",\n    street_1: \"Avda de Madrid 34\",\n    postal_code: \"28013\",\n    country: \"ES\",\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdatePoaDataAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdatePoaDataParams\n{\n    IssuingState = \"ESP\",\n    DocumentType = new SessionsUpdatePoaDataParamsDocumentType(\"BANK_STATEMENT\"),\n    Issuer = \"Banco Example S.A.\",\n    IssueDate = \"2026-05-02\",\n    PoaAddress = \"Avda de Madrid 34, 28013 Madrid\",\n    NameOnDocument = \"Carmen Espanola\",\n    ExtraFields = new Dictionary<string, object> { [\"bank_iban\"] = \"ES9121000418450200051332\", [\"additional_names\"] = new object[] { \"Carmen E. Espanola\" } },\n    PoaParsedAddress = new SessionsUpdatePoaDataParamsPoaParsedAddress\n    {\n        City = \"Madrid\",\n        Street1 = \"Avda de Madrid 34\",\n        PostalCode = \"28013\",\n        Country = \"ES\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/{companyUuid}/update-data/": {
      "patch": {
        "summary": "기업 확인(KYB) 세션에서 법인 등기부에서 추출한 기업 데이터 업데이트",
        "description": "`companyUuid`로 식별되는 기업 확인(KYB) 세션에서 등기부에서 추출된 기업 데이터(기업명, 등록번호, 주소, 상태, 연락처 세부 정보)를 수정합니다. 주로 컴플라이언스 분석가가 등기부 오인식을 수정하거나 백오피스에서 수정된 기업 데이터를 동기화할 때 호출합니다. 본문의 모든 필드는 선택 사항(`PATCH` 시맨틱)이며, 빈 JSON 본문(`{}`)은 아무 작업도 수행하지 않고 단순히 현재 기업 레코드를 그대로 반환합니다(no-op).\n\n수정 사항은 두 곳에 동시에 기록됩니다. 표준 기업 컬럼이 있는 필드(이름, 등록번호, 국가, 설립일, 납세자 번호, 유형, 상태, 자본 필드(`registered_capital`, `registered_capital_amount`, `registered_capital_currency`), 대체 이름, 사업 성격, 웹사이트, 이메일, 전화번호, LEI, 위치 및 `legal_address` → `registered_address`)는 해당 컬럼을 업데이트하며, 제출된 **모든** 키는 `registry_data` 스냅샷(날짜는 ISO 문자열)에도 병합되어 \"등기부에서 추출됨\" 뷰에 수정 내용이 반영됩니다. 컬럼이 없는 필드(`region`, `registration_date`, `dissolution_date`, `control_scheme`)는 `registry_data`에만 반영됩니다. `user_provided_data`(호스팅 플로우에서 최종 사용자가 확인한 데이터)는 절대 변경되지 않으며, 비어 있지 않은 모든 PATCH에는 `last_console_edit_at` 타임스탬프가 기록됩니다.\n\nKYC/POA 업데이트 endpoint와 달리 **세션 상태 제한이 없습니다**. 즉, 기업 세션의 라이프사이클 중 어느 시점에서나 기업 정보를 수정할 수 있습니다. 기업은 경로에 지정된 세션에 속해야 하고(그렇지 않으면 `\"KYB company does not belong to the given session.\"`과 함께 `404` 반환) 해당 애플리케이션에 속해야 합니다. 비어 있지 않은 모든 PATCH는 제출된 값이 기존에 저장된 값과 동일하더라도 기업 세션에 대해 `data.updated` [webhook](/ko/integration/webhooks)을 트리거합니다(트리거 `console_registry_edit`). 세션의 상태와 결정은 재평가되지 **않으며**, 검토/감사 항목도 기록되지 않습니다.\n\nAPI 키 또는 콘솔 사용자 토큰을 사용할 수 있으며, 두 경우 모두 해당 자격 증명에 `write:businesses` 권한이 필요합니다. 인증 및 권한 실패는 모두 `403`을 반환하며, 이 API는 절대로 `401`을 반환하지 않습니다. 자격 증명 확인 전에 세션 조회가 먼저 실행되므로, 알 수 없는 `sessionId`의 경우 자격 증명이 누락되었더라도 `404`가 반환됩니다. API 키당 분당 300회의 공유 쓰기 속도 제한이 적용됩니다.\n\n사용자 인증 세션의 경우 이에 해당하는 KYC endpoint는 `PATCH /v3/session/{sessionId}/update-data/`이며, 세션 결정 자체를 변경하려면 `PATCH /v3/session/{sessionId}/update-status/`를 사용하세요.",
        "operationId": "patch_v3_session_kyb_company_update_data",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_kyb_company_data",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "상위 기업 확인(KYB) 세션의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "companyUuid",
            "in": "path",
            "required": true,
            "description": "업데이트할 기업 기록의 UUID(기업 세션 결정의 `registry_checks[].company.uuid`)입니다. `sessionId`로 참조되는 세션에 속해 있어야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "88888888-9999-aaaa-bbbb-cccccccccccc"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "모든 필드는 선택 사항입니다. 변경하려는 항목만 전송하십시오. 제공된 필드는 표준 기업 열(존재하는 경우)을 업데이트하고 `registry_data` 스냅샷에 병합됩니다.",
                "properties": {
                  "company_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "회사의 법인명입니다. 표준 컬럼 및 등기부 스냅샷에 기록됩니다.",
                    "example": "Docs Probe Corp"
                  },
                  "registration_number": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "법인 등기부의 공식 등록번호입니다.",
                    "example": "DPC-001"
                  },
                  "country_code": {
                    "type": "string",
                    "maxLength": 2,
                    "description": "설립 국가, ISO 3166-1 alpha-2. 대소문자를 구분하지 않습니다(`us`는 `US`로 저장됨). Alpha-3 코드는 2자 제한을 초과하여 `400` 오류가 발생합니다.",
                    "example": "US"
                  },
                  "region": {
                    "type": "string",
                    "maxLength": 10,
                    "nullable": true,
                    "description": "법인 등기부에 있는 경우 행정 구역/지역 태그입니다(예: 미국 주). 등기부 스냅샷에만 저장되며 정규 열은 없습니다."
                  },
                  "incorporation_date": {
                    "type": "string",
                    "format": "date",
                    "description": "`YYYY-MM-DD` 형식의 설립일입니다. 다른 모든 필드와 마찬가지로 선택 사항입니다 — `PATCH`는 부분 업데이트입니다. 다른 날짜 형식을 사용하면 `400`이 반환됩니다.",
                    "example": "2015-04-12"
                  },
                  "registration_date": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "법인 등기부에서 설립일과 구분하여 명시한 등록일입니다. 법인 등기부 스냅샷에만 저장됩니다."
                  },
                  "dissolution_date": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "더 이상 활동하지 않는 기업의 해산일입니다. 등기부 스냅샷에만 저장됩니다."
                  },
                  "tax_number": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "납세자 번호입니다."
                  },
                  "legal_address": {
                    "type": "string",
                    "description": "법적/등록 주소입니다. 서버 측에서 정규 `registered_address` 열로 별칭 처리되어, 응답에서는 `registered_address` 아래에 반환되지만 등기부 스냅샷에는 전송한 `legal_address` 키가 유지됩니다.",
                    "example": "1 Example Plaza, Wilmington, DE 19801"
                  },
                  "company_type": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "법인 유형(예: `Limited Liability Company`, `PLC`, `GmbH`).",
                    "example": "Limited Liability Company"
                  },
                  "registry_status": {
                    "type": "string",
                    "enum": [
                      "active",
                      "dissolved",
                      "deregistered",
                      "see full details",
                      "authorised",
                      "appointed representative",
                      "unauthorised",
                      "inactive",
                      "no longer authorised",
                      "closed",
                      "struck off"
                    ],
                    "nullable": true,
                    "description": "법인 등기부에 보고된 기업 상태입니다. 소문자이며, 일부 값에는 공백이 포함됩니다(예: `struck off`, `no longer authorised`). 다른 모든 값은 `400`을 반환합니다.",
                    "example": "active"
                  },
                  "verification_status": {
                    "type": "string",
                    "enum": [
                      "verified",
                      "failed",
                      "unknown"
                    ],
                    "nullable": true,
                    "description": "등기부 검증 결과입니다. 다른 값은 `400`을 반환합니다.",
                    "example": "verified"
                  },
                  "alternative_names": {
                    "type": "string",
                    "description": "상호, 이전 법인명, DBA 명칭(자유 형식 텍스트)."
                  },
                  "nature_of_business": {
                    "type": "string",
                    "description": "기업 활동에 대한 간단한 설명입니다.",
                    "example": "Software development"
                  },
                  "registered_capital": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "사람이 읽을 수 있는 등록 자본금(예: `USD 50000`)입니다. 구조화된 값에는 `registered_capital_amount` + `registered_capital_currency`를 사용하고, 자유 형식 텍스트에는 이 필드를 사용하세요.",
                    "example": "USD 50000"
                  },
                  "registered_capital_amount": {
                    "type": "number",
                    "format": "double",
                    "nullable": true,
                    "description": "숫자 형식의 등록 자본금(최대 20자리, 소수점 이하 2자리)입니다. `registered_capital_amount` 열을 설정하고 `registry_data`에 십진수 문자열로 미러링되며, 응답에는 십진수 문자열(예: `\"1500000.50\"`)로 반환됩니다."
                  },
                  "registered_capital_currency": {
                    "type": "string",
                    "maxLength": 3,
                    "nullable": true,
                    "description": "`registered_capital_amount`의 ISO 4217 통화 코드입니다. 대소문자를 구분하지 않으며(`usd`는 `USD`로 저장됨), 정확히 3글자가 아닌 값은 ISO 4217 메시지와 함께 `400`을 반환합니다. 표준 `registered_capital_currency` 열을 설정하며 `registry_data`에 반영됩니다.",
                    "example": "USD"
                  },
                  "website": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "기업 웹사이트입니다. 도메인만 입력한 값도 허용되며 `https://` 접두사로 정규화됩니다(`docsprobe.example.com`은 `https://docsprobe.example.com`으로 저장됨). URL 유효성 검사에 실패하는 값은 `400`을 반환합니다.",
                    "example": "https://docsprobe.example.com"
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "등기소에 등록된 연락처 이메일입니다.",
                    "example": "legal@docsprobe.example.com"
                  },
                  "phone": {
                    "type": "string",
                    "maxLength": 50,
                    "description": "연락처 전화번호입니다. `+`, 숫자, 공백, 대시, 점 또는 괄호와 일치해야 하며 총 7~15자리 숫자여야 합니다. 그렇지 않으면 `400`이 반환됩니다.",
                    "example": "+1 302 555 0143"
                  },
                  "legal_entity_identifier": {
                    "type": "string",
                    "maxLength": 50,
                    "description": "기업이 보유한 경우의 LEI입니다."
                  },
                  "location_of_registration": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "기록된 등기부의 도시 / 하위 행정 구역입니다."
                  },
                  "vat_number": {
                    "type": "string",
                    "maxLength": 64,
                    "description": "EU VAT 번호입니다. `registry_data` 스냅샷에만 병합되며, 여기서 편집해도 VAT 및 납세자 번호 검증이 다시 실행되지 않으므로 `vat_validation_status` 및 기타 `vat_*` 결과 필드는 변경되지 않습니다."
                  },
                  "control_scheme": {
                    "type": "string",
                    "description": "등기부에서 공개하는 지배/지배구조 체계입니다. 등기부 스냅샷에만 저장됩니다."
                  }
                }
              },
              "examples": {
                "Correct registry data": {
                  "summary": "기업의 법인 등기부에서 추출된 필드 수정",
                  "value": {
                    "company_name": "Docs Probe Corp",
                    "registration_number": "DPC-001",
                    "country_code": "US",
                    "incorporation_date": "2015-04-12",
                    "company_type": "Limited Liability Company",
                    "legal_address": "1 Example Plaza, Wilmington, DE 19801",
                    "registry_status": "active",
                    "verification_status": "verified",
                    "website": "docsprobe.example.com",
                    "email": "legal@docsprobe.example.com",
                    "phone": "+1 302 555 0143",
                    "registered_capital": "USD 50000",
                    "nature_of_business": "Software development"
                  }
                },
                "Single field": {
                  "summary": "전송한 키만 기록됩니다",
                  "value": {
                    "registry_status": "dissolved"
                  }
                },
                "No-op": {
                  "summary": "빈 본문은 webhook을 트리거하지 않고 현재 레코드를 그대로 반환합니다.",
                  "value": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "업데이트된 기업 데이터입니다(요청 본문이 비어 있는 경우 변경 없이 그대로 반환됩니다). 전체 KYB 기업 레코드를 반환하며, 이는 기업 세션 결정의 `registry_checks[].company`와 동일한 형태입니다. `legal_address`가 `registered_address`로 반환되는 점에 유의하십시오. `registered_capital_amount`/`registered_capital_currency`는 정규 컬럼에 채워지며 `registry_data`에도 반영됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "전체 KYB 회사 레코드 — 기업 세션 결정의 `registry_checks[]` 내 `company` 객체와 동일한 형태입니다.",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "기업 레코드 식별자(`companyUuid` 경로 파라미터)입니다."
                    },
                    "node_id": {
                      "type": "string",
                      "nullable": true,
                      "description": "워크플로가 그래프 기반일 때 이 기업 기록이 속한 워크플로 그래프 노드입니다."
                    },
                    "status": {
                      "type": "string",
                      "description": "등기소 확인의 기능 라이프사이클 상태(예: `Not Finished`, `Approved`, `Declined`, `In Review`)."
                    },
                    "registry_status": {
                      "type": "string",
                      "nullable": true,
                      "description": "법인 등기부에 보고된 기업 상태(예: `active`, `dissolved`, `struck off`)입니다."
                    },
                    "data_resolved": {
                      "type": "boolean",
                      "description": "기업 데이터가 완전할 때 `true`입니다. 직접 입력한 기업의 경우 항상 `true`이며, 법인 등기부에서 가져온 기업의 경우 등기부 조회가 완료되면 `true`입니다."
                    },
                    "company_name": {
                      "type": "string",
                      "nullable": true
                    },
                    "registration_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "country_code": {
                      "type": "string",
                      "nullable": true,
                      "description": "설립 국가의 ISO 3166-1 alpha-2 코드입니다."
                    },
                    "region": {
                      "type": "string",
                      "nullable": true
                    },
                    "company_type": {
                      "type": "string",
                      "nullable": true
                    },
                    "incorporation_date": {
                      "type": "string",
                      "format": "date",
                      "nullable": true
                    },
                    "registered_address": {
                      "type": "string",
                      "nullable": true,
                      "description": "표준 등록 주소 — `legal_address`를 전송할 때 업데이트됩니다."
                    },
                    "tax_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "risk_level": {
                      "type": "string",
                      "nullable": true
                    },
                    "verification_status": {
                      "type": "string",
                      "nullable": true,
                      "description": "`verified`, `failed` 또는 `unknown`입니다."
                    },
                    "is_from_registry": {
                      "type": "boolean",
                      "description": "수동으로 입력하지 않고 법인 등기부 검색을 통해 기업 정보가 자동으로 입력되었을 때 `true`입니다."
                    },
                    "fetch_status": {
                      "type": "string",
                      "nullable": true,
                      "description": "법인 등기부 출처 기업에 대한 법인 등기부 조회 라이프사이클(`pending` / `resolved`)입니다. 직접 입력한 항목의 경우 `null`입니다."
                    },
                    "alternative_names": {
                      "type": "string",
                      "nullable": true,
                      "description": "보고된 경우, 텍스트 형태의 대체명, 상호명, 이전 명칭 또는 원어 기업명입니다."
                    },
                    "nature_of_business": {
                      "type": "string",
                      "nullable": true
                    },
                    "registered_capital": {
                      "type": "string",
                      "nullable": true
                    },
                    "registered_capital_amount": {
                      "type": "string",
                      "nullable": true,
                      "description": "표준 열입니다. 십진수 문자열로 반환됩니다(예: `\"2750000.00\"`)."
                    },
                    "registered_capital_currency": {
                      "type": "string",
                      "nullable": true,
                      "description": "표준 열입니다. 등기소 워크플로에 의해 설정되거나 이 endpoint를 통한 콘솔/API 편집으로 설정됩니다."
                    },
                    "website": {
                      "type": "string",
                      "nullable": true
                    },
                    "email": {
                      "type": "string",
                      "nullable": true
                    },
                    "phone": {
                      "type": "string",
                      "nullable": true
                    },
                    "legal_entity_identifier": {
                      "type": "string",
                      "nullable": true
                    },
                    "location_of_registration": {
                      "type": "string",
                      "nullable": true
                    },
                    "vat_number": {
                      "type": "string",
                      "nullable": true,
                      "description": "호스팅 법인 등기부 단계에서 수집되었거나 이후 편집된 EU VAT 번호입니다."
                    },
                    "vat_validation_status": {
                      "type": "string",
                      "enum": [
                        "valid",
                        "invalid",
                        "format_valid",
                        "invalid_format",
                        "could_not_validate",
                        "not_applicable"
                      ],
                      "description": "법인 등기부 제출 시 VAT 번호 또는 없는 경우 `tax_number`를 검증한 결과입니다. `valid` / `invalid`: 해당 국가의 공식 등기소(EU VIES, 노르웨이, 스위스, 브라질, 콜롬비아, 코스타리카, 에콰도르, 파라과이, 폴란드의 경우 국내 VAT 등록부 포함)에서 결정됩니다. `format_valid` / `invalid_format`: 등기소 조회가 불가능한 경우 해당 국가의 서식 및 체크 디지트 규칙에 따라 결정됩니다. `could_not_validate`: 등기소를 사용할 수 없습니다. `not_applicable`: 번호가 없거나, 등기소나 규칙이 없는 국가이거나, 샌드박스 세션인 경우입니다."
                    },
                    "vat_validated_number": {
                      "type": "string",
                      "nullable": true,
                      "description": "출처가 인식하는 확인된 번호입니다(예: 프랑스 SIREN 또는 네덜란드 RSIN에서 파생된 VAT 번호). 확인이 실행되지 않은 경우 `null`입니다."
                    },
                    "vat_validation_source": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "eu_vies",
                        "pl_vat_white_list",
                        "no_brreg",
                        "ch_uid_register",
                        "br_receita_federal",
                        "co_rues",
                        "cr_hacienda",
                        "ec_sri",
                        "py_dnit",
                        "format_rules",
                        null
                      ],
                      "description": "`vat_validation_status`를 결정한 소스(공식 등기소 또는 `format_rules`)입니다. 검사가 실행되지 않은 경우 `null`입니다."
                    },
                    "vat_validated_name": {
                      "type": "string",
                      "nullable": true,
                      "description": "해당 번호를 검증한 소스에 등록된 이름(소스를 통해 공개된 경우). 상태가 `valid`인 경우에만 설정됩니다."
                    },
                    "vat_validated_address": {
                      "type": "string",
                      "nullable": true,
                      "description": "번호를 검증한 출처에 등록된 주소(출처에서 제공하는 경우)입니다. 상태가 `valid`일 때만 설정됩니다."
                    },
                    "vat_checked_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "검사의 타임스탬프입니다. 검사가 실행되지 않은 경우 `null`입니다."
                    },
                    "financial_summary": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true
                    },
                    "officers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "개인별 KYC 진행 상황을 포함하여 회사에 소속된 이사/임원입니다."
                    },
                    "beneficial_owners": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "개인별 KYC 진행 상황을 포함하여 회사에 연결된 실소유자입니다."
                    },
                    "addresses": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "법인 등기부에서 반환된 주소 상세 정보(있는 경우)입니다."
                    },
                    "industries": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "제공되는 경우, 법인 등기부 업종 분류입니다."
                    },
                    "accounts": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "제공되는 경우 법인 등기부 제출 날짜입니다. 연차 보고서 및 주주총회에는 last_annual_return_date 및 last_agm_date를 사용하며, 재무제표와는 구별됩니다."
                    },
                    "registry_data": {
                      "$ref": "#/components/schemas/KYBRegistryData"
                    },
                    "user_provided_data": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "호스팅 등기부 확인 단계에서 최종 사용자가 입력한 내용입니다. 이 endpoint로는 절대 수정되지 않습니다."
                    },
                    "confirmed_by_user_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "최종 사용자가 호스팅 흐름에서 회사 데이터를 확인한 시점입니다."
                    },
                    "last_console_edit_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "성공한 모든 비어 있지 않은 PATCH에 스탬프 처리되므로, UI에서 \"운영자가 편집함\" 컨텍스트를 표시할 수 있습니다."
                    },
                    "is_editable": {
                      "type": "boolean",
                      "description": "최종 사용자가 호스팅 플로우에서 법인 등기부 출처 데이터를 계속 편집할 수 있는 동안 `true`입니다(등기부 출처 데이터이나 아직 확인되지 않음)."
                    }
                  }
                },
                "examples": {
                  "Updated company": {
                    "summary": "수정 후 전체 회사 레코드",
                    "value": {
                      "uuid": "6b9479f5-6769-46c8-baf1-df63bbbc5f8c",
                      "node_id": null,
                      "status": "Not Finished",
                      "registry_status": "active",
                      "data_resolved": true,
                      "company_name": "Docs Probe Corp",
                      "registration_number": "DPC-001",
                      "country_code": "US",
                      "region": null,
                      "company_type": "Limited Liability Company",
                      "incorporation_date": "2015-04-12",
                      "registered_address": "1 Example Plaza, Wilmington, DE 19801",
                      "tax_number": null,
                      "risk_level": null,
                      "verification_status": "verified",
                      "is_from_registry": false,
                      "fetch_status": null,
                      "alternative_names": null,
                      "nature_of_business": "Software development",
                      "registered_capital": "USD 50000",
                      "registered_capital_amount": null,
                      "registered_capital_currency": "USD",
                      "website": "https://docsprobe.example.com",
                      "email": "legal@docsprobe.example.com",
                      "phone": "+1 302 555 0143",
                      "legal_entity_identifier": null,
                      "location_of_registration": null,
                      "financial_summary": null,
                      "officers": [],
                      "beneficial_owners": [],
                      "addresses": null,
                      "industries": null,
                      "accounts": null,
                      "registry_data": {
                        "company_name": "Docs Probe Corp",
                        "registration_number": "DPC-001",
                        "country_code": "US",
                        "incorporation_date": "2015-04-12",
                        "legal_address": "1 Example Plaza, Wilmington, DE 19801",
                        "company_type": "Limited Liability Company",
                        "registry_status": "active",
                        "verification_status": "verified",
                        "nature_of_business": "Software development",
                        "registered_capital": "USD 50000",
                        "registered_capital_currency": "USD",
                        "website": "https://docsprobe.example.com",
                        "email": "legal@docsprobe.example.com",
                        "phone": "+1 302 555 0143"
                      },
                      "user_provided_data": null,
                      "confirmed_by_user_at": null,
                      "last_console_edit_at": "2026-06-12T00:02:34.276061Z",
                      "is_editable": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 필드 오류는 `{\"<field>\": [\"<message>\"]}`로 전달됩니다. 형식 검사보다 최대 길이 검사가 먼저 실행되므로, `country_code: \"USA\"`는 ISO 메시지 대신 2자 제한 오류를 보고합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Alpha-3 country code": {
                    "summary": "country_code는 alpha-2여야 합니다 — 길이 확인이 먼저 실행됩니다",
                    "value": {
                      "country_code": [
                        "Ensure this field has no more than 2 characters."
                      ]
                    }
                  },
                  "Non-alphabetic country code": {
                    "summary": "2자이지만 문자가 아님",
                    "value": {
                      "country_code": [
                        "country_code must be a 2-letter ISO 3166-1 alpha-2 code."
                      ]
                    }
                  },
                  "Invalid currency": {
                    "summary": "3자이지만 ISO 4217 코드가 아님",
                    "value": {
                      "registered_capital_currency": [
                        "Currency must be a 3-letter ISO 4217 code (e.g. USD, EUR, GBP)."
                      ]
                    }
                  },
                  "Invalid phone": {
                    "summary": "전화번호가 형식/자릿수 검사에 실패함",
                    "value": {
                      "phone": [
                        "Invalid phone number format."
                      ]
                    }
                  },
                  "Invalid registry status": {
                    "summary": "registry_status가 enum에 없습니다.",
                    "value": {
                      "registry_status": [
                        "\"liquidated\" is not a valid choice."
                      ]
                    }
                  },
                  "Invalid email": {
                    "summary": "잘못된 형식의 이메일 주소",
                    "value": {
                      "email": [
                        "Enter a valid email address."
                      ]
                    }
                  },
                  "Invalid website": {
                    "summary": "https:// 정규화 후에도 URL 검증에 실패하는 값입니다.",
                    "value": {
                      "website": [
                        "Enter a valid URL."
                      ]
                    }
                  },
                  "Bad date format": {
                    "summary": "날짜는 YYYY-MM-DD 형식이어야 합니다.",
                    "value": {
                      "incorporation_date": [
                        "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나 권한이 부족합니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "자격 증명에 write:businesses 권한이 없습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 세션이거나, 알 수 없는 회사이거나, 다른 세션에 속한 회사입니다. 각 케이스마다 별도의 `detail` 메시지가 표시됩니다(예시 참조). 알 수 없는 세션 조회는 자격 증명 확인 전에 실행됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown session": {
                    "summary": "애플리케이션에 이 ID를 가진 세션이 없습니다(또는 삭제됨)",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Unknown company": {
                    "summary": "귀하의 애플리케이션에 이 UUID를 가진 기업이 없습니다",
                    "value": {
                      "detail": "No KYBCompany matches the given query."
                    }
                  },
                  "Company / session mismatch": {
                    "summary": "companyUuid가 존재하지만 다른 세션에 속해 있습니다",
                    "value": {
                      "detail": "KYB company does not belong to the given session."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "공유 쓰기 속도 제한을 초과했습니다(API 키당 분당 300개의 POST/PATCH/DELETE 요청). 재시도하기 전에 `Retry-After` 및 `X-RateLimit-*` 응답 헤더를 확인하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "쓰기 예산 소진됨",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/33333333-4444-5555-6666-777777777777/kyb/88888888-9999-aaaa-bbbb-cccccccccccc/update-data/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"company_name\": \"Docs Probe Corp\",\n    \"registration_number\": \"DPC-001\",\n    \"country_code\": \"US\",\n    \"incorporation_date\": \"2015-04-12\",\n    \"company_type\": \"Limited Liability Company\",\n    \"legal_address\": \"1 Example Plaza, Wilmington, DE 19801\",\n    \"registry_status\": \"active\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_kyb_company_data(\n    \"33333333-4444-5555-6666-777777777777\",\n    \"88888888-9999-aaaa-bbbb-cccccccccccc\",\n    company_name=\"Docs Probe Corp\",\n    registration_number=\"DPC-001\",\n    country_code=\"US\",\n    incorporation_date=\"2015-04-12\",\n    legal_address=\"1 Example Plaza, Wilmington, DE 19801\",\n    company_type=\"Limited Liability Company\",\n    registry_status=\"active\",\n    verification_status=\"verified\",\n    nature_of_business=\"Software development\",\n    registered_capital=\"USD 50000\",\n    website=\"docsprobe.example.com\",\n    email=\"legal@docsprobe.example.com\",\n    phone=\"+1 302 555 0143\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateKybCompanyData(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"88888888-9999-aaaa-bbbb-cccccccccccc\",\n  {\n    company_name: \"Docs Probe Corp\",\n    registration_number: \"DPC-001\",\n    country_code: \"US\",\n    incorporation_date: \"2015-04-12\",\n    legal_address: \"1 Example Plaza, Wilmington, DE 19801\",\n    company_type: \"Limited Liability Company\",\n    registry_status: \"active\",\n    verification_status: \"verified\",\n    nature_of_business: \"Software development\",\n    registered_capital: \"USD 50000\",\n    website: \"docsprobe.example.com\",\n    email: \"legal@docsprobe.example.com\",\n    phone: \"+1 302 555 0143\",\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateKYBCompanyData(ctx, \"33333333-4444-5555-6666-777777777777\", \"88888888-9999-aaaa-bbbb-cccccccccccc\", didit.SessionsUpdateKYBCompanyDataParams{\n\tCompanyName:        didit.String(\"Docs Probe Corp\"),\n\tRegistrationNumber: didit.String(\"DPC-001\"),\n\tCountryCode:        didit.String(\"US\"),\n\tIncorporationDate:  didit.String(\"2015-04-12\"),\n\tLegalAddress:       didit.String(\"1 Example Plaza, Wilmington, DE 19801\"),\n\tCompanyType:        didit.String(\"Limited Liability Company\"),\n\tRegistryStatus:     didit.Some(didit.SessionsUpdateKYBCompanyDataParamsRegistryStatus(\"active\")),\n\tVerificationStatus: didit.Some(didit.SessionsUpdateKYBCompanyDataParamsVerificationStatus(\"verified\")),\n\tNatureOfBusiness:   didit.String(\"Software development\"),\n\tRegisteredCapital:  didit.String(\"USD 50000\"),\n\tWebsite:            didit.String(\"docsprobe.example.com\"),\n\tEmail:              didit.String(\"legal@docsprobe.example.com\"),\n\tPhone:              didit.String(\"+1 302 555 0143\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUpdateKybCompanyDataParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateKybCompanyData(\"33333333-4444-5555-6666-777777777777\", \"88888888-9999-aaaa-bbbb-cccccccccccc\", SessionsUpdateKybCompanyDataParams.builder()\n        .companyName(\"Docs Probe Corp\")\n        .registrationNumber(\"DPC-001\")\n        .countryCode(\"US\")\n        .incorporationDate(LocalDate.parse(\"2015-04-12\"))\n        .legalAddress(\"1 Example Plaza, Wilmington, DE 19801\")\n        .companyType(\"Limited Liability Company\")\n        .registryStatus(SessionsUpdateKybCompanyDataParams.RegistryStatus.of(\"active\"))\n        .verificationStatus(SessionsUpdateKybCompanyDataParams.VerificationStatus.of(\"verified\"))\n        .natureOfBusiness(\"Software development\")\n        .registeredCapital(\"USD 50000\")\n        .website(\"docsprobe.example.com\")\n        .email(\"legal@docsprobe.example.com\")\n        .phone(\"+1 302 555 0143\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateKybCompanyData('33333333-4444-5555-6666-777777777777', '88888888-9999-aaaa-bbbb-cccccccccccc', [\n    'company_name' => 'Docs Probe Corp',\n    'registration_number' => 'DPC-001',\n    'country_code' => 'US',\n    'incorporation_date' => '2015-04-12',\n    'legal_address' => '1 Example Plaza, Wilmington, DE 19801',\n    'company_type' => 'Limited Liability Company',\n    'registry_status' => 'active',\n    'verification_status' => 'verified',\n    'nature_of_business' => 'Software development',\n    'registered_capital' => 'USD 50000',\n    'website' => 'docsprobe.example.com',\n    'email' => 'legal@docsprobe.example.com',\n    'phone' => '+1 302 555 0143',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_kyb_company_data(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"88888888-9999-aaaa-bbbb-cccccccccccc\",\n  company_name: \"Docs Probe Corp\",\n  registration_number: \"DPC-001\",\n  country_code: \"US\",\n  incorporation_date: \"2015-04-12\",\n  legal_address: \"1 Example Plaza, Wilmington, DE 19801\",\n  company_type: \"Limited Liability Company\",\n  registry_status: \"active\",\n  verification_status: \"verified\",\n  nature_of_business: \"Software development\",\n  registered_capital: \"USD 50000\",\n  website: \"docsprobe.example.com\",\n  email: \"legal@docsprobe.example.com\",\n  phone: \"+1 302 555 0143\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateKybCompanyDataAsync(\"33333333-4444-5555-6666-777777777777\", \"88888888-9999-aaaa-bbbb-cccccccccccc\", new SessionsUpdateKybCompanyDataParams\n{\n    CompanyName = \"Docs Probe Corp\",\n    RegistrationNumber = \"DPC-001\",\n    CountryCode = \"US\",\n    IncorporationDate = \"2015-04-12\",\n    LegalAddress = \"1 Example Plaza, Wilmington, DE 19801\",\n    CompanyType = \"Limited Liability Company\",\n    RegistryStatus = new SessionsUpdateKybCompanyDataParamsRegistryStatus(\"active\"),\n    VerificationStatus = new SessionsUpdateKybCompanyDataParamsVerificationStatus(\"verified\"),\n    NatureOfBusiness = \"Software development\",\n    RegisteredCapital = \"USD 50000\",\n    Website = \"docsprobe.example.com\",\n    Email = \"legal@docsprobe.example.com\",\n    Phone = \"+1 302 555 0143\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/parties/{partyUuid}/": {
      "patch": {
        "summary": "기업 확인(KYB) 세션에서 주요 인물 당사자 건너뛰기(또는 재요구)",
        "description": "주요 인물 당사자를 인증 대상에서 제외하거나 다시 대상에 포함합니다. 이는 자체 검사를 절대 완료할 수 없는 당사자를 위한 운영자 비상 탈출구입니다. 대부분 UBO나 이사에게 전달된 개별 KYC 세션이 삭제되어 해당 하위 세션의 상태가 동결되고 KYB가 `Awaiting User` 상태로 멈춰 더 이상 진행할 수 없게 된 경우에 사용됩니다.\n\n`is_skipped: true`로 설정하면 주요 인물 집계에서 해당 당사자가 제외되고 `KYBKeyPeopleCheck` 및 상위 세션 상태가 즉시 재계산되므로, 기업 세션이 확정된 후 승인되거나 거부될 수 있습니다. `is_skipped: false`를 전송하면 해당 당사자가 다시 대상에 포함되고 검사는 해당 당사자를 다시 대기하게 됩니다.\n\n호스팅 주요 인물 화면의 신청자용 건너뛰기와 달리, 이 endpoint는 역할의 `allow_skip` 설정에 의해 제약받지 **않습니다**. 해당 플래그는 분석가가 재정의할 수 있는 내용이 아니라 신청자가 결정할 수 있는 범위를 제한합니다. `requires_verification`은 의도적으로 변경되지 않은 상태로 유지되므로 재정의된 당사자는 `requires_verification: true` **및** `is_skipped: true`로 표시되며 기록에는 규칙이 요구했던 사항이 그대로 남습니다.\n\n해당 당사자는 경로의 세션에 속해야 하며(그렇지 않은 경우 `\"Party does not belong to the given session.\"`과 함께 `404`), 귀하의 애플리케이션에 속해야 합니다. 실제로 플래그를 변경하는 PATCH 요청은 `console_key_people_skip` 트리거와 함께 기업 세션에서 `data.updated` [webhook](/ko/integration/webhooks)을 발생시킵니다. 플래그를 현재 값과 동일하게 설정하는 PATCH 요청은 당사자 정보를 그대로 에코하는 no-op 작업입니다.\n\nAPI 키 또는 콘솔 사용자 token을 허용하며, 어느 쪽이든 해당 자격 증명에는 `write:businesses` 권한이 필요합니다.",
        "operationId": "patch_v3_session_kyb_party_update",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_kyb_party",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "상위 기업 확인(KYB) 세션의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "partyUuid",
            "in": "path",
            "required": true,
            "description": "업데이트할 주요 인물(Key People) 당사자의 UUID(기업 세션 결정의 `key_people_checks[].submitted.parties[].uuid`)입니다. `sessionId`로 참조되는 세션에 속해 있어야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "is_skipped"
                ],
                "properties": {
                  "is_skipped": {
                    "type": "boolean",
                    "description": "`true`는 해당 당사자를 인증 대상에서 면제하여 이 당사자 없이도 주요 인물 검사를 완료할 수 있도록 합니다. `false`는 다시 인증 대상에 포함합니다.",
                    "example": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "업데이트된 당사자입니다(또는 플래그에 이미 이 값이 설정되어 있었던 경우 변경 없이 그대로 반환됨). 기업 세션 결정의 `key_people_checks[].submitted.parties[]` 항목과 동일한 형태의 당사자를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "주요 인물 당사자 레코드 - 기업 세션 결정의 `key_people_checks[].submitted.parties[]` 항목과 동일한 형태입니다.",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "당사자 식별자입니다."
                    },
                    "entity_type": {
                      "type": "string",
                      "enum": [
                        "person",
                        "company"
                      ],
                      "description": "해당 당사자가 개인인지 기업인지 여부입니다."
                    },
                    "name": {
                      "type": "string",
                      "description": "당사자의 표시 이름입니다."
                    },
                    "is_skipped": {
                      "type": "boolean",
                      "description": "해당 당사자가 인증 면제 대상인지 여부입니다."
                    },
                    "requires_verification": {
                      "type": "boolean",
                      "description": "역할 및 임계값 규칙이 요청한 내용입니다. 이 endpoint에서는 수정되지 않은 상태로 유지됩니다."
                    },
                    "kyc_session_status": {
                      "type": "string",
                      "nullable": true,
                      "description": "연결된 개인 KYC 세션의 상태로, 세션이 삭제된 경우 삭제 시점에 동결됩니다."
                    },
                    "kyc_session_url": {
                      "type": "string",
                      "nullable": true,
                      "description": "연결된 개인 KYC 세션으로의 링크입니다. 없거나 삭제된 경우 `null`입니다."
                    },
                    "kyc_session_deleted": {
                      "type": "boolean",
                      "description": "연결된 개인 KYC 세션이 삭제되어 완료될 수 없습니다."
                    },
                    "kyb_sub_session_deleted": {
                      "type": "boolean",
                      "description": "`kyc_session_deleted`에 대응하는 법인 당사자 이벤트입니다."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "요청 본문의 검증 오류. `is_skipped`는 이 endpoint가 읽는 유일한 필드이며 필수 항목입니다. 필드 오류는 `{\"<field>\": [\"<message>\"]}` 형식으로 전달됩니다. 본문 검증은 당사자 조회 *이후*에 실행되므로, 존재하지 않는 당사자에게 잘못된 형식의 `is_skipped`를 보내면 `400`이 아닌 `404`가 보고됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing is_skipped": {
                    "summary": "빈 본문 또는 `is_skipped`가 생략된 본문",
                    "value": {
                      "is_skipped": [
                        "This field is required."
                      ]
                    }
                  },
                  "Non-boolean is_skipped": {
                    "summary": "불리언(boolean)이 아닌 값(`\"maybe\"`, `2`, `[]`)입니다. 불리언 외에 `\"true\"`/`\"false\"`, `1`/`0`, `\"yes\"`/`\"no\"`도 모두 허용됩니다.",
                    "value": {
                      "is_skipped": [
                        "Must be a valid boolean."
                      ]
                    }
                  },
                  "Null is_skipped": {
                    "summary": "`is_skipped`가 존재하지만 `null`입니다.",
                    "value": {
                      "is_skipped": [
                        "This field may not be null."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나 권한이 부족합니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "자격 증명에 write:businesses 권한이 없습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 당사자이거나 다른 세션에 속한 당사자입니다. 각 케이스마다 별도의 `detail` 메시지가 표시됩니다(예시 참조). 당사자 조회 전에 자격 증명 및 권한 확인이 실행되므로, 승인되지 않은 호출은 `404` 대신 `403`을 반환합니다. 별도의 세션 조회는 제공되지 않으며, 알 수 없는 `sessionId`가 귀사의 당사자와 페어링된 경우 불일치 메시지가 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown party": {
                    "summary": "귀하의 애플리케이션에 이 UUID를 가진 당사자가 없습니다",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Party / session mismatch": {
                    "summary": "partyUuid가 존재하지만 다른 세션에 연결되어 있음",
                    "value": {
                      "detail": "Party does not belong to the given session."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "공유 쓰기 속도 제한을 초과했습니다(API 키당 분당 300개의 POST/PATCH/DELETE 요청). 재시도하기 전에 `Retry-After` 및 `X-RateLimit-*` 응답 헤더를 확인하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "쓰기 예산 소진됨",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_kyb_party(\n    \"33333333-4444-5555-6666-777777777777\",\n    \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n    is_skipped=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateKybParty(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n  {\n    is_skipped: true,\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateKYBParty(ctx, \"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\", didit.SessionsUpdateKYBPartyParams{\n\tIsSkipped: true,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateKybPartyParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateKybParty(\"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\", SessionsUpdateKybPartyParams.builder()\n        .isSkipped(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateKybParty('33333333-4444-5555-6666-777777777777', '0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41', [\n    'is_skipped' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_kyb_party(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n  is_skipped: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateKybPartyAsync(\"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\", new SessionsUpdateKybPartyParams\n{\n    IsSkipped = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/travel-rule/settings/": {
      "get": {
        "summary": "Travel Rule 설정 조회",
        "description": "애플리케이션의 Travel Rule 설정 및 VASP 프로필을 읽습니다. 처음 읽을 때 기본(비활성화) 설정 행과 빈 프로필을 자동으로 생성합니다.",
        "operationId": "getTravelRuleSettings",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "retrieve_settings",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/settings/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.retrieve_settings()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.retrieveSettings();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RetrieveSettings(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().retrieveSettings();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->retrieveSettings();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.retrieve_settings\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RetrieveSettingsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "현재 Travel Rule 설정 및 VASP 프로필입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleSettingsDetail"
                },
                "examples": {
                  "Disabled (default)": {
                    "value": {
                      "is_enabled": false,
                      "jurisdiction": "EU",
                      "name_matching_strictness": "DEFAULT",
                      "confirmation_timeout_hours": 48,
                      "timeout_outcome": "HOLD",
                      "threshold_amount": "0.00",
                      "inbound_auto_accept": true,
                      "allow_self_declaration": true,
                      "allow_screenshot_proof": true,
                      "auto_wallet_verification": true,
                      "vasp_attribution_enabled": true,
                      "legal_name": "",
                      "lei": "",
                      "compliance_email": "",
                      "is_discoverable": true,
                      "counterparty_screening_enabled": false,
                      "sunrise_policy": "",
                      "sunrise_jurisdictions": [
                        "CO",
                        "KH",
                        "VN"
                      ],
                      "non_responsive_policy": "",
                      "travel_address": "",
                      "disabled_networks": [],
                      "networks": {
                        "gtr": {
                          "rail": "GTR",
                          "mode": "unavailable",
                          "state": "didit_onboarding",
                          "reason": "didit_membership_not_live",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        },
                        "trust": {
                          "rail": "TRUST",
                          "mode": "unavailable",
                          "state": "unavailable",
                          "reason": "own_membership_only",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        },
                        "verifyvasp": {
                          "rail": "VERIFYVASP",
                          "mode": "unavailable",
                          "state": "didit_onboarding",
                          "reason": "didit_membership_not_live",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        },
                        "sygna": {
                          "rail": "SYGNA",
                          "mode": "unavailable",
                          "state": "didit_onboarding",
                          "reason": "didit_membership_not_live",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        }
                      },
                      "didit_network": {
                        "listed": false,
                        "missing": [
                          "travel_rule_off",
                          "legal_name_missing",
                          "compliance_email_missing"
                        ],
                        "compliance_email_confirmed": false
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Travel Rule 설정 업데이트",
        "description": "애플리케이션의 Travel Rule 설정 및 VASP 프로필을 업서트(생성 또는 갱신)합니다. 부분 업데이트이므로 변경하려는 필드만 전송하십시오. `is_enabled: true`를 설정하려면 공백이 아닌 `legal_name`(이미 저장되어 있거나 동일한 요청에 포함됨)이 필요하며, 그렇지 않으면 400을 반환합니다.",
        "operationId": "updateTravelRuleSettings",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "update_settings",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleSettingsUpdate"
              },
              "example": {
                "is_enabled": true,
                "legal_name": "Origin CASP SL",
                "jurisdiction": "EU",
                "name_matching_strictness": "DEFAULT",
                "confirmation_timeout_hours": 48,
                "timeout_outcome": "HOLD",
                "is_discoverable": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PUT https://verification.didit.me/v3/travel-rule/settings/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"is_enabled\": true, \"legal_name\": \"Origin CASP SL\", \"jurisdiction\": \"EU\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.update_settings(\n    is_enabled=True,\n    legal_name=\"Origin CASP SL\",\n    jurisdiction=\"EU\",\n    name_matching_strictness=\"DEFAULT\",\n    confirmation_timeout_hours=48,\n    timeout_outcome=\"HOLD\",\n    is_discoverable=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.updateSettings({\n  is_enabled: true,\n  legal_name: \"Origin CASP SL\",\n  jurisdiction: \"EU\",\n  name_matching_strictness: \"DEFAULT\",\n  confirmation_timeout_hours: 48,\n  timeout_outcome: \"HOLD\",\n  is_discoverable: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.UpdateSettings(ctx, didit.TravelRuleSettingsUpdate{\n\tIsEnabled:                didit.Bool(true),\n\tLegalName:                didit.String(\"Origin CASP SL\"),\n\tJurisdiction:             didit.String(\"EU\"),\n\tNameMatchingStrictness:   didit.Some(didit.TravelRuleSettingsUpdateNameMatchingStrictness(\"DEFAULT\")),\n\tConfirmationTimeoutHours: didit.Int(48),\n\tTimeoutOutcome:           didit.Some(didit.TravelRuleSettingsUpdateTimeoutOutcome(\"HOLD\")),\n\tIsDiscoverable:           didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleSettingsUpdate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().updateSettings(TravelRuleSettingsUpdate.builder()\n        .isEnabled(true)\n        .legalName(\"Origin CASP SL\")\n        .jurisdiction(\"EU\")\n        .nameMatchingStrictness(TravelRuleSettingsUpdate.NameMatchingStrictness.of(\"DEFAULT\"))\n        .confirmationTimeoutHours(48L)\n        .timeoutOutcome(TravelRuleSettingsUpdate.TimeoutOutcome.of(\"HOLD\"))\n        .isDiscoverable(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->updateSettings([\n    'is_enabled' => true,\n    'legal_name' => 'Origin CASP SL',\n    'jurisdiction' => 'EU',\n    'name_matching_strictness' => 'DEFAULT',\n    'confirmation_timeout_hours' => 48,\n    'timeout_outcome' => 'HOLD',\n    'is_discoverable' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.update_settings(\n  is_enabled: true,\n  legal_name: \"Origin CASP SL\",\n  jurisdiction: \"EU\",\n  name_matching_strictness: \"DEFAULT\",\n  confirmation_timeout_hours: 48,\n  timeout_outcome: \"HOLD\",\n  is_discoverable: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.UpdateSettingsAsync(new TravelRuleSettingsUpdate\n{\n    IsEnabled = true,\n    LegalName = \"Origin CASP SL\",\n    Jurisdiction = \"EU\",\n    NameMatchingStrictness = new TravelRuleSettingsUpdateNameMatchingStrictness(\"DEFAULT\"),\n    ConfirmationTimeoutHours = 48,\n    TimeoutOutcome = new TravelRuleSettingsUpdateTimeoutOutcome(\"HOLD\"),\n    IsDiscoverable = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "GET과 동일한 형태의 업데이트된 설정 및 프로필입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleSettingsDetail"
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 예: legal_name 없이 활성화, HOLD, REJECT, PROCEED 또는 비어 있는 값 이외의 sunrise_policy 또는 non_responsive_policy 설정, `matching_rules` 내 알 수 없는 필드, 또는 해당 관할권 규정의 송금인 의무를 충족할 수 없는 `data_sharing_fields` 선택(`data_sharing_fields` 아래의 엔티티 유형별로 오류가 키로 지정됨).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "legal_name": [
                    "legal_name is required to enable travel rule."
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/settings/compliance-email/confirmation/": {
      "post": {
        "summary": "컴플라이언스 이메일 확인을 전송합니다",
        "description": "VASP 프로필의 compliance_email로 일회용 확인 링크를 이메일로 전송합니다. 링크를 열고 확인 버튼을 누르면 주소가 확인되며, Didit 네트워크에 프로필이 등록되기 전에 이 과정이 필요합니다. 새 요청을 보내면 이전 링크가 대체되며, 컴플라이언스 이메일이 변경되면 해당 링크는 더 이상 작동하지 않습니다. 주소당 1분에 한 건의 이메일로 제한됩니다.",
        "operationId": "sendTravelRuleComplianceEmailConfirmation",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "send_compliance_email_confirmation",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/settings/compliance-email/confirmation/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.send_compliance_email_confirmation()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.sendComplianceEmailConfirmation();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.SendComplianceEmailConfirmation(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().sendComplianceEmailConfirmation();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->sendComplianceEmailConfirmation();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.send_compliance_email_confirmation\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.SendComplianceEmailConfirmationAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "202": {
            "description": "확인 이메일이 전송되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sent_to": {
                      "type": "string",
                      "format": "email"
                    }
                  }
                },
                "example": {
                  "sent_to": "compliance@your-vasp.example"
                }
              }
            }
          },
          "400": {
            "description": "컴플라이언스 이메일이 설정되지 않았거나 이미 확인되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "No compliance email": {
                    "value": {
                      "compliance_email": [
                        "Set a compliance email before confirming it."
                      ]
                    }
                  },
                  "Already confirmed": {
                    "value": {
                      "compliance_email": [
                        "This compliance email is already confirmed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "1분 미만 전에 이 주소로 확인이 전송되었습니다."
          },
          "503": {
            "description": "이메일을 전송할 수 없습니다. 변경된 사항은 없으므로 잠시 후 다시 시도해 주세요."
          }
        }
      }
    },
    "/v3/travel-rule/wallet-addresses/": {
      "get": {
        "summary": "지갑 주소록 항목 목록 조회",
        "description": "애플리케이션의 Travel Rule 지갑 주소록의 페이지 단위 목록(최신순)입니다.",
        "operationId": "listTravelRuleWalletAddresses",
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_addresses",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/wallet-addresses/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.wallet_addresses.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.walletAddresses.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.WalletAddresses.ListAutoPaging(ctx, didit.TravelRuleWalletAddressesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().walletAddresses().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->travelRule->walletAddresses->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.wallet_addresses.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.WalletAddresses.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "페이지네이션된 지갑 주소록 항목 목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WalletAddressEntry"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "지갑 주소 등록",
        "description": "Travel Rule 지갑 주소록에 항목을 추가하여 인바운드 INTERNAL 레일 송금이 이를 대조하여 처리할 수 있도록 합니다.",
        "operationId": "createTravelRuleWalletAddress",
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_addresses",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WalletAddressEntryCreate"
              },
              "example": {
                "address": "0xBeneficiaryWallet01",
                "chain": "ETH",
                "holder_name": "Ana Diaz",
                "holder_vendor_data": "user-042",
                "self_declared": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/wallet-addresses/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"address\": \"0xBeneficiaryWallet01\", \"chain\": \"ETH\", \"holder_name\": \"Ana Diaz\", \"self_declared\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.wallet_addresses.create(\n    address=\"0xBeneficiaryWallet01\",\n    chain=\"ETH\",\n    holder_vendor_data=\"user-042\",\n    holder_name=\"Ana Diaz\",\n    self_declared=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.walletAddresses.create({\n  address: \"0xBeneficiaryWallet01\",\n  chain: \"ETH\",\n  holder_vendor_data: \"user-042\",\n  holder_name: \"Ana Diaz\",\n  self_declared: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.WalletAddresses.Create(ctx, didit.WalletAddressEntryCreate{\n\tAddress:          \"0xBeneficiaryWallet01\",\n\tChain:            didit.String(\"ETH\"),\n\tHolderVendorData: didit.String(\"user-042\"),\n\tHolderName:       didit.String(\"Ana Diaz\"),\n\tSelfDeclared:     didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.WalletAddressEntryCreate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().walletAddresses().create(WalletAddressEntryCreate.builder()\n        .address(\"0xBeneficiaryWallet01\")\n        .chain(\"ETH\")\n        .holderVendorData(\"user-042\")\n        .holderName(\"Ana Diaz\")\n        .selfDeclared(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->walletAddresses->create([\n    'address' => '0xBeneficiaryWallet01',\n    'chain' => 'ETH',\n    'holder_vendor_data' => 'user-042',\n    'holder_name' => 'Ana Diaz',\n    'self_declared' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.wallet_addresses.create(\n  address: \"0xBeneficiaryWallet01\",\n  chain: \"ETH\",\n  holder_vendor_data: \"user-042\",\n  holder_name: \"Ana Diaz\",\n  self_declared: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.WalletAddresses.CreateAsync(new WalletAddressEntryCreate\n{\n    Address = \"0xBeneficiaryWallet01\",\n    Chain = \"ETH\",\n    HolderVendorData = \"user-042\",\n    HolderName = \"Ana Diaz\",\n    SelfDeclared = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "생성된 항목입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletAddressEntry"
                }
              }
            }
          },
          "400": {
            "description": "이 애플리케이션에 대한 중복 지갑(주소, 체인 및 메모), 체인에서 지원할 수 없는 메모 또는 X-address, 누락된 `address`, 유효하지 않은 `travel_address`, `allow_self_declaration`이 꺼져 있는 동안의 `self_declared: true`, 또는 `ownership_validation_mode`가 `FULL`인 동안의 `self_declared: true`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "Duplicate entry": {
                    "value": {
                      "address": [
                        "A wallet address entry with this address and chain already exists."
                      ]
                    }
                  },
                  "Invalid travel address": {
                    "value": {
                      "travel_address": [
                        "Invalid travel address."
                      ]
                    }
                  },
                  "Self-declaration disabled": {
                    "value": {
                      "self_declared": [
                        "Self-declared ownership is disabled for this application."
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/wallet-addresses/{entry_uuid}/": {
      "patch": {
        "summary": "지갑 주소 소유자 메타데이터 업데이트",
        "description": "holder_name, holder_vendor_data, entity_type 및 travel_address의 부분 업데이트입니다. travel_address를 설정하면 항목에 TRP 라우팅 주소가 연결되며, 유효하지 않은 값은 400으로 거부됩니다. 응답에는 이 네 가지 필드만 그대로 반환됩니다.",
        "operationId": "updateTravelRuleWalletAddress",
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_addresses",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "entry_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WalletAddressEntryUpdate"
              },
              "example": {
                "holder_name": "Ana Updated",
                "travel_address": "ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH https://verification.didit.me/v3/travel-rule/wallet-addresses/{entry_uuid}/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"holder_name\": \"Ana Updated\", \"travel_address\": \"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.wallet_addresses.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    holder_name=\"Ana Updated\",\n    travel_address=\"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.walletAddresses.update(\"11111111-2222-3333-4444-555555555555\", {\n  holder_name: \"Ana Updated\",\n  travel_address: \"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.WalletAddresses.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.WalletAddressEntryUpdateParam{\n\tHolderName:    didit.String(\"Ana Updated\"),\n\tTravelAddress: didit.String(\"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.WalletAddressEntryUpdate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().walletAddresses().update(\"11111111-2222-3333-4444-555555555555\", WalletAddressEntryUpdate.builder()\n        .holderName(\"Ana Updated\")\n        .travelAddress(\"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->walletAddresses->update('11111111-2222-3333-4444-555555555555', [\n    'holder_name' => 'Ana Updated',\n    'travel_address' => 'ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.wallet_addresses.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  holder_name: \"Ana Updated\",\n  travel_address: \"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.WalletAddresses.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new WalletAddressEntryUpdate\n{\n    HolderName = \"Ana Updated\",\n    TravelAddress = \"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "업데이트된 필드입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletAddressEntryUpdate"
                }
              }
            }
          },
          "400": {
            "description": "`travel_address`이(가) 유효한 Travel Address가 아닙니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid travel address": {
                    "value": {
                      "travel_address": [
                        "Invalid travel address."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "알 수 없거나 삭제된 항목입니다."
          }
        }
      },
      "delete": {
        "summary": "지갑 주소 삭제",
        "description": "소유권 증명 및 저장된 스크린샷과 함께 해당 항목을 삭제합니다. 새 전송에 대한 일치가 즉시 중단되며 주소는 재등록을 위해 해제됩니다. 지갑을 이미 사용한 전송은 자체 기록을 유지하며 동일하게 조회됩니다. 삭제는 되돌릴 수 없습니다.",
        "operationId": "deleteTravelRuleWalletAddress",
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_addresses",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "entry_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE https://verification.didit.me/v3/travel-rule/wallet-addresses/{entry_uuid}/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.travel_rule.wallet_addresses.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.travelRule.walletAddresses.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.TravelRule.WalletAddresses.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.travelRule().walletAddresses().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->travelRule->walletAddresses->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.wallet_addresses.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.TravelRule.WalletAddresses.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ],
        "responses": {
          "204": {
            "description": "삭제되었습니다."
          },
          "404": {
            "description": "알 수 없거나 이미 삭제된 항목입니다."
          },
          "503": {
            "description": "`wallet_address_deletion_incomplete`: 저장된 파일을 삭제할 수 없어 삭제가 완료되기 전에 중단되었습니다. 주소록 항목은 여전히 남아 있습니다. 완료하려면 동일한 요청을 재시도하십시오.",
            "content": {
              "application/json": {
                "example": {
                  "detail": "A stored file could not be deleted, so the deletion stopped before it finished. Try again.",
                  "code": "wallet_address_deletion_incomplete"
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/vasps/": {
      "get": {
        "summary": "VASP 디렉터리 검색",
        "description": "VASP 디렉터리의 이름순 정렬 페이지네이션 검색: Didit이 ESMA 임시 MiCA 등록부, 공개 TRISA 디렉터리, 글로벌 LEI 등록부 및 자체 큐레이션을 통해 구축한 공유 디렉터리 항목과 Didit 네트워크 멤버가 포함됩니다. 각 행에는 현재 귀하의 애플리케이션이 해당 항목에 대해 보유한 라우트가 포함됩니다. 귀하 애플리케이션 자체의 프로필은 절대 나열되지 않습니다. 또한 행에는 공유 실사 평가와 귀하 애플리케이션 자체의 결정, 엔터티 스크리닝 및 설문지가 포함됩니다.",
        "operationId": "listTravelRuleVasps",
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "이름 또는 별칭의 일부(대소문자 구분 없음), 정확한 LEI 또는 도메인(example.com 또는 해당 도메인의 URL)입니다. Didit 네트워크 멤버는 법적 이름, LEI 또는 컴플라이언스 이메일 도메인을 기준으로 일치 여부를 확인합니다."
          },
          {
            "name": "network",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "GTR",
                "TRUST",
                "VERIFYVASP",
                "SYGNA",
                "TRISA"
              ]
            },
            "description": "네트워크의 멤버 디렉터리에 현재 나열된 디렉터리 항목만 해당합니다."
          },
          {
            "name": "jurisdiction",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO 3166 alpha-2 또는 alpha-3 국가 코드입니다. 그 외의 값은 400을 반환합니다."
          },
          {
            "name": "reachable",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "true: 귀하의 애플리케이션에서 도달 가능한 경로가 있는 VASP만 해당(Didit 네트워크 멤버 포함). false: 현재 도달할 수 없는 디렉터리 항목만 해당."
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "directory",
                "didit"
              ]
            },
            "description": "디렉터리 항목만, 또는 Didit 네트워크 멤버만 해당합니다."
          },
          {
            "name": "risk",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "LOW",
                "MEDIUM",
                "HIGH"
              ]
            },
            "description": "risk_level이 이 구간에 해당하는 디렉터리 항목만 해당합니다. 점수가 산정되지 않는 Didit 네트워크 멤버는 일치하지 않습니다."
          },
          {
            "name": "responsiveness",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "RESPONSIVE",
                "UNRESPONSIVE",
                "UNKNOWN"
              ]
            },
            "description": "responsiveness.status가 이 값인 디렉터리 항목만 해당합니다. Didit 네트워크 멤버는 일치하지 않습니다."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/travel-rule/vasps/?search=counterparty&reachable=true' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.list_vasps():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.listVasps()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.ListVASPsAutoPaging(ctx, didit.TravelRuleListVASPsParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().listVasps()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->travelRule->listVasps() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.list_vasps.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.ListVaspsAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "이름순으로 정렬된 페이지네이션된 VASP 디렉터리 결과입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VaspDirectoryEntry"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "필터가 유효하지 않습니다. 요청 본문에 각 필드가 명시됩니다(예: 알 수 없는 네트워크, 국가 코드, 위험 등급 또는 응답 상태).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "jurisdiction": [
                    "Use an ISO 3166 alpha-2 or alpha-3 country code."
                  ],
                  "network": [
                    "\"SWIFT\" is not a valid choice."
                  ]
                }
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "list_vasps",
          "auth": "api_key",
          "server": true
        }
      }
    },
    "/v3/travel-rule/vasps/{vasp_id}/": {
      "get": {
        "summary": "VASP 디렉터리 항목 조회",
        "description": "검색에서 반환된 ID 기준 디렉터리 항목 또는 Didit 네트워크 멤버 1개이며, 동일한 필드 및 애플리케이션에서 해당 항목으로 연결되는 경로가 포함됩니다.",
        "operationId": "getTravelRuleVasp",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "retrieve_vasp",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "GET /v3/travel-rule/vasps/ 행의 id입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.retrieve_vasp(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.retrieveVasp(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RetrieveVASP(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().retrieveVasp(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->retrieveVasp('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.retrieve_vasp(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RetrieveVaspAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "항목입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VaspDirectoryEntry"
                }
              }
            }
          },
          "404": {
            "description": "이 id를 가진 항목 또는 등록된 Didit 네트워크 멤버가 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry has this id."
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/vasps/{vasp_id}/decision/": {
      "get": {
        "summary": "VASP에 대한 결정 가져오기",
        "description": "거래 상대방(디렉터리 항목 또는 Didit 네트워크 멤버)에 대한 귀하 애플리케이션의 결정(approved, restricted 또는 blocked)입니다. 자체 결정이 없는 브랜드 소속 엔티티는 inherited_from에 명시된 브랜드의 결정을 따릅니다. 귀하의 애플리케이션에만 비공개로 유지됩니다.",
        "operationId": "getTravelRuleVaspDecision",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "retrieve_vasp_decision",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "GET /v3/travel-rule/vasps/ 행의 id: 디렉터리 항목 또는 Didit 네트워크 멤버입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/decision/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.retrieve_vasp_decision(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.retrieveVaspDecision(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RetrieveVASPDecision(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().retrieveVaspDecision(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->retrieveVaspDecision('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.retrieve_vasp_decision(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RetrieveVaspDecisionAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "적용되는 결정 또는 null입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyDecisionResponse"
                },
                "examples": {
                  "Own decision": {
                    "value": {
                      "decision": {
                        "decision": "APPROVED",
                        "reason": "Licensed in DE, questionnaire reviewed",
                        "decided_by": "",
                        "updated_at": "2026-10-14T10:05:00Z",
                        "inherited_from": null
                      }
                    }
                  },
                  "Inherited from the brand": {
                    "value": {
                      "decision": {
                        "decision": "BLOCKED",
                        "reason": "Group refused after review",
                        "decided_by": "",
                        "updated_at": "2026-10-14T10:05:00Z",
                        "inherited_from": {
                          "id": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",
                          "name": "Example Group"
                        }
                      }
                    }
                  },
                  "No decision": {
                    "value": {
                      "decision": null
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 id를 가진 디렉터리 항목 또는 등록된 Didit 네트워크 멤버가 없습니다. 귀하 자신의 VASP 프로필은 귀하의 거래 상대방이 될 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry or Didit network member has this id."
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "VASP에 대한 결정을 설정합니다",
        "description": "거래 상대방에 대한 애플리케이션의 결정을 내리거나 변경합니다(APPROVED, RESTRICTED 또는 BLOCKED, 사유는 선택 사항임). 공유 디렉터리 항목은 변경되지 않으며 오직 거래 규칙(counterparty_dd_status)을 통해서만 작동합니다. 브랜드에 대한 결정은 자체 결정이 없는 해당 브랜드의 각 엔티티에도 적용됩니다.",
        "operationId": "updateTravelRuleVaspDecision",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "update_vasp_decision",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "GET /v3/travel-rule/vasps/ 행의 id: 디렉터리 항목 또는 Didit 네트워크 멤버입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleCounterpartyDecisionRequest"
              },
              "example": {
                "decision": "BLOCKED",
                "reason": "Unlicensed in its home jurisdiction"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PUT https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/decision/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"decision\": \"BLOCKED\", \"reason\": \"Unlicensed in its home jurisdiction\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.update_vasp_decision(\n    \"11111111-2222-3333-4444-555555555555\",\n    decision=\"BLOCKED\",\n    reason=\"Unlicensed in its home jurisdiction\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.updateVaspDecision(\"11111111-2222-3333-4444-555555555555\", {\n  decision: \"BLOCKED\",\n  reason: \"Unlicensed in its home jurisdiction\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.UpdateVASPDecision(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleCounterpartyDecisionRequest{\n\tDecision: \"BLOCKED\",\n\tReason:   didit.String(\"Unlicensed in its home jurisdiction\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleCounterpartyDecisionRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().updateVaspDecision(\"11111111-2222-3333-4444-555555555555\", TravelRuleCounterpartyDecisionRequest.builder()\n        .decision(TravelRuleCounterpartyDecisionRequest.Decision.of(\"BLOCKED\"))\n        .reason(\"Unlicensed in its home jurisdiction\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->updateVaspDecision('11111111-2222-3333-4444-555555555555', [\n    'decision' => 'BLOCKED',\n    'reason' => 'Unlicensed in its home jurisdiction',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.update_vasp_decision(\n  \"11111111-2222-3333-4444-555555555555\",\n  decision: \"BLOCKED\",\n  reason: \"Unlicensed in its home jurisdiction\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.UpdateVaspDecisionAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleCounterpartyDecisionRequest\n{\n    Decision = \"BLOCKED\",\n    Reason = \"Unlicensed in its home jurisdiction\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "현재 적용되는 결정입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyDecisionResponse"
                },
                "example": {
                  "decision": {
                    "decision": "BLOCKED",
                    "reason": "Unlicensed in its home jurisdiction",
                    "decided_by": "",
                    "updated_at": "2026-10-14T10:05:00Z",
                    "inherited_from": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "결정이 누락되었거나 APPROVED, RESTRICTED, BLOCKED 중 하나가 아니거나, 사유가 255자를 초과합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "decision": [
                    "\"MAYBE\" is not a valid choice."
                  ]
                }
              }
            }
          },
          "404": {
            "description": "이 id를 가진 디렉터리 항목 또는 등록된 Didit 네트워크 멤버가 없습니다. 귀하 자신의 VASP 프로필은 귀하의 거래 상대방이 될 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry or Didit network member has this id."
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "VASP에 대한 결정 지우기",
        "description": "거래 상대방에 대한 애플리케이션 자체의 결정을 지웁니다. 응답에는 이후 적용되는 결정이 표시됩니다. null이거나 브랜드 엔터티의 경우 엔터티가 다시 따르게 되는 브랜드의 결정이 표시됩니다.",
        "operationId": "clearTravelRuleVaspDecision",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "clear_vasp_decision",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "GET /v3/travel-rule/vasps/ 행의 id: 디렉터리 항목 또는 Didit 네트워크 멤버입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/decision/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.clear_vasp_decision(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.clearVaspDecision(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.ClearVASPDecision(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().clearVaspDecision(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->clearVaspDecision('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.clear_vasp_decision(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.ClearVaspDecisionAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "결정이 해제되었습니다. 본문에는 현재 적용되는 결정이 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyDecisionResponse"
                },
                "example": {
                  "decision": null
                }
              }
            }
          },
          "404": {
            "description": "이 id를 가진 거래 상대방이 없거나, 귀하의 애플리케이션 자체의 결정이 없습니다(브랜드로부터 상속받기만 한 결정은 여기서 삭제할 수 없으므로 브랜드의 결정을 삭제해야 합니다).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Unknown id": {
                    "value": {
                      "detail": "No directory entry or Didit network member has this id."
                    }
                  },
                  "No decision of its own": {
                    "value": {
                      "detail": "This application has no decision of its own on this counterparty."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/vasps/{vasp_id}/screening/": {
      "get": {
        "summary": "VASP 엔티티 스크리닝 조회",
        "description": "애플리케이션에 거래 상대방 스크리닝이 활성화되어 있는지 여부, 조직에 부과되는 1회 스크리닝 비용, 결과 유효 기간, 그리고 거래 상대방에 대한 최신 제재 및 부정적 언론 보도 스크리닝 정보입니다. 조회는 무료입니다.",
        "operationId": "getTravelRuleVaspScreening",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "retrieve_vasp_screening",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "GET /v3/travel-rule/vasps/ 행의 id: 디렉터리 항목 또는 Didit 네트워크 멤버입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/screening/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.retrieve_vasp_screening(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.retrieveVaspScreening(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RetrieveVASPScreening(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().retrieveVaspScreening(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->retrieveVaspScreening('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.retrieve_vasp_screening(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RetrieveVaspScreeningAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "귀하의 스크리닝 설정, 가격 및 최근 스크리닝 내역입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyScreeningStatus"
                },
                "example": {
                  "enabled": true,
                  "price": "0.20",
                  "fresh_days": 30,
                  "screening": {
                    "id": "7a1d2c3b-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                    "status": "Approved",
                    "total_hits": 0,
                    "score": null,
                    "screened_at": "2026-10-14T09:58:00Z",
                    "fresh": true,
                    "flagged": false
                  }
                }
              }
            }
          },
          "403": {
            "description": "조직의 계약에 거래 상대방 스크리닝에 대한 요율이 구성되어 있지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No contract rate is configured for this usage type."
                }
              }
            }
          },
          "404": {
            "description": "이 id를 가진 디렉터리 항목 또는 등록된 Didit 네트워크 멤버가 없습니다. 귀하 자신의 VASP 프로필은 귀하의 거래 상대방이 될 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry or Didit network member has this id."
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "VASP 스크리닝",
        "description": "애플케이션을 위해 거래 상대방 엔티티를 제재 및 부정적 언론 보도에 대해 스크리닝합니다. 옵트인: Travel Rule 설정에서 counterparty_screening_enabled가 켜져 있어야 합니다. 새로운 스크리닝마다 조직의 기업 AML 스크리닝 가격으로 청구되며, refresh: true를 전송하지 않는 한 30일 이내의 스크리닝이 대신 반환됩니다(200, 청구되지 않음). 거래 상대방 스크리닝은 애플케이션당 한 번에 하나씩 실행됩니다. 결과는 해당 애플케이션에만 비공개로 유지됩니다. 샌드박스 애플케이션은 스크리닝되지 않습니다.",
        "operationId": "screenTravelRuleVasp",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "screen_vasp",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "GET /v3/travel-rule/vasps/ 행의 id: 디렉터리 항목 또는 Didit 네트워크 멤버입니다."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleCounterpartyScreeningRequest"
              },
              "example": {
                "refresh": false
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/screening/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"refresh\": false}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.screen_vasp(\n    \"11111111-2222-3333-4444-555555555555\",\n    refresh=False,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.screenVasp(\"11111111-2222-3333-4444-555555555555\", {\n  refresh: false,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.ScreenVASP(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleCounterpartyScreeningRequest{\n\tRefresh: didit.Bool(false),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleCounterpartyScreeningRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().screenVasp(\"11111111-2222-3333-4444-555555555555\", TravelRuleCounterpartyScreeningRequest.builder()\n        .refresh(false)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->screenVasp('11111111-2222-3333-4444-555555555555', [\n    'refresh' => false,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.screen_vasp(\n  \"11111111-2222-3333-4444-555555555555\",\n  refresh: false\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.ScreenVaspAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleCounterpartyScreeningRequest\n{\n    Refresh = false,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "최신 스크리닝이 이미 존재하여 해당 결과가 반환되었습니다. 요금이 청구되지 않았습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyScreeningResult"
                },
                "example": {
                  "outcome": "reused",
                  "screening": {
                    "id": "7a1d2c3b-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                    "status": "Approved",
                    "total_hits": 0,
                    "score": null,
                    "screened_at": "2026-10-14T09:58:00Z",
                    "fresh": true,
                    "flagged": false
                  }
                }
              }
            }
          },
          "201": {
            "description": "새로운 스크리닝이 실행되었으며 청구되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyScreeningResult"
                },
                "example": {
                  "outcome": "screened",
                  "screening": {
                    "id": "7a1d2c3b-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                    "status": "In Review",
                    "total_hits": 2,
                    "score": 85.0,
                    "screened_at": "2026-10-14T09:58:00Z",
                    "fresh": true,
                    "flagged": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "본문이 유효하지 않거나, 거래 상대방에게 스크리닝할 이름이 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": [
                    "This counterparty has no name to screen."
                  ]
                }
              }
            }
          },
          "403": {
            "description": "조직의 잔액이 스크리닝 비용을 충당할 수 없거나(코드 insufficient_credits, 아무 작업도 실행되지 않았으며 비용이 청구되지 않음), 계약에 해당 작업에 대한 요율이 구성되지 않았습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "You don't have enough credits to perform this request. Please top up at https://business.didit.me",
                  "code": "insufficient_credits"
                }
              }
            }
          },
          "404": {
            "description": "이 id를 가진 디렉터리 항목 또는 등록된 Didit 네트워크 멤버가 없습니다. 귀하 자신의 VASP 프로필은 귀하의 거래 상대방이 될 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry or Didit network member has this id."
                }
              }
            }
          },
          "409": {
            "description": "아무것도 실행되지 않았으며 비용이 청구되지 않았습니다. 애플리케이션에 거래 상대방 스크리닝이 꺼져 있거나, 애플리케이션이 샌드박스 애플리케이션이거나, 이 거래 상대방에 대한 스크리닝이 이미 실행 중입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Screening off": {
                    "value": {
                      "detail": "Counterparty screening is turned off. Enable it in the Travel Rule settings first."
                    }
                  },
                  "Sandbox application": {
                    "value": {
                      "detail": "Counterparty screening does not run for sandbox applications."
                    }
                  },
                  "Already running": {
                    "value": {
                      "detail": "A screening of this counterparty is already running. Try again in a moment."
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "스크리닝을 완료할 수 없습니다. 청구되지 않았으며, 잠시 후 다시 시도해 주세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "The screening provider did not answer. Try again in a moment."
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/vasps/{vasp_id}/questionnaires/": {
      "get": {
        "summary": "VASP와의 실사 설문지 목록 조회",
        "description": "애플리케이션이 거래 상대방에게 보낸 모든 고객 실사 설문지(최신순)와 해당 상태 및 답변 완료 시 답변 내용입니다. 애플리케이션에만 비공개입니다.",
        "operationId": "listTravelRuleVaspQuestionnaires",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "list_vasp_questionnaires",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "GET /v3/travel-rule/vasps/ 행의 id: 디렉터리 항목 또는 Didit 네트워크 멤버입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/questionnaires/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.list_vasp_questionnaires(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.listVaspQuestionnaires(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.ListVASPQuestionnaires(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().listVaspQuestionnaires(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->listVaspQuestionnaires('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.list_vasp_questionnaires(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.ListVaspQuestionnairesAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "이 거래 상대방과의 설문지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyQuestionnaireList"
                },
                "example": {
                  "questionnaires": [
                    {
                      "id": "3f9e8d7c-6b5a-4c3d-9e2f-1a0b9c8d7e6f",
                      "status": "SENT",
                      "form_version": "1",
                      "sent_to": "travelrule@counterparty.example",
                      "sent_at": "2026-10-14T10:00:00Z",
                      "expires_at": "2026-11-13T10:00:00Z",
                      "answered_at": null,
                      "valid_until": null,
                      "current": false,
                      "answers": {}
                    },
                    {
                      "id": "8b7a6c5d-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
                      "status": "ANSWERED",
                      "form_version": "1",
                      "sent_to": "travelrule@counterparty.example",
                      "sent_at": "2026-09-02T08:00:00Z",
                      "expires_at": "2026-10-02T08:00:00Z",
                      "answered_at": "2026-09-04T15:20:00Z",
                      "valid_until": "2027-09-04T15:20:00Z",
                      "current": true,
                      "answers": {
                        "legal_name": "Example Counterparty VASP, incorporated in the example jurisdiction.",
                        "licensing": "Crypto-asset service provider authorised under MiCA by its national regulator, licence active.",
                        "jurisdictions": "EU and EEA. We do not serve the United States.",
                        "aml_program": "Written AML/CFT policy, annual independent review, last completed in March 2026.",
                        "compliance_officer": "Head of Compliance, reachable at compliance@counterparty.example.",
                        "sanctions_screening": "Customers at onboarding and daily; counterparties on every transfer.",
                        "transaction_monitoring": "Rule-based monitoring with analyst review; suspicious activity reports filed with the FIU.",
                        "travel_rule": "TRP and email; we answer requests within one business day.",
                        "custody": "Segregated customer wallets held with a qualified custodian, insured.",
                        "ownership": "No shareholder holds 25 percent or more; parent company Example Holding Group.",
                        "record_keeping": "Five-year record-keeping for Travel Rule and transaction data, as our regulator requires.",
                        "data_protection": "Encrypted at rest and in transit, stored in the EU."
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "이 id를 가진 디렉터리 항목 또는 등록된 Didit 네트워크 멤버가 없습니다. 귀하 자신의 VASP 프로필은 귀하의 거래 상대방이 될 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry or Didit network member has this id."
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "VASP에 실사 설문지 전송",
        "description": "거래 상대방의 등록된 컴플라이언스 주소로 일회용 답변 링크가 포함된 Didit의 표준 실사 설문지를 이메일로 발송합니다. 거래 상대방은 30일 이내에 모든 질문에 답변해야 하며, 답변은 365일 동안 유지됩니다. 새로 발송하면 동일한 거래 상대방에게 보냈던 이전 미답변 설문지가 대체되며 해당 링크는 작동을 중단합니다. 주소당 1분에 한 번씩 발송할 수 있습니다.",
        "operationId": "sendTravelRuleVaspQuestionnaire",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "send_vasp_questionnaire",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "GET /v3/travel-rule/vasps/ 행의 id: 디렉터리 항목 또는 Didit 네트워크 멤버입니다."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleCounterpartyQuestionnaireRequest"
              },
              "example": {
                "sent_to": "travelrule@counterparty.example"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/questionnaires/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"sent_to\": \"travelrule@counterparty.example\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.send_vasp_questionnaire(\n    \"11111111-2222-3333-4444-555555555555\",\n    sent_to=\"travelrule@counterparty.example\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.sendVaspQuestionnaire(\"11111111-2222-3333-4444-555555555555\", {\n  sent_to: \"travelrule@counterparty.example\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.SendVASPQuestionnaire(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleCounterpartyQuestionnaireRequest{\n\tSentTo: didit.String(\"travelrule@counterparty.example\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleCounterpartyQuestionnaireRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().sendVaspQuestionnaire(\"11111111-2222-3333-4444-555555555555\", TravelRuleCounterpartyQuestionnaireRequest.builder()\n        .sentTo(\"travelrule@counterparty.example\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->sendVaspQuestionnaire('11111111-2222-3333-4444-555555555555', [\n    'sent_to' => 'travelrule@counterparty.example',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.send_vasp_questionnaire(\n  \"11111111-2222-3333-4444-555555555555\",\n  sent_to: \"travelrule@counterparty.example\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.SendVaspQuestionnaireAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleCounterpartyQuestionnaireRequest\n{\n    SentTo = \"travelrule@counterparty.example\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "202": {
            "description": "설문지가 이메일로 전송되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyQuestionnaire"
                },
                "example": {
                  "id": "3f9e8d7c-6b5a-4c3d-9e2f-1a0b9c8d7e6f",
                  "status": "SENT",
                  "form_version": "1",
                  "sent_to": "travelrule@counterparty.example",
                  "sent_at": "2026-10-14T10:00:00Z",
                  "expires_at": "2026-11-13T10:00:00Z",
                  "answered_at": null,
                  "valid_until": null,
                  "current": false,
                  "answers": {}
                }
              }
            }
          },
          "400": {
            "description": "sent_to가 유효한 이메일 주소가 아니거나 거래 상대방의 등록된 컴플라이언스 주소가 아닙니다. 또는 거래 상대방에게 등록된 컴플라이언스 주소가 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not on record": {
                    "value": {
                      "sent_to": [
                        "Send the questionnaire to a compliance address on record for this counterparty."
                      ]
                    }
                  },
                  "No address": {
                    "value": {
                      "sent_to": [
                        "No compliance address is on record for this counterparty. Add a contact for it first."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 id를 가진 디렉터리 항목 또는 등록된 Didit 네트워크 멤버가 없습니다. 귀하 자신의 VASP 프로필은 귀하의 거래 상대방이 될 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry or Didit network member has this id."
                }
              }
            }
          },
          "429": {
            "description": "1분 이내에 이 주소로 설문지가 발송되었습니다."
          },
          "503": {
            "description": "이메일을 전송할 수 없었으며 설문지가 생성되지 않았습니다. 잠시 후 다시 시도해 주세요."
          }
        }
      }
    },
    "/v3/transactions/{transaction_id}/travel-rule/": {
      "patch": {
        "summary": "Travel Rule 전송을 완료, 취소 또는 재전송하거나 송금인 지갑을 업데이트",
        "description": "온체인 해시를 보고하고 아웃바운드 COMPLETED 전송을 FINISHED로 이동하려면 `payment_txn_id`를 제공하고(해당 INTERNAL 레일 상대 항목도 FINISHED로 이동함), 종료되지 않은 전송을 취소하려면 `{\"action\": \"cancel\"}`을 제공하거나, COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE 또는 NOT_ENOUGH_COUNTERPARTY_DATA 상태에 머물러 있는 아웃바운드 전송을 다시 라우팅하려면 `{\"action\": \"resend\"}`를 제공하세요(먼저 거래 상대방 데이터를 개선해야 합니다. 예: 대상 지갑 항목에 travel_address 추가). resend는 아웃바운드 전송에만 적용됩니다. `{\"action\": \"update_compliance_email\", \"compliance_email\": \"desk@example.com\"}`은 해당 세 가지 상태 중 하나에 있는 아웃바운드 전송의 컴플라이언스 이메일을 교체하며, 이는 `reason: email_undeliverable`에 대한 해결책입니다. 상태는 변경되지 않으며 다음 `resend` 시 해당 주소로 요청이 전송됩니다. 재전송은 요청 내에서 직접 실행되지 않고 대기열에 추가됩니다. 응답에는 전송이 `resend queued` 타임라인 항목 및 대기열에 추가된 `delivery`와 함께 AWAITING_COUNTERPARTY 상태로 돌아간 것으로 표시되며, 어디로 전송되었는지는 `travel_rule.status.updated` webhook으로 전달됩니다. 전송이 GTR, VerifyVASP 또는 Sygna Bridge를 통해 이루어진 경우 네트워크는 응답 후 재시도를 통해 온체인 해시 또는 취소 여부를 파악합니다. `delivery`는 해당 메시지의 상태를 보여줍니다. `{\"action\": \"update_originator_wallet\", \"wallet_address\": \"...\"}`는 아웃바운드 전송 시 실제로 자금이 출금된 지갑(예: 선언한 기본 지갑 대신 UTXO 출금이 브로드캐스트된 주소)을 기록합니다. 이는 기록만 변경할 뿐 거래 상대방에게 다시 전송되는 것은 없으며 상태도 유지됩니다. 송금인은 `source: updated`가 설정된 `chain_details.originator`가 되고, 이전 지갑 및 새 지갑과 함께 변경 사항이 `timeline`에 추가되며, 해당 전송의 INTERNAL 레일 상대 항목도 동일한 방식으로 업데이트됩니다. `{\"action\": \"beneficiary_vasp\", \"beneficiary_vasp\": \"<directory VASP id>\"}`는 COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE 또는 NOT_ENOUGH_COUNTERPARTY_DATA 상태의 아웃바운드 전송에서 탐색을 통해 찾을 수 없었던 거래 상대방을 직접 지정합니다. 전송은 해당 VASP로 라우팅되어 다시 전송됩니다.",
        "operationId": "patchTravelRuleTransfer",
        "x-didit-sdk": {
          "resource": "transactions.travel_rule",
          "method": "update_transfer",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "해당 이체를 소유한 Didit 고유 거래 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleTransferPatchRequest"
              },
              "examples": {
                "Finish": {
                  "value": {
                    "payment_txn_id": "0xchainhash"
                  }
                },
                "Cancel": {
                  "value": {
                    "action": "cancel"
                  }
                },
                "Resend": {
                  "value": {
                    "action": "resend"
                  }
                },
                "Update compliance email": {
                  "value": {
                    "action": "update_compliance_email",
                    "compliance_email": "desk@example.com"
                  }
                },
                "Update originator wallet": {
                  "value": {
                    "action": "update_originator_wallet",
                    "wallet_address": "bc1qOriginatorInputAddress01"
                  }
                },
                "Name the counterparty": {
                  "value": {
                    "action": "beneficiary_vasp",
                    "beneficiary_vasp": "9f1c2b34-5d6e-4f70-8a91-b2c3d4e5f607"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"payment_txn_id\": \"0xchainhash\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.update_transfer(\n    \"11111111-2222-3333-4444-555555555555\",\n    payment_txn_id=\"0xchainhash\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.updateTransfer(\"11111111-2222-3333-4444-555555555555\", {\n  payment_txn_id: \"0xchainhash\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.UpdateTransfer(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleTransferPatchRequest{\n\tPaymentTxnID: didit.String(\"0xchainhash\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleTransferPatchRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().updateTransfer(\"11111111-2222-3333-4444-555555555555\", TravelRuleTransferPatchRequest.builder()\n        .paymentTxnId(\"0xchainhash\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->travelRule->updateTransfer('11111111-2222-3333-4444-555555555555', [\n    'payment_txn_id' => '0xchainhash',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.travel_rule.update_transfer(\n  \"11111111-2222-3333-4444-555555555555\",\n  payment_txn_id: \"0xchainhash\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.UpdateTransferAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleTransferPatchRequest\n{\n    PaymentTxnId = \"0xchainhash\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "업데이트된 전송 내역입니다. `update_compliance_email` 이후에도 상태는 변경되지 않으며 다음 `resend` 전까지 `reason: email_undeliverable` 상태를 유지합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleTransferDetail"
                }
              }
            }
          },
          "400": {
            "description": "payment_txn_id와 지원되는 작업이 모두 제공되지 않았거나, `update_compliance_email`에서 `compliance_email`이 누락되었거나 이메일 주소가 아니거나, `update_originator_wallet`의 경우 wallet_address가 없거나 전송 체인에서 지원할 수 없는 지갑 또는 메모이거나 전송의 UTXO 입력 중 하나가 아닌 지갑이거나, `beneficiary_vasp`가 누락되었거나 유효한 디렉터리 VASP ID가 아닙니다.",
            "content": {
              "application/json": {
                "examples": {
                  "No action": {
                    "value": {
                      "detail": [
                        "Provide payment_txn_id, action=cancel, action=resend, action=beneficiary_vasp, action=update_originator_wallet or action=update_compliance_email."
                      ]
                    }
                  },
                  "Invalid compliance email": {
                    "value": {
                      "compliance_email": [
                        "Enter a valid email address."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 거래이거나, 해당 거래에 Travel Rule 전송 내역이 없거나, (작업 `beneficiary_vasp`) 해당 ID를 가진 디렉터리 항목이 없습니다."
          },
          "409": {
            "description": "전송이 이 작업을 허용하는 상태가 아닙니다(예: finish의 경우 COMPLETED/outbound 상태가 아니거나, cancel의 경우 이미 종료 상태이거나, resend의 경우 재전송 가능한 상태의 아웃바운드 전송이 아님). `update_compliance_email`은 인바운드 전송 및 COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE, NOT_ENOUGH_COUNTERPARTY_DATA 이외의 아웃바운드 전송에 대해 `409`로 응답합니다. `update_originator_wallet`은 인바운드, 취소됨 또는 만료됨 상태의 전송에 대해 `409`로 응답합니다. `beneficiary_vasp`는 전송이 아웃바운드이고 COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE 또는 NOT_ENOUGH_COUNTERPARTY_DATA 상태인 경우를 제외하고 `409`로 응답합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Cancel from a terminal status": {
                    "value": {
                      "detail": "Transfer is already in a terminal state."
                    }
                  },
                  "Resend not allowed": {
                    "value": {
                      "detail": "Transfer cannot be resent from its current state."
                    }
                  },
                  "Finish not allowed": {
                    "value": {
                      "detail": "Transfer must be an outbound transfer in COMPLETED status to finish."
                    }
                  },
                  "Compliance email cannot change": {
                    "value": {
                      "detail": "The compliance email of this transfer cannot change from its current state."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/transactions/{transaction_id}/travel-rule/ownership/": {
      "post": {
        "summary": "지갑 소유권 확인 또는 거부",
        "description": "지갑 소유권 확인을 대기 중인 이체를 처리합니다. 이체가 UNCONFIRMED_OWNERSHIP 상태이거나 ON_HOLD 상태의 인바운드 이체일 때 자체 측에서 이를 호출합니다. 확인하면 일치하는 지갑 주소록 항목이 소유권 검증됨으로 표시되고(항목이 없는 인바운드 ON_HOLD 이체의 경우 Didit이 beneficiary_data.wallet_address로부터 항목을 생성함), 이체의 양쪽 모두에서 수취인 이름 일치를 실행합니다. 거부하면 양쪽 모두 거부됩니다. 입금이 이미 정산된 인바운드 이체는 일치가 성공하면 FINISHED로 이동합니다. 거래 상대방 지갑이 자체 보관 지갑(counterparty.payment_method.method_type: unhosted_wallet)으로 신고된 경우, 확인하면 고객이 해당 지갑을 제어하는 주체를 확인했음이 기록되고 양방향 모두에서 이체가 완료(COMPLETED)되거나, 온체인 해시가 이미 알려진 인바운드 입금의 경우 FINISHED가 됩니다. 검증된 지갑은 거래 상대방의 지갑입니다. 즉 아웃바운드 출금의 목적지이거나 인바운드 입금의 출처(송금인의 지갑)입니다. 아직 지갑 주소록에 없는 경우 Didit은 거래 상대방 이름 아래 소유권 검증된 상태로 이를 추가합니다. 주소록에 이미 다른 보유자 이름으로 등록되어 있다면 이체는 COUNTERPARTY_MISMATCHED_DATA로 이동합니다. UNCONFIRMED_OWNERSHIP, ON_HOLD 또는 COUNTERPARTY_MISMATCHED_DATA 상태인 인바운드 TRP 이체의 경우, Didit은 대신 귀하의 결정을 송금 VASP로 전송합니다. 승인하면 결제 주소(wallet_address 또는 일치하는 항목의 주소)가 반환되고 이체가 COMPLETED로 이동하며, 거부하면 거부 처리됩니다. 동일한 호출로 GTR 또는 Sygna Bridge 거래 상대방이 전송하여 귀하의 검토를 대기 중인 인바운드 이체(`UNCONFIRMED_OWNERSHIP`, `ON_HOLD` 또는 `COUNTERPARTY_MISMATCHED_DATA`)도 결정합니다. `confirmed: true`는 이를 승인하고(이체에 지정된 주소가 없을 경우 `wallet_address`를 전달), `confirmed: false`는 이를 거부하며, 응답 후 재시도를 포함하여 네트워크에 답변이 전송됩니다. VerifyVASP는 요청 시 즉시 응답을 받으므로, 귀하의 검토가 필요한 VerifyVASP 이체는 즉시 거부되며 나중에 결정할 수 없습니다.",
        "operationId": "confirmTravelRuleOwnership",
        "x-didit-sdk": {
          "resource": "transactions.travel_rule",
          "method": "confirm_ownership",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "애플리케이션이 이 이체에 대해 보유한 거래의 Didit 고유 UUID입니다: INTERNAL 레일 이체의 수취인 측 거래, 또는 상대방 지갑이 자체 보관 지갑으로 신고되었을 때 생성한(송금 또는 수취) 거래입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleOwnershipConfirmRequest"
              },
              "example": {
                "confirmed": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/ownership/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"confirmed\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.confirm_ownership(\n    \"11111111-2222-3333-4444-555555555555\",\n    confirmed=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.confirmOwnership(\"11111111-2222-3333-4444-555555555555\", {\n  confirmed: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.ConfirmOwnership(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleOwnershipConfirmRequest{\n\tConfirmed: true,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleOwnershipConfirmRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().confirmOwnership(\"11111111-2222-3333-4444-555555555555\", TravelRuleOwnershipConfirmRequest.builder()\n        .confirmed(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->travelRule->confirmOwnership('11111111-2222-3333-4444-555555555555', [\n    'confirmed' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.travel_rule.confirm_ownership(\n  \"11111111-2222-3333-4444-555555555555\",\n  confirmed: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.ConfirmOwnershipAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleOwnershipConfirmRequest\n{\n    Confirmed = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "업데이트된 전송 내역입니다. 인바운드 전송의 경우 소유권이 확인될 때까지 거래 상대방의 originator_data/beneficiary_data는 마스킹 처리(`data_masked: true`)된 상태로 유지되며, 확인 후 `data_unmasked`에 언제, 왜, 누구에 의해 해제되었는지가 기록됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleTransferDetail"
                }
              }
            }
          },
          "409": {
            "description": "전송이 소유권 확인 대기 중이 아니거나, 상대방 지갑과 일치하는 지갑 주소록 항목이 없거나, 다른 Didit 고객으로부터의 INTERNAL 전송을 확인하기 전에 제어 증명(서명된 메시지 또는 테스트 입금)이 필요하거나, 네트워크 전송이 해당 네트워크를 통해 이미 응답된 상태입니다(VerifyVASP 전송, 또는 귀하 또는 Didit이 이미 결정을 내린 GTR 또는 Sygna Bridge 전송).",
            "content": {
              "application/json": {
                "examples": {
                  "Not awaiting confirmation": {
                    "value": {
                      "detail": "Transfer is not awaiting ownership confirmation."
                    }
                  },
                  "No matching address book entry": {
                    "value": {
                      "detail": "wallet address entry no longer available"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류: confirmed가 누락되었거나, 인바운드 TRP 승인에 wallet_address가 없고 대체할 주소도 없거나, 거래 상대방 지갑을 지정하지 않고 `wallet_address`도 전송되지 않은 신고된 자체 보관 지갑 전송에 `confirmed: true`가 설정되어 있습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "No payment address": {
                    "value": {
                      "wallet_address": [
                        "wallet_address is required to approve."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 거래이거나, 해당 거래에 Travel Rule 전송 내역이 없습니다."
          },
          "502": {
            "description": "인바운드 TRP 전송 전용: Didit이 송금인 VASP에 결정을 전송할 수 없어 전송 상태가 변경되지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Callback not delivered": {
                    "value": {
                      "detail": "Counterparty inquiry-resolution callback could not be delivered."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/transactions/{transaction_id}/travel-rule/messages/": {
      "get": {
        "summary": "Travel Rule 메시지 목록 조회",
        "description": "이번 이체와 관련하여 거래 상대방 VASP와 주고받은 메시지 및 문서 요청입니다.",
        "operationId": "listTravelRuleMessages",
        "x-didit-sdk": {
          "resource": "transactions.travel_rule",
          "method": "list_messages",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "해당 이체를 소유한 Didit 고유 거래 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/messages/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.list_messages(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.listMessages(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.ListMessages(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().listMessages(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->travelRule->listMessages('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.travel_rule.list_messages(\"11111111-2222-3333-4444-555555555555\").each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.ListMessagesAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "오래된 순으로 정렬된 메시지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TravelRuleMessage"
                  }
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 거래 또는 token이거나, 해당 거래에 Travel Rule 전송 내역이 없습니다."
          }
        }
      },
      "post": {
        "summary": "Travel Rule 메시지 또는 문서 요청 전송",
        "description": "거래 상대방 VASP에 메시지 또는 문서 요청을 전송합니다. INTERNAL 전송(상대방 Didit 고객이 해당 페어의 자기 측에서 확인) 및 EMAIL 전송(거래 상대방에게 이메일이 발송되고 픽업 포털에서 답변)에서 작동합니다. TRP, GTR, TRUST, VerifyVASP 또는 Sygna를 통한 전송에는 해당 프로토콜 자체에 메시지 기능이 없으므로 메시지가 포함되지 않습니다. 제한: 전송당 메시지 100개, 본문당 5000자, 요청 문서 10개, 각 10 MB 파일 5개.",
        "operationId": "createTravelRuleMessage",
        "x-didit-sdk": {
          "resource": "transactions.travel_rule",
          "method": "create_message",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "해당 이체를 소유한 Didit 고유 거래 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleMessageCreateRequest"
              },
              "example": {
                "kind": "DOCUMENT_REQUEST",
                "body": "Please confirm the date of birth of the beneficiary.",
                "requested_documents": [
                  "Proof of address"
                ]
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleMessageCreateRequest"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/messages/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"kind\": \"DOCUMENT_REQUEST\", \"body\": \"Please confirm the date of birth of the beneficiary.\", \"requested_documents\": [\"Proof of address\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.create_message(\n    \"11111111-2222-3333-4444-555555555555\",\n    kind=\"DOCUMENT_REQUEST\",\n    body=\"Please confirm the date of birth of the beneficiary.\",\n    requested_documents=[\"Proof of address\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.createMessage(\"11111111-2222-3333-4444-555555555555\", {\n  kind: \"DOCUMENT_REQUEST\",\n  body: \"Please confirm the date of birth of the beneficiary.\",\n  requested_documents: [\"Proof of address\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.CreateMessage(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleMessageCreateRequest{\n\tKind:               didit.Some(didit.TravelRuleMessageCreateRequestKind(\"DOCUMENT_REQUEST\")),\n\tBody:               didit.String(\"Please confirm the date of birth of the beneficiary.\"),\n\tRequestedDocuments: didit.Some([]string{\"Proof of address\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.TravelRuleMessageCreateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().createMessage(\"11111111-2222-3333-4444-555555555555\", TravelRuleMessageCreateRequest.builder()\n        .kind(TravelRuleMessageCreateRequest.Kind.of(\"DOCUMENT_REQUEST\"))\n        .body(\"Please confirm the date of birth of the beneficiary.\")\n        .requestedDocuments(List.of(\"Proof of address\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->travelRule->createMessage('11111111-2222-3333-4444-555555555555', [\n    'kind' => 'DOCUMENT_REQUEST',\n    'body' => 'Please confirm the date of birth of the beneficiary.',\n    'requested_documents' => ['Proof of address'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.travel_rule.create_message(\n  \"11111111-2222-3333-4444-555555555555\",\n  kind: \"DOCUMENT_REQUEST\",\n  body: \"Please confirm the date of birth of the beneficiary.\",\n  requested_documents: [\"Proof of address\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.CreateMessageAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleMessageCreateRequest\n{\n    Kind = new TravelRuleMessageCreateRequestKind(\"DOCUMENT_REQUEST\"),\n    Body = \"Please confirm the date of birth of the beneficiary.\",\n    RequestedDocuments = new string[] { \"Proof of address\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "저장된 메시지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleMessage"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 본문, 허용되지 않는 파일 형식 또는 크기, 전송 건당 100개를 초과하는 메시지, 또는 해당 전송의 메시지가 아닌 `reply_to`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "requested_documents": [
                    "Name at least one document the counterparty should send."
                  ]
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 거래 또는 token이거나, 해당 거래에 Travel Rule 전송 내역이 없습니다."
          },
          "409": {
            "description": "거래 상대방에게 메시지가 도달할 수 없습니다. `detail`에 이유가 표시됩니다. 전송이 네트워크 레일(TRP, GTR, TRUST, VerifyVASP 또는 Sygna)을 통해 실행 중이거나, 거래 상대방이 아직 없거나, INTERNAL 전송의 데이터가 지갑 소유자와 일치하지 않아 수취인에게 도달하지 못했거나, EMAIL 전송의 수령 링크가 만료되었거나 전송이 종료되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/pickup/{token}/": {
      "get": {
        "summary": "이메일 레일 픽업 정보 조회",
        "description": "공개, 비인증. Didit을 사용하지 않는 거래 상대방 VASP가 이메일로 수신한 픽업 링크를 통해 대기 중인 교환 건을 미리 볼 수 있도록 합니다. token 자체가 인증 역할을 합니다.",
        "operationId": "getTravelRulePickup",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "retrieve_pickup",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "contact",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "링크의 `?contact=` 값으로, 링크가 전송된 연락처입니다. `contact`로 변경 없이 그대로 반환되며, 검증되지 않습니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl https://verification.didit.me/v3/travel-rule/pickup/{token}/"
          }
        ],
        "responses": {
          "200": {
            "description": "수령 미리보기입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRulePickupInfo"
                },
                "example": {
                  "reference": "33333333-4444-5555-6666-777777777777",
                  "requested_at": "2026-07-05T10:00:00Z",
                  "originator_vasp_name": "Origin CASP SL",
                  "originator_vasp_lei": "529900EXAMPLEORIG001",
                  "recipient_vasp_name": "Example Counterparty VASP",
                  "language": "es",
                  "amount": "0.250000000000000000",
                  "currency": "ETH",
                  "fiat_amount": "",
                  "fiat_currency": "",
                  "chain": "ETH",
                  "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
                  "status": "AWAITING_COUNTERPARTY",
                  "ivms_version": "ivms101.2023",
                  "deadline_at": "2026-07-07T10:00:00Z",
                  "reminders_sent": 0,
                  "contact": "",
                  "decline_reasons": [
                    "data_mismatch",
                    "not_our_customer",
                    "wallet_not_hosted",
                    "sanctions",
                    "risk_appetite",
                    "jurisdiction",
                    "insufficient_data",
                    "other"
                  ],
                  "join_invitation": {
                    "eligible": false,
                    "url": ""
                  },
                  "originator_data": {
                    "name": "Jane Doe",
                    "wallet_address": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7"
                  },
                  "beneficiary_data": {
                    "name": "Ana Diaz",
                    "wallet_address": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb"
                  },
                  "ivms_request": {
                    "originator": {
                      "originatorPersons": [
                        {
                          "naturalPerson": {
                            "name": {
                              "nameIdentifier": [
                                {
                                  "primaryIdentifier": "Doe",
                                  "secondaryIdentifier": "Jane",
                                  "nameIdentifierType": "LEGL"
                                }
                              ]
                            }
                          }
                        }
                      ],
                      "accountNumber": [
                        "0x77ccff0cc624a53cd8b8d8703ced826710211ec7"
                      ]
                    },
                    "beneficiary": {
                      "beneficiaryPersons": [
                        {
                          "naturalPerson": {
                            "name": {
                              "nameIdentifier": [
                                {
                                  "primaryIdentifier": "Diaz",
                                  "secondaryIdentifier": "Ana",
                                  "nameIdentifierType": "LEGL"
                                }
                              ]
                            }
                          }
                        }
                      ],
                      "accountNumber": [
                        "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb"
                      ]
                    }
                  },
                  "data_masked": false
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 token입니다."
          },
          "410": {
            "description": "기간이 마감되었습니다. 거래 상대방이 이미 응답했거나, 전송이 AWAITING_COUNTERPARTY 상태를 벗어났거나, 마감 시한이 지났습니다."
          }
        }
      }
    },
    "/v3/travel-rule/pickup/{token}/respond/": {
      "post": {
        "summary": "이메일 레일 픽업에 응답",
        "description": "공개 및 미인증 상태입니다. 이메일로 전송된 수령 링크에서 교환을 수락하거나 거부합니다. 수락 시 beneficiary_name이 송금인의 name_matching_strictness 정책에 따라 검사됩니다.",
        "operationId": "respondTravelRulePickup",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "respond_pickup",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "contact",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "링크의 `?contact=` 값입니다. 본문에서 `contact`를 보내지 않을 때 사용됩니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRulePickupRespondRequest"
              },
              "example": {
                "decision": "accept",
                "beneficiary_name": "Carlos Ruiz"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/pickup/{token}/respond/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"decision\": \"accept\", \"beneficiary_name\": \"Carlos Ruiz\"}'"
          }
        ],
        "responses": {
          "200": {
            "description": "그 결과인 교환 상태: 수락 후에는 COMPLETED 또는 COUNTERPARTY_MISMATCHED_DATA, 거부 후에는 `decline_reason`도 함께 반환하는 COUNTERPARTY_VASP_GENERAL_DECLINE입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "decline_reason": {
                      "type": "string",
                      "description": "거부된 후 표시됩니다."
                    }
                  }
                },
                "examples": {
                  "accepted": {
                    "value": {
                      "status": "COMPLETED"
                    }
                  },
                  "declined": {
                    "value": {
                      "status": "COUNTERPARTY_VASP_GENERAL_DECLINE",
                      "decline_reason": "not_our_customer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "필드가 유효하지 않습니다. 예를 들어 `decision`이 누락되었거나 `accept` 또는 `decline`이 아닌 경우, `decline_reason: other`인 거부에서 `decline_detail`이 누락된 경우, `ivms_response`가 IVMS 101 객체가 아니거나 16384자를 초과하는 경우, 또는 본문의 `contact`가 UUID가 아닌 경우(`{\"contact\": [\"Must be a valid UUID.\"]}`) 등입니다.",
            "content": {
              "application/json": {
                "example": {
                  "decline_detail": [
                    "Say what the reason is when you choose another reason."
                  ]
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 token입니다."
          },
          "410": {
            "description": "기간이 마감되었습니다. 거래 상대방이 이미 응답했거나, 전송이 AWAITING_COUNTERPARTY 상태를 벗어났거나, 마감 시한이 지났습니다."
          }
        }
      }
    },
    "/v3/travel-rule/pickup/{token}/messages/": {
      "get": {
        "summary": "픽업 메시지 목록 조회",
        "description": "공개, 비인증. 거래 상대방 VASP가 읽는 EMAIL-rail 전송 건의 메시지입니다. 고객이 전송한 내용은 `INBOUND`이며 고객의 VASP 이름으로 서명됩니다. token이 인증 역할을 합니다.",
        "operationId": "listTravelRulePickupMessages",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "list_pickup_messages",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl https://verification.didit.me/v3/travel-rule/pickup/{token}/messages/"
          }
        ],
        "responses": {
          "200": {
            "description": "오래된 순으로 정렬된 거래 상대방 측의 메시지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TravelRuleMessage"
                  }
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 token입니다."
          },
          "410": {
            "description": "수령 링크가 만료되었거나 전송이 종료되었습니다."
          }
        }
      },
      "post": {
        "summary": "픽업 포털에서 회신",
        "description": "공개, 비인증. 거래 상대방 VASP가 EMAIL-rail 전송 건에 대해 회신합니다. 거래의 메시지와 동일한 본문이며, 첨부 파일은 PDF, PNG, JPEG 또는 WebP 형식이어야 합니다. token이 인증 역할을 합니다.",
        "operationId": "createTravelRulePickupMessage",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "create_pickup_message",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleMessageCreateRequest"
              },
              "example": {
                "kind": "MESSAGE",
                "body": "Attached is the proof of address of the wallet holder."
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleMessageCreateRequest"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/pickup/{token}/messages/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"kind\": \"MESSAGE\", \"body\": \"Attached is the proof of address of the wallet holder.\"}'"
          }
        ],
        "responses": {
          "201": {
            "description": "저장된 메시지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleMessage"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 본문, 허용되지 않는 파일 형식 또는 크기, 전송 건당 100개를 초과하는 메시지, 또는 해당 전송의 메시지가 아닌 `reply_to`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "requested_documents": [
                    "Name at least one document the counterparty should send."
                  ]
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 token입니다."
          },
          "410": {
            "description": "수령 링크가 만료되었거나 전송이 종료되었습니다."
          }
        }
      }
    },
    "/v3/travel-rule/inbound/": {
      "post": {
        "summary": "입금 후(선라이즈) 인바운드 전송 등록",
        "description": "어떠한 거래소 거래도 이루어지기 전에 이미 온체인에서 결제된 암호화폐 입금에 대한 Travel Rule 데이터를 등록합니다. 인바운드 travelRule 거래를 생성하거나(또는 청구되지 않은 입금을 재사용), 지갑 주소록을 기반으로 전송을 확인합니다. 새로 생성된 거래의 경우 Didit은 transaction.created를 먼저 보낸 후 travel_rule.status.updated webhook을 전송합니다.",
        "operationId": "registerTravelRuleInbound",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "register_inbound",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleInboundRequest"
              },
              "example": {
                "chain": "ETH",
                "txid": "0xdeposit-hash",
                "wallet_address": "0xYourDepositWallet",
                "amount": "500.00",
                "currency": "USDC",
                "originator_data": {
                  "name": "Origin CASP SL"
                },
                "beneficiary_data": {
                  "name": "Ana Diaz"
                },
                "originating_vasp": {
                  "name": "Origin CASP SL",
                  "lei": "",
                  "travel_address": "ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/inbound/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"chain\":\"ETH\",\"txid\":\"0xdeposit-hash\",\"wallet_address\":\"0xYourDepositWallet\",\"amount\":\"500.00\",\"currency\":\"USDC\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.register_inbound(\n    chain=\"ETH\",\n    txid=\"0xdeposit-hash\",\n    wallet_address=\"0xYourDepositWallet\",\n    amount=\"500.00\",\n    currency=\"USDC\",\n    originator_data={\"name\": \"Origin CASP SL\"},\n    beneficiary_data={\"name\": \"Ana Diaz\"},\n    originating_vasp={\n        \"name\": \"Origin CASP SL\",\n        \"lei\": \"\",\n        \"travel_address\": \"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\",\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.registerInbound({\n  chain: \"ETH\",\n  txid: \"0xdeposit-hash\",\n  wallet_address: \"0xYourDepositWallet\",\n  amount: \"500.00\",\n  currency: \"USDC\",\n  originator_data: { name: \"Origin CASP SL\" },\n  beneficiary_data: { name: \"Ana Diaz\" },\n  originating_vasp: {\n    name: \"Origin CASP SL\",\n    lei: \"\",\n    travel_address: \"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\",\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RegisterInbound(ctx, didit.TravelRuleInboundRequest{\n\tChain:           \"ETH\",\n\tTxid:            \"0xdeposit-hash\",\n\tWalletAddress:   \"0xYourDepositWallet\",\n\tAmount:          \"500.00\",\n\tCurrency:        \"USDC\",\n\tOriginatorData:  didit.Some(map[string]any{\"name\": \"Origin CASP SL\"}),\n\tBeneficiaryData: didit.Some(map[string]any{\"name\": \"Ana Diaz\"}),\n\tOriginatingVASP: didit.Some(didit.TravelRuleInboundRequestOriginatingVASP{\n\t\tName:          didit.String(\"Origin CASP SL\"),\n\t\tLei:           didit.String(\"\"),\n\t\tTravelAddress: didit.String(\"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\"),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.TravelRuleInboundRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().registerInbound(TravelRuleInboundRequest.builder()\n        .chain(\"ETH\")\n        .txid(\"0xdeposit-hash\")\n        .walletAddress(\"0xYourDepositWallet\")\n        .amount(\"500.00\")\n        .currency(\"USDC\")\n        .originatorData(Map.of(\"name\", \"Origin CASP SL\"))\n        .beneficiaryData(Map.of(\"name\", \"Ana Diaz\"))\n        .originatingVasp(TravelRuleInboundRequest.OriginatingVasp.builder()\n                .name(\"Origin CASP SL\")\n                .lei(\"\")\n                .travelAddress(\"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\")\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->registerInbound([\n    'chain' => 'ETH',\n    'txid' => '0xdeposit-hash',\n    'wallet_address' => '0xYourDepositWallet',\n    'amount' => '500.00',\n    'currency' => 'USDC',\n    'originator_data' => ['name' => 'Origin CASP SL'],\n    'beneficiary_data' => ['name' => 'Ana Diaz'],\n    'originating_vasp' => [\n        'name' => 'Origin CASP SL',\n        'lei' => '',\n        'travel_address' => 'ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC',\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.register_inbound(\n  chain: \"ETH\",\n  txid: \"0xdeposit-hash\",\n  wallet_address: \"0xYourDepositWallet\",\n  amount: \"500.00\",\n  currency: \"USDC\",\n  originator_data: { name: \"Origin CASP SL\" },\n  beneficiary_data: { name: \"Ana Diaz\" },\n  originating_vasp: {\n    name: \"Origin CASP SL\",\n    lei: \"\",\n    travel_address: \"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\",\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RegisterInboundAsync(new TravelRuleInboundRequest\n{\n    Chain = \"ETH\",\n    Txid = \"0xdeposit-hash\",\n    WalletAddress = \"0xYourDepositWallet\",\n    Amount = \"500.00\",\n    Currency = \"USDC\",\n    OriginatorData = new Dictionary<string, object> { [\"name\"] = \"Origin CASP SL\" },\n    BeneficiaryData = new Dictionary<string, object> { [\"name\"] = \"Ana Diaz\" },\n    OriginatingVasp = new TravelRuleInboundRequestOriginatingVasp\n    {\n        Name = \"Origin CASP SL\",\n        Lei = \"\",\n        TravelAddress = \"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "이 txid 및 wallet_address에 대한 이체가 이미 등록되어 있습니다. 기존 이체가 변경 없이 반환됩니다(created는 false입니다).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleInboundResponse"
                }
              }
            }
          },
          "201": {
            "description": "새로운 인바운드 거래 또는 기존의 미청구 입금 건에 대해 새로운 Travel Rule 이체가 등록되었습니다(created는 true).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleInboundResponse"
                }
              }
            }
          },
          "400": {
            "description": "필수 필드(`chain`, `txid`, `wallet_address`, `amount`, `currency`)가 누락되었거나, `originating_vasp.lei`가 유효한 LEI가 아니거나, `originating_vasp.travel_address`가 유효한 Travel Address가 아니거나, 해당 체인에서 지원할 수 없는 메모, X-address 또는 `utxo`가 포함되었거나, `originator_data` / `beneficiary_data`가 객체가 아닙니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing field": {
                    "value": {
                      "txid": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid LEI": {
                    "value": {
                      "originating_vasp": {
                        "lei": [
                          "Invalid LEI: expected 20 alphanumeric characters (ISO 17442)."
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/test-vasp/inbound/": {
      "post": {
        "summary": "Didit Test VASP에서 인바운드 이체 트리거(샌드박스)",
        "description": "샌드박스 애플리케이션 전용입니다. 프로덕션 환경으로 전환하기 전에 거래소의 수신 측을 엔드투엔드로 테스트할 수 있도록 Didit Test VASP가 애플리케이션에 인바운드 Travel Rule 전송을 보냅니다. 전송은 실제 네트워크의 인바운드 전송이 지갑 주소록을 대상으로 실행하는 것과 동일한 로직으로 예약되고 결정되므로, 수신함, 결정 및 지갑 소유 구조 절차가 프로덕션 환경과 동일하게 작동합니다. Didit 외부로 아무것도 나가지 않습니다. 프로덕션 환경 애플리케이션은 400을 수신합니다. 두 번째 전송을 생성하는 대신 첫 번째 호출이 예약한 전송을 가져오려면 동일한 `reference`를 다시 보내십시오.",
        "operationId": "triggerTravelRuleTestVaspInbound",
        "x-didit-sdk": {
          "resource": "transactions.travel_rule",
          "method": "trigger_test_vasp_inbound",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleTestVaspInboundRequest"
              },
              "example": {
                "beneficiary_wallet_address": "0xYourSandboxWallet",
                "scenario": "accept",
                "amount": "1",
                "reference": "demo-001"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/test-vasp/inbound/ \\\n  -H 'x-api-key: YOUR_SANDBOX_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"beneficiary_wallet_address\":\"0xYourSandboxWallet\",\"scenario\":\"accept\",\"reference\":\"demo-001\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.trigger_test_vasp_inbound(\n    beneficiary_wallet_address=\"0xYourSandboxWallet\",\n    scenario=\"accept\",\n    amount=\"1\",\n    reference=\"demo-001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.triggerTestVaspInbound({\n  beneficiary_wallet_address: \"0xYourSandboxWallet\",\n  scenario: \"accept\",\n  amount: \"1\",\n  reference: \"demo-001\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.TriggerTestVASPInbound(ctx, didit.TravelRuleTestVASPInboundRequest{\n\tBeneficiaryWalletAddress: \"0xYourSandboxWallet\",\n\tScenario:                 didit.Some(didit.TravelRuleTestVASPInboundRequestScenario(\"accept\")),\n\tAmount:                   didit.String(\"1\"),\n\tReference:                didit.String(\"demo-001\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleTestVaspInboundRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().triggerTestVaspInbound(TravelRuleTestVaspInboundRequest.builder()\n        .beneficiaryWalletAddress(\"0xYourSandboxWallet\")\n        .scenario(TravelRuleTestVaspInboundRequest.Scenario.of(\"accept\"))\n        .amount(\"1\")\n        .reference(\"demo-001\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->travelRule->triggerTestVaspInbound([\n    'beneficiary_wallet_address' => '0xYourSandboxWallet',\n    'scenario' => 'accept',\n    'amount' => '1',\n    'reference' => 'demo-001',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.travel_rule.trigger_test_vasp_inbound(\n  beneficiary_wallet_address: \"0xYourSandboxWallet\",\n  scenario: \"accept\",\n  amount: \"1\",\n  reference: \"demo-001\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.TriggerTestVaspInboundAsync(new TravelRuleTestVaspInboundRequest\n{\n    BeneficiaryWalletAddress = \"0xYourSandboxWallet\",\n    Scenario = new TravelRuleTestVaspInboundRequestScenario(\"accept\"),\n    Amount = \"1\",\n    Reference = \"demo-001\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "인바운드 전송이 기록되고 결정되었습니다. 동일한 `reference`로 반복 요청하면 동일한 body가 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleTestVaspInboundResponse"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 본문, 알 수 없거나 지원되지 않는 `scenario`, 또는 해당 애플리케이션이 프로덕션 애플리케이션인 경우입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "409": {
            "description": "예를 들어 애플리케이션에 Travel Rule이 활성화되어 있지 않아 전송을 기록할 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/widget-session/": {
      "post": {
        "summary": "지갑 소유권 위젯 세션 발급",
        "description": "호스팅 지갑 소유권 위젯 URL/토큰을 생성합니다. 지갑 제어 권한을 증명(메시지 서명, 사토시 테스트, 스크린샷 또는 자체 선언)할 수 있도록 고객을 반환된 url로 안내하십시오. 이 릴리스에서 위젯은 웹 전용입니다. 모바일 SDK 웹뷰 내부가 아닌 시스템 브라우저 또는 커스텀 탭에서 url을 열어야 합니다.",
        "operationId": "createTravelRuleWidgetSession",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "create_widget_session",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleWidgetSessionCreate"
              },
              "example": {
                "wallet_address": "0xd3b62acb76fb27a7f8961ec40fa11746b113aca9",
                "chain": "ETH",
                "holder_name": "Jane Doe",
                "vendor_data": "user-042",
                "transaction_id": "99999999-aaaa-bbbb-cccc-dddddddddddd",
                "expires_in_minutes": 60
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/widget-session/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"wallet_address\":\"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\"chain\":\"ETH\",\"holder_name\":\"Jane Doe\",\"transaction_id\":\"99999999-aaaa-bbbb-cccc-dddddddddddd\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.create_widget_session(\n    wallet_address=\"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\n    chain=\"ETH\",\n    holder_name=\"Jane Doe\",\n    vendor_data=\"user-042\",\n    transaction_id=\"99999999-aaaa-bbbb-cccc-dddddddddddd\",\n    expires_in_minutes=60,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.createWidgetSession({\n  wallet_address: \"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\n  chain: \"ETH\",\n  holder_name: \"Jane Doe\",\n  vendor_data: \"user-042\",\n  transaction_id: \"99999999-aaaa-bbbb-cccc-dddddddddddd\",\n  expires_in_minutes: 60,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.CreateWidgetSession(ctx, didit.TravelRuleWidgetSessionCreate{\n\tWalletAddress:    didit.String(\"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\"),\n\tChain:            didit.String(\"ETH\"),\n\tHolderName:       didit.String(\"Jane Doe\"),\n\tVendorData:       didit.String(\"user-042\"),\n\tTransactionID:    didit.String(\"99999999-aaaa-bbbb-cccc-dddddddddddd\"),\n\tExpiresInMinutes: didit.Int(60),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWidgetSessionCreate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().createWidgetSession(TravelRuleWidgetSessionCreate.builder()\n        .walletAddress(\"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\")\n        .chain(\"ETH\")\n        .holderName(\"Jane Doe\")\n        .vendorData(\"user-042\")\n        .transactionId(\"99999999-aaaa-bbbb-cccc-dddddddddddd\")\n        .expiresInMinutes(60L)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->createWidgetSession([\n    'wallet_address' => '0xd3b62acb76fb27a7f8961ec40fa11746b113aca9',\n    'chain' => 'ETH',\n    'holder_name' => 'Jane Doe',\n    'vendor_data' => 'user-042',\n    'transaction_id' => '99999999-aaaa-bbbb-cccc-dddddddddddd',\n    'expires_in_minutes' => 60,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.create_widget_session(\n  wallet_address: \"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\n  chain: \"ETH\",\n  holder_name: \"Jane Doe\",\n  vendor_data: \"user-042\",\n  transaction_id: \"99999999-aaaa-bbbb-cccc-dddddddddddd\",\n  expires_in_minutes: 60\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.CreateWidgetSessionAsync(new TravelRuleWidgetSessionCreate\n{\n    WalletAddress = \"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\n    Chain = \"ETH\",\n    HolderName = \"Jane Doe\",\n    VendorData = \"user-042\",\n    TransactionId = \"99999999-aaaa-bbbb-cccc-dddddddddddd\",\n    ExpiresInMinutes = 60,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "발급된 위젯 세션입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetSessionResponse"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 본문: `callback_url`이 절대 http(s) URL이 아니거나, `expires_in_minutes`가 5~10080 범위를 벗어났거나, `transaction_id`가 UUID가 아니거나, 필드가 제한 길이를 초과했습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid callback_url": {
                    "value": {
                      "callback_url": [
                        "callback_url must be an absolute http(s) URL."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`transaction_id`가 이 애플리케이션의 Travel Rule 전송을 지정하지 않습니다."
          }
        }
      }
    },
    "/v3/travel-rule/widget/{token}/": {
      "get": {
        "summary": "지갑 소유권 위젯 컨텍스트 가져오기",
        "description": "위젯 세션 token으로 식별되는 공개 읽기 endpoint이며 API 키가 필요하지 않습니다. 위젯 컨텍스트와 모든 증명의 상태를 반환하므로 폴링하여 완료 여부를 감지할 수 있습니다. 증명이 검증되면 completed_at이 null이 아닌 값이 됩니다. SATOSHI_TEST 증명은 입금이 온체인에서 감지되었으나 아직 확인되지 않은 동안 상태 PENDING에 머무를 수 있습니다. 백그라운드 작업이 자동으로 재확인하고 입금이 확인되면 완료하므로 대기하는 동안 클라이언트 작업이 필요하지 않습니다. 각 증명은 해당 방식에 필요한 필드를 포함합니다: SATOSHI_TEST의 경우 deposit_address, expected_amount, 자체 expires_at, MESSAGE_SIGNING의 경우 challenge. 세션이 전송에 연결되어 있는 경우 폴링보다 travel_rule.status.updated webhook을 사용하는 것이 좋습니다.",
        "operationId": "getTravelRuleWidgetContext",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "retrieve_widget_context",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "위젯 세션이 생성되었을 때 반환된 불투명 세션 token입니다.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl https://verification.didit.me/v3/travel-rule/widget/{token}/"
          }
        ],
        "responses": {
          "200": {
            "description": "위젯 컨텍스트 및 증명 상태입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetContext"
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 token입니다."
          },
          "410": {
            "description": "세션이 완료되지 않고 만료되었습니다."
          }
        }
      }
    },
    "/v3/travel-rule/widget/{token}/vasps/": {
      "get": {
        "summary": "지갑 위젯에서 VASP 검색",
        "description": "위젯 세션 token으로 식별되는 공개 읽기 endpoint이며 API 키가 필요하지 않습니다. 최종 사용자 위젯의 VASP 선택기입니다. 위젯의 애플리케이션에 대한 GET /v3/travel-rule/vasps/와 동일한 검색 및 필터를 사용하며, 각 VASP의 정보와 연결 가능 여부만 응답합니다.",
        "operationId": "listTravelRuleWidgetVasps",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "list_widget_vasps",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "위젯 세션이 생성되었을 때 반환된 불투명 세션 token입니다.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "이름 또는 별칭의 일부(대소문자 구분 없음), 정확한 LEI 또는 도메인(example.com 또는 해당 도메인의 URL)입니다. Didit 네트워크 멤버는 법적 이름, LEI 또는 컴플라이언스 이메일 도메인을 기준으로 일치 여부를 확인합니다."
          },
          {
            "name": "network",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "GTR",
                "TRUST",
                "VERIFYVASP",
                "SYGNA",
                "TRISA"
              ]
            },
            "description": "네트워크의 멤버 디렉터리에 현재 나열된 디렉터리 항목만 해당합니다."
          },
          {
            "name": "jurisdiction",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO 3166 alpha-2 또는 alpha-3 국가 코드입니다. 그 외의 값은 400을 반환합니다."
          },
          {
            "name": "reachable",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "true: 귀하의 애플리케이션에서 도달 가능한 경로가 있는 VASP만 해당(Didit 네트워크 멤버 포함). false: 현재 도달할 수 없는 디렉터리 항목만 해당."
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "directory",
                "didit"
              ]
            },
            "description": "디렉터리 항목만, 또는 Didit 네트워크 멤버만 해당합니다."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl 'https://verification.didit.me/v3/travel-rule/widget/{token}/vasps/?search=counterparty'"
          }
        ],
        "responses": {
          "200": {
            "description": "이름순으로 정렬된 페이지네이션 결과입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VaspDirectoryWidgetEntry"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "필터가 유효하지 않습니다. 요청 본문에 각 필드가 명시됩니다(예: 알 수 없는 네트워크 또는 국가 코드).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "jurisdiction": [
                    "Use an ISO 3166 alpha-2 or alpha-3 country code."
                  ],
                  "network": [
                    "\"SWIFT\" is not a valid choice."
                  ]
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 token입니다."
          },
          "410": {
            "description": "세션이 만료되었습니다."
          }
        }
      },
      "post": {
        "summary": "지갑 위젯에서 거래 상대방 VASP 선택",
        "description": "위젯 세션 token으로 식별되는 공개 쓰기 endpoint이며 API 키가 필요하지 않습니다. 자동 감지로 확인할 수 없었던 대상 VASP를 최종 사용자가 직접 선택한 경우입니다. COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE 또는 NOT_ENOUGH_COUNTERPARTY_DATA 상태의 아웃바운드 전송만 이를 허용합니다. 전송은 해당 VASP로 라우팅되어 다시 발송되며, 자동 감지가 이 선택을 덮어쓰지 않습니다.",
        "operationId": "selectTravelRuleWidgetVasp",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "select_widget_vasp",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "위젯 세션이 생성되었을 때 반환된 불투명 세션 token입니다.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "vasp"
                ],
                "properties": {
                  "vasp": {
                    "type": "string",
                    "format": "uuid",
                    "description": "`GET /v3/travel-rule/widget/{token}/vasps/`에서 가져온 VASP의 `id`입니다."
                  }
                }
              },
              "example": {
                "vasp": "9f1c2b34-5d6e-4f70-8a91-b2c3d4e5f607"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/widget/{token}/vasps/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"vasp\": \"9f1c2b34-5d6e-4f70-8a91-b2c3d4e5f607\"}'"
          }
        ],
        "responses": {
          "200": {
            "description": "선택이 기록되었으며 전송이 다시 실행되는 중입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "transfer_status": {
                      "type": "string",
                      "description": "선택 후의 전송 상태입니다."
                    },
                    "counterparty_vasp": {
                      "type": "string",
                      "description": "최종 사용자가 선택한 VASP의 이름입니다."
                    }
                  }
                },
                "example": {
                  "detail": "Counterparty VASP selected; the transfer is being resent.",
                  "transfer_status": "AWAITING_COUNTERPARTY",
                  "counterparty_vasp": "Northwind Exchange"
                }
              }
            }
          },
          "400": {
            "description": "`vasp`가 누락되었거나 활성 디렉터리 항목에 해당 ID가 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "vasp": [
                    "No directory entry has this id."
                  ]
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 token입니다."
          },
          "409": {
            "description": "위젯 세션이 Travel Rule 전송에 연결되어 있지 않거나, 전송이 거래 상대방을 수락하는 상태의 송신 전송이 아닙니다."
          },
          "410": {
            "description": "세션이 만료되었습니다."
          }
        }
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/vendor-users/toggle-ongoing-monitoring/": {
      "patch": {
        "summary": "사용자에 대한 지속적인 AML 모니터링 토글",
        "description": "사용자 수준에서 지속적인 AML 모니터링을 활성화하거나 비활성화합니다. 사용자당 정확히 하나의 모니터링 대상 AML 스크리닝이 유지됩니다. AML 스크리닝이 전혀 없는 사용자(예: 가져온 사용자)의 경우 먼저 스크리닝이 생성되어 실행되며, 일반 AML 스크리닝으로 청구됩니다. 쓰기 작업 없이 건수와 비용을 미리 보려면 estimate_only를 설정하세요. 20개 이하의 배치는 인라인으로 즉시 처리되고(200, COMPLETED), 더 큰 배치는 202를 반환하며 비동기식으로 실행됩니다.",
        "operationId": "toggle_vendor_users_ongoing_monitoring",
        "x-didit-sdk": {
          "resource": "users",
          "method": "set_ongoing_monitoring",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OngoingMonitoringToggleRequest"
              },
              "example": {
                "is_enabled": true,
                "didit_internal_id_list": [
                  "5b9a0000-0000-4000-8000-00000000f00d"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "견적(estimate_only인 경우) 또는 인라인으로 처리된 소규모 배치에 대한 완료된 작업.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringToggleResult"
                }
              }
            }
          },
          "202": {
            "description": "대규모 배치는 비동기식으로 처리됩니다. 반환된 job_id를 사용하여 작업 endpoint를 폴링하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringJob"
                }
              }
            }
          },
          "403": {
            "description": "write:sessions 권한이 누락되었거나 활성화하기에 잔액이 부족합니다(예상 금액이 오류 본문에 포함됨)."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.users.set_ongoing_monitoring(\n    is_enabled=True,\n    didit_internal_id_list=[\"5b9a0000-0000-4000-8000-00000000f00d\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.users.setOngoingMonitoring({\n  is_enabled: true,\n  didit_internal_id_list: [\"5b9a0000-0000-4000-8000-00000000f00d\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Users.SetOngoingMonitoring(ctx, didit.OngoingMonitoringToggleRequest{\n\tIsEnabled:           true,\n\tDiditInternalIDList: didit.Some([]string{\"5b9a0000-0000-4000-8000-00000000f00d\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.OngoingMonitoringToggleRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.users().setOngoingMonitoring(OngoingMonitoringToggleRequest.builder()\n        .isEnabled(true)\n        .diditInternalIdList(List.of(\"5b9a0000-0000-4000-8000-00000000f00d\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->users->setOngoingMonitoring([\n    'is_enabled' => true,\n    'didit_internal_id_list' => ['5b9a0000-0000-4000-8000-00000000f00d'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.users.set_ongoing_monitoring(\n  is_enabled: true,\n  didit_internal_id_list: [\"5b9a0000-0000-4000-8000-00000000f00d\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Users.SetOngoingMonitoringAsync(new OngoingMonitoringToggleRequest\n{\n    IsEnabled = true,\n    DiditInternalIdList = new string[] { \"5b9a0000-0000-4000-8000-00000000f00d\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/vendor-users/toggle-ongoing-monitoring/{job_id}/": {
      "get": {
        "summary": "지속적인 AML 모니터링 작업 조회",
        "description": "모니터링 전환 작업의 진행 상황 및 결과별 카운터입니다. 상태가 PENDING 또는 PROCESSING인 동안 몇 초마다 폴링하십시오.",
        "operationId": "get_vendor_users_ongoing_monitoring_job",
        "x-didit-sdk": {
          "resource": "users",
          "method": "retrieve_ongoing_monitoring_job",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "토글 endpoint에서 반환된 모니터링 작업 UUID입니다."
          }
        ],
        "responses": {
          "200": {
            "description": "작업입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringJob"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에 대해 알 수 없는 작업입니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.users.retrieve_ongoing_monitoring_job(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.users.retrieveOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Users.RetrieveOngoingMonitoringJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.users().retrieveOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->users->retrieveOngoingMonitoringJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.users.retrieve_ongoing_monitoring_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Users.RetrieveOngoingMonitoringJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/vendor-businesses/toggle-ongoing-monitoring/": {
      "patch": {
        "summary": "기업에 대한 지속적인 AML 모니터링 토글",
        "description": "사용자 토글의 기업 수준에 해당하는 항목입니다. 기업당 하나의 모니터링 대상 AML 스크리닝이 수행되며, AML 스크리닝 이력이 없는 기업(기업 엔티티)이 먼저 스크리닝됩니다. estimate_only, 인라인 빠른 경로 및 비동기 작업 규약은 동일합니다.",
        "operationId": "toggle_vendor_businesses_ongoing_monitoring",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "set_ongoing_monitoring",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OngoingMonitoringToggleRequest"
              },
              "example": {
                "is_enabled": true,
                "didit_internal_id_list": [
                  "b0000000-0000-4000-8000-0000000000b1"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "견적(estimate_only인 경우) 또는 인라인으로 처리된 소규모 배치에 대한 완료된 작업.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringToggleResult"
                }
              }
            }
          },
          "202": {
            "description": "대규모 배치는 비동기식으로 처리됩니다. 반환된 job_id를 사용하여 작업 endpoint를 폴링하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringJob"
                }
              }
            }
          },
          "403": {
            "description": "write:sessions 권한이 누락되었거나 활성화하기에 잔액이 부족합니다(예상 금액이 오류 본문에 포함됨)."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.set_ongoing_monitoring(\n    is_enabled=True,\n    didit_internal_id_list=[\"b0000000-0000-4000-8000-0000000000b1\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.setOngoingMonitoring({\n  is_enabled: true,\n  didit_internal_id_list: [\"b0000000-0000-4000-8000-0000000000b1\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.SetOngoingMonitoring(ctx, didit.OngoingMonitoringToggleRequest{\n\tIsEnabled:           true,\n\tDiditInternalIDList: didit.Some([]string{\"b0000000-0000-4000-8000-0000000000b1\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.OngoingMonitoringToggleRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().setOngoingMonitoring(OngoingMonitoringToggleRequest.builder()\n        .isEnabled(true)\n        .diditInternalIdList(List.of(\"b0000000-0000-4000-8000-0000000000b1\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->businesses->setOngoingMonitoring([\n    'is_enabled' => true,\n    'didit_internal_id_list' => ['b0000000-0000-4000-8000-0000000000b1'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.set_ongoing_monitoring(\n  is_enabled: true,\n  didit_internal_id_list: [\"b0000000-0000-4000-8000-0000000000b1\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.SetOngoingMonitoringAsync(new OngoingMonitoringToggleRequest\n{\n    IsEnabled = true,\n    DiditInternalIdList = new string[] { \"b0000000-0000-4000-8000-0000000000b1\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/vendor-businesses/toggle-ongoing-monitoring/{job_id}/": {
      "get": {
        "summary": "지속적인 AML 모니터링 작업 조회",
        "description": "모니터링 전환 작업의 진행 상황 및 결과별 카운터입니다. 상태가 PENDING 또는 PROCESSING인 동안 몇 초마다 폴링하십시오.",
        "operationId": "get_vendor_businesses_ongoing_monitoring_job",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "retrieve_ongoing_monitoring_job",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "토글 endpoint에서 반환된 모니터링 작업 UUID입니다."
          }
        ],
        "responses": {
          "200": {
            "description": "작업입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringJob"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에 대해 알 수 없는 작업입니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.retrieve_ongoing_monitoring_job(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.retrieveOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.RetrieveOngoingMonitoringJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().retrieveOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->businesses->retrieveOngoingMonitoringJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.retrieve_ongoing_monitoring_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.RetrieveOngoingMonitoringJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/businesses/toggle-ongoing-monitoring/": {
      "patch": {
        "summary": "기업 세션에 대한 지속적인 AML 모니터링 토글",
        "description": "세션 번호로 지정하는 KYB 인증용 세션 수준 토글입니다. AML 스크리닝이 없는 세션은 스크리닝이 하나 생성되어 세션 자체에 연결됩니다. 사용자 수준 endpoint와 동일한 estimate_only, 인라인 빠른 경로 및 비동기 작업 규약을 따릅니다. AML 스크리닝이 없는 세션을 건너뛰던 기존 동기식 동작을 대체합니다.",
        "operationId": "toggle_business_sessions_ongoing_monitoring",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "set_session_ongoing_monitoring",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "is_enabled"
                ],
                "properties": {
                  "is_enabled": {
                    "type": "boolean",
                    "description": "모니터링을 활성화하려면 true, 비활성화하려면 false입니다."
                  },
                  "estimate_only": {
                    "type": "boolean",
                    "default": false,
                    "description": "true인 경우, 예상 비용을 반환하며 쓰기 작업을 수행하지 않습니다."
                  },
                  "update_all": {
                    "type": "boolean",
                    "default": false,
                    "description": "애플리케이션의 모든 엔티티에 적용됩니다(있는 경우 filter_* 파라미터로 범위가 지정됨)."
                  },
                  "filter_search": {
                    "type": "string"
                  },
                  "filter_status": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "filter_country": {
                    "type": "string"
                  },
                  "filter_date_from": {
                    "type": "string",
                    "format": "date"
                  },
                  "filter_date_to": {
                    "type": "string",
                    "format": "date"
                  },
                  "session_numbers": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "전환할 기업 세션 번호입니다. update_all(또는 레거시 toggle_all 별칭)이 true가 아닌 경우 필수입니다."
                  },
                  "toggle_all": {
                    "type": "boolean",
                    "default": false,
                    "description": "update_all의 레거시 별칭입니다."
                  },
                  "filter_workflow_id": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "is_enabled": true,
                "session_numbers": [
                  "1001",
                  "1002"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "견적(estimate_only인 경우) 또는 인라인으로 처리된 소규모 배치에 대한 완료된 작업.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringToggleResult"
                }
              }
            }
          },
          "202": {
            "description": "대규모 배치는 비동기식으로 처리됩니다. 반환된 job_id를 사용하여 작업 endpoint를 폴링하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringJob"
                }
              }
            }
          },
          "403": {
            "description": "write:sessions 권한이 누락되었거나 활성화하기에 잔액이 부족합니다(예상 금액이 오류 본문에 포함됨)."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.set_session_ongoing_monitoring(\n    is_enabled=True,\n    session_numbers=[\"1001\", \"1002\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.setSessionOngoingMonitoring({\n  is_enabled: true,\n  session_numbers: [\"1001\", \"1002\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.SetSessionOngoingMonitoring(ctx, didit.BusinessesSetSessionOngoingMonitoringParams{\n\tIsEnabled:      true,\n\tSessionNumbers: didit.Some([]string{\"1001\", \"1002\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.BusinessesSetSessionOngoingMonitoringParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().setSessionOngoingMonitoring(BusinessesSetSessionOngoingMonitoringParams.builder()\n        .isEnabled(true)\n        .sessionNumbers(List.of(\"1001\", \"1002\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->businesses->setSessionOngoingMonitoring([\n    'is_enabled' => true,\n    'session_numbers' => ['1001', '1002'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.set_session_ongoing_monitoring(\n  is_enabled: true,\n  session_numbers: [\"1001\", \"1002\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.SetSessionOngoingMonitoringAsync(new BusinessesSetSessionOngoingMonitoringParams\n{\n    IsEnabled = true,\n    SessionNumbers = new string[] { \"1001\", \"1002\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/businesses/toggle-ongoing-monitoring/{job_id}/": {
      "get": {
        "summary": "지속적인 AML 모니터링 작업 조회",
        "description": "모니터링 전환 작업의 진행 상황 및 결과별 카운터입니다. 상태가 PENDING 또는 PROCESSING인 동안 몇 초마다 폴링하십시오.",
        "operationId": "get_business_sessions_ongoing_monitoring_job",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "retrieve_session_ongoing_monitoring_job",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "토글 endpoint에서 반환된 모니터링 작업 UUID입니다."
          }
        ],
        "responses": {
          "200": {
            "description": "작업입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringJob"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에 대해 알 수 없는 작업입니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.retrieve_session_ongoing_monitoring_job(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.retrieveSessionOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.RetrieveSessionOngoingMonitoringJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().retrieveSessionOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->businesses->retrieveSessionOngoingMonitoringJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.retrieve_session_ongoing_monitoring_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.RetrieveSessionOngoingMonitoringJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/": {
      "get": {
        "summary": "케이스 목록 조회",
        "description": "애플리케이션의 케이스 목록을 최신순으로 조회합니다. 필터링, 검색, 정렬을 지원하며 쿼리 파라미터를 참고하십시오. `limit`/`offset`을 사용한 페이지네이션이 적용됩니다.",
        "operationId": "list_cases",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "페이지 크기입니다. 기본값은 50입니다."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "첫 번째 레코드의 0부터 시작하는 오프셋입니다."
          },
          {
            "name": "status__in",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "포함할 쉼표로 구분된 상태입니다(예: OPEN,AWAITING_USER)."
          },
          {
            "name": "priority",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "포함할 쉼표로 구분된 우선순위입니다."
          },
          {
            "name": "source__in",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "포함할 쉼표로 구분된 소스입니다."
          },
          {
            "name": "blueprint",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "이 블루프린트의 케이스로 필터링합니다."
          },
          {
            "name": "assigned_to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "이 사용자에게 배정된 케이스로 필터링합니다."
          },
          {
            "name": "unassigned",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "할당되지 않은 케이스의 경우 true, 할당된 케이스의 경우 false입니다."
          },
          {
            "name": "tag",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "이 정확한 태그가 지정된 케이스로 필터링합니다."
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "제목, case_number, 태그, 대상자 성명/UUID/외부 ID, 연결된 세션 UUID 또는 연결된 거래 UUID와 일치합니다."
          },
          {
            "name": "date_from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "생성 일시 하한값(해당 값 포함)."
          },
          {
            "name": "date_to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "생성 일시 상한값(해당 값 포함)."
          },
          {
            "name": "due_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "due_at 상한값입니다."
          },
          {
            "name": "overdue",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "기한이 지난 open/awaiting-user 케이스만 반환하려면 true입니다."
          },
          {
            "name": "ordering",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "created_at",
                "-created_at",
                "due_at",
                "-due_at"
              ],
              "default": "-created_at"
            },
            "description": "정렬 순서입니다. due_at은 null 값을 마지막으로 정렬합니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/?status__in=OPEN,AWAITING_USER&ordering=-due_at' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.ListAutoPaging(ctx, didit.CasesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "페이지 단위로 제공되는 케이스 목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "일치하는 행의 수입니다. 최대 100개까지는 정확하며, 성능상의 이유로 100개를 초과하면 100으로 제한됩니다. 마지막 페이지를 감지하려면 `next`가 null인지 확인하십시오."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "다음 페이지의 절대 URL이거나 null입니다."
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "이전 페이지의 절대 URL이거나 null입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaseListItem"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "케이스 생성",
        "description": "직접 지정하거나 연결된 세션/거래 링크에서 대상을 파생하여 정확히 하나의 대상(사용자 또는 기업)에 고정된 케이스를 생성합니다. API로 생성된 케이스의 소스는 항상 `MANUAL`입니다.",
        "operationId": "create_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "title"
                ],
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "blueprint": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "CaseBlueprint UUID. 블루프린트가 없는 경우 생략합니다."
                  },
                  "priority": {
                    "type": "string",
                    "enum": [
                      "LOW",
                      "MEDIUM",
                      "HIGH"
                    ],
                    "default": "MEDIUM"
                  },
                  "due_at": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "subject": {
                    "type": "object",
                    "description": "links가 제공되지 않으면 필수입니다. 케이스의 정확히 하나의 대상입니다.",
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "user",
                          "business"
                        ]
                      },
                      "uuid": {
                        "type": "string",
                        "format": "uuid"
                      }
                    }
                  },
                  "links": {
                    "type": "array",
                    "description": "생성 시 연결할 세션/기업 세션/거래입니다(예: [{\"entity_type\": \"transaction\", \"entity_uuid\": \"...\"}]). subject가 생략된 경우, 첫 번째 링크의 소유자로부터 subject가 파생됩니다.",
                    "items": {
                      "type": "object"
                    }
                  },
                  "assigned_to": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "즉시 할당할 사용자 UUID입니다."
                  },
                  "review_duplicates": {
                    "type": "boolean",
                    "default": false,
                    "description": "케이스를 생성하기 전에 기존 조사를 다시 확인합니다. true인 경우 기존 케이스가 있는 대상에 대해 비어 있지 않은 separate_incident_reason이 필요합니다. 콘솔에서는 항상 이 보호 기능이 활성화됩니다. 이를 생략하면 기존 API 동작이 유지됩니다."
                  },
                  "separate_incident_reason": {
                    "type": "string",
                    "maxLength": 1000
                  },
                  "source_context": {
                    "$ref": "#/components/schemas/CaseDuplicateCaseFraudSourceContextRequest"
                  }
                }
              },
              "example": {
                "title": "Manual - Jane Doe",
                "blueprint": "b1de0000-0000-4000-8000-000000000002",
                "priority": "HIGH",
                "subject": {
                  "type": "user",
                  "uuid": "5b9a0000-0000-4000-8000-00000000f00d"
                },
                "tags": [
                  "review"
                ]
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"title\": \"Manual - Jane Doe\", \"blueprint\": \"b1de0000-0000-4000-8000-000000000002\", \"priority\": \"HIGH\", \"subject\": {\"type\": \"user\", \"uuid\": \"5b9a0000-0000-4000-8000-00000000f00d\"}, \"tags\": [\"review\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.create(\n    title=\"Manual - Jane Doe\",\n    blueprint=\"b1de0000-0000-4000-8000-000000000002\",\n    priority=\"HIGH\",\n    tags=[\"review\"],\n    subject={\n        \"type\": \"user\",\n        \"uuid\": \"5b9a0000-0000-4000-8000-00000000f00d\",\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.create({\n  title: \"Manual - Jane Doe\",\n  blueprint: \"b1de0000-0000-4000-8000-000000000002\",\n  priority: \"HIGH\",\n  tags: [\"review\"],\n  subject: {\n    type: \"user\",\n    uuid: \"5b9a0000-0000-4000-8000-00000000f00d\",\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Create(ctx, didit.CasesCreateParams{\n\tTitle:     \"Manual - Jane Doe\",\n\tBlueprint: didit.String(\"b1de0000-0000-4000-8000-000000000002\"),\n\tPriority:  didit.Some(didit.CasesCreateParamsPriority(\"HIGH\")),\n\tTags:      didit.Some([]string{\"review\"}),\n\tSubject: didit.Some(didit.CasesCreateParamsSubject{\n\t\tType: didit.Some(didit.CasesCreateParamsSubjectType(\"user\")),\n\t\tUUID: didit.String(\"5b9a0000-0000-4000-8000-00000000f00d\"),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CasesCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().create(CasesCreateParams.builder()\n        .title(\"Manual - Jane Doe\")\n        .blueprint(\"b1de0000-0000-4000-8000-000000000002\")\n        .priority(CasesCreateParams.Priority.of(\"HIGH\"))\n        .tags(List.of(\"review\"))\n        .subject(CasesCreateParams.Subject.builder()\n                .type(CasesCreateParams.Subject.Type.of(\"user\"))\n                .uuid(\"5b9a0000-0000-4000-8000-00000000f00d\")\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->create([\n    'title' => 'Manual - Jane Doe',\n    'blueprint' => 'b1de0000-0000-4000-8000-000000000002',\n    'priority' => 'HIGH',\n    'tags' => ['review'],\n    'subject' => [\n        'type' => 'user',\n        'uuid' => '5b9a0000-0000-4000-8000-00000000f00d',\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.create(\n  title: \"Manual - Jane Doe\",\n  blueprint: \"b1de0000-0000-4000-8000-000000000002\",\n  priority: \"HIGH\",\n  tags: [\"review\"],\n  subject: {\n    type: \"user\",\n    uuid: \"5b9a0000-0000-4000-8000-00000000f00d\",\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.CreateAsync(new CasesCreateParams\n{\n    Title = \"Manual - Jane Doe\",\n    Blueprint = \"b1de0000-0000-4000-8000-000000000002\",\n    Priority = new CasesCreateParamsPriority(\"HIGH\"),\n    Tags = new string[] { \"review\" },\n    Subject = new CasesCreateParamsSubject\n    {\n        Type = new CasesCreateParamsSubjectType(\"user\"),\n        Uuid = \"5b9a0000-0000-4000-8000-00000000f00d\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "케이스가 생성되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "400": {
            "description": "subject와 links가 모두 제공되지 않았거나, subject/blueprint/assignee를 찾을 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "409": {
            "description": "중복 검토가 활성화되어 있으며 별도 사건 사유가 없는 기존 케이스가 발견되었습니다. 케이스가 생성되지 않았습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/": {
      "get": {
        "summary": "케이스 조회",
        "description": "대상자, 블루프린트, 메모, 이벤트, 링크 및 체크리스트와 함께 케이스를 조회합니다.",
        "operationId": "get_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.retrieve(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.retrieve(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Retrieve(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().retrieve(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->retrieve('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.retrieve(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RetrieveAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "케이스 세부 정보.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에서 케이스(또는 중첩된 리소스)를 찾을 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "케이스 업데이트",
        "description": "케이스의 제목, 우선순위, 마감일, 태그 또는 소유 검토 팀을 업데이트합니다. 변경하려는 필드만 전송하세요. 생략된 필드는 기존 값을 유지합니다. `tags`는 전체 태그 목록을 대체합니다. `team`에는 이 애플리케이션의 활성 검토 팀의 uuid를 지정하거나(`GET .../cases/teams/`로 목록 조회), 팀 지정을 해제하려면 null을 지정합니다. 전체 액세스 API 키 또는 콘솔 멤버의 경우 `write:cases` 권한이 필요합니다. 접근 권한이 제한된 키는 403을 받습니다. 해당하는 경우 PRIORITY_CHANGED, DUE_DATE_CHANGED, TAG_ADDED, TAG_REMOVED, TEAM_CHANGED 이벤트를 기록합니다. 제목 변경은 타임라인 이벤트 없이 저장됩니다. 업데이트된 케이스를 반환합니다.",
        "operationId": "update_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "새 케이스 제목입니다."
                  },
                  "priority": {
                    "type": "string",
                    "enum": [
                      "LOW",
                      "MEDIUM",
                      "HIGH"
                    ]
                  },
                  "due_at": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "description": "새 마감 기한입니다. 초기화하려면 null을 전송하세요."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "전체 태그 목록입니다. 현재 태그를 대체합니다."
                  },
                  "team": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "케이스를 소유한 검토 팀의 UUID입니다. 이 애플리케이션의 활성 팀이어야 합니다. 팀 지정을 해제하려면 null을 전송하십시오."
                  }
                }
              },
              "examples": {
                "Change priority and deadline": {
                  "value": {
                    "priority": "HIGH",
                    "due_at": "2026-11-01T00:00:00Z"
                  }
                },
                "Move the case to a team": {
                  "value": {
                    "team": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                  }
                },
                "Clear the team": {
                  "value": {
                    "team": null
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"priority\": \"HIGH\", \"due_at\": \"2026-08-01T00:00:00Z\"}'"
          },
          {
            "lang": "curl",
            "label": "curl (change team)",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"team\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.update(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    priority=\"HIGH\",\n    due_at=\"2026-11-01T00:00:00Z\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.update(\"c1a5e000-0000-4000-8000-000000000001\", {\n  priority: \"HIGH\",\n  due_at: \"2026-11-01T00:00:00Z\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Update(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesUpdateParams{\n\tPriority: didit.Some(didit.CasesUpdateParamsPriority(\"HIGH\")),\n\tDueAt:    didit.Time(time.Date(2026, 11, 1, 0, 0, 0, 0, time.UTC)),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.OffsetDateTime;\nimport me.didit.Didit;\nimport me.didit.types.CasesUpdateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().update(\"c1a5e000-0000-4000-8000-000000000001\", CasesUpdateParams.builder()\n        .priority(CasesUpdateParams.Priority.of(\"HIGH\"))\n        .dueAt(OffsetDateTime.parse(\"2026-11-01T00:00:00Z\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->update('c1a5e000-0000-4000-8000-000000000001', [\n    'priority' => 'HIGH',\n    'due_at' => '2026-11-01T00:00:00Z',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.update(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  priority: \"HIGH\",\n  due_at: \"2026-11-01T00:00:00Z\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.UpdateAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesUpdateParams\n{\n    Priority = new CasesUpdateParamsPriority(\"HIGH\"),\n    DueAt = DateTimeOffset.Parse(\"2026-11-01T00:00:00Z\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "업데이트된 케이스입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "400": {
            "description": "필드 유효성 검사에 실패했습니다. 본문은 필드 이름을 키로 사용합니다. `team`이 이 애플리케이션의 활성 검토 팀이 아닌 경우 거부됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Team not active in this application": {
                    "value": {
                      "team": [
                        "Choose an active team of this application."
                      ]
                    }
                  },
                  "Invalid priority": {
                    "value": {
                      "priority": [
                        "\"URGENT\" is not a valid choice."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 다른 애플리케이션에 속해 있거나 접근 권한이 제한된 키입니다. Cases 엔드포인트에는 전체 접근 권한 키가 필요합니다. 콘솔 멤버 토큰에는 `write:cases` 권한이 필요합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Restricted API Key": {
                    "summary": "액세스가 제한된 API 키",
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "write:cases 권한이 없는 콘솔 멤버이거나 다른 애플리케이션의 키입니다.",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에서 케이스를 찾을 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No Case matches the given query."
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "summary": "케이스 삭제",
        "description": "케이스를 영구적으로 삭제합니다. 임시 저장된 규제 보고서도 함께 삭제됩니다. 연결된 인증, 인물, 기업 및 거래는 삭제되지 않습니다. 삭제 취소 endpoint는 제공되지 않습니다.\n\n케이스에 최종 확정된 규제 보고서가 있는 경우, 전체 요청이 `409`와 함께 거부되며 아무것도 삭제되지 않습니다. 응답 본문은 `code: in_filed_report`를 사용하며 각 보고서를 `uuid`, `report_number`, `report_type`, `case_uuid`로 지정합니다. 보고서를 삭제한 후 요청을 다시 시도하세요.",
        "operationId": "delete_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.delete(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.delete(\"c1a5e000-0000-4000-8000-000000000001\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Delete(ctx, \"c1a5e000-0000-4000-8000-000000000001\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().delete(\"c1a5e000-0000-4000-8000-000000000001\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->cases->delete('c1a5e000-0000-4000-8000-000000000001');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.delete(\"c1a5e000-0000-4000-8000-000000000001\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.DeleteAsync(\"c1a5e000-0000-4000-8000-000000000001\");"
          }
        ],
        "responses": {
          "204": {
            "description": "케이스가 삭제되었습니다."
          },
          "403": {
            "description": "키가 케이스를 삭제할 수 없습니다. `write:cases` 권한이 있는 전체 액세스 키가 필요합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "케이스가 이 애플리케이션에 존재하지 않거나 이미 삭제되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "케이스에 확정된 규제 보고서가 있습니다. 아무것도 삭제되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InFiledReportError"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/assign/": {
      "post": {
        "summary": "케이스 할당 또는 할당 해제",
        "description": "케이스를 사용자에게 할당하거나, assignee_user_id: null을 전송하여 할당을 해제합니다. 담당자가 아직 존재하지 않는 경우 assignee_email/assignee_name을 통해 사용자 행이 자동 프로비저닝됩니다.",
        "operationId": "assign_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "assign",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "assignee_user_id"
                ],
                "properties": {
                  "assignee_user_id": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "할당을 해제하려면 null입니다."
                  },
                  "assignee_email": {
                    "type": "string",
                    "format": "email",
                    "nullable": true
                  },
                  "assignee_name": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "example": {
                "assignee_user_id": "9a000000-0000-4000-8000-0000000000aa"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/assign/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"assignee_user_id\": \"9a000000-0000-4000-8000-0000000000aa\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.assign(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    assignee_user_id=\"9a000000-0000-4000-8000-0000000000aa\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.assign(\"c1a5e000-0000-4000-8000-000000000001\", {\n  assignee_user_id: \"9a000000-0000-4000-8000-0000000000aa\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Assign(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesAssignParams{\n\tAssigneeUserID: didit.String(\"9a000000-0000-4000-8000-0000000000aa\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesAssignParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().assign(\"c1a5e000-0000-4000-8000-000000000001\", CasesAssignParams.builder()\n        .assigneeUserId(\"9a000000-0000-4000-8000-0000000000aa\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->assign('c1a5e000-0000-4000-8000-000000000001', [\n    'assignee_user_id' => '9a000000-0000-4000-8000-0000000000aa',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.assign(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  assignee_user_id: \"9a000000-0000-4000-8000-0000000000aa\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.AssignAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesAssignParams\n{\n    AssigneeUserId = \"9a000000-0000-4000-8000-0000000000aa\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "케이스가 할당되었거나 할당 해제되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/resolve/": {
      "post": {
        "summary": "케이스 해결",
        "description": "케이스를 다섯 가지 해결 상태 중 하나로 해결합니다: FALSE_POSITIVE(우려 사항 없음), VALID_THREAT(우려 사항 확인됨), INCONCLUSIVE, REQUIREMENTS_NOT_MET 또는 REQUIREMENTS_SATISFIED. 블루프린트의 체크리스트가 선택 사항이 아니며 완료되지 않은 항목이 남아 있거나, 블루프린트에서 해결 메모를 요구하지만 제공되지 않은 경우 400 오류로 차단됩니다. 케이스의 블루프린트에 four-eyes 검토자 단계(four_eyes_checker_blueprint)가 있는 경우, 해결이 스테이징되며(case.pending_resolution) 케이스가 즉시 해결되는 대신 검토자 블루프린트로 이동합니다. 이때 다른 담당자가 approve 또는 reject-approval을 호출해야 합니다. four-eyes 해결은 콘솔 멤버로서 제출해야 합니다. API 키가 제출한 해결에는 기록된 작성자가 없으므로 모든 호출자에 대해 approve 및 reject-approval이 403을 반환합니다. four-eyes 블루프린트에서는 승인해야 하는 멤버를 `checker`로 지정할 수 있으며, 이 경우 해당 멤버만 해결을 승인하거나 거부할 수 있고 응답의 `checker`에 해당 멤버의 이름이 표시됩니다. `checker`가 없으면 해결은 검토자 블루프린트의 대기열에서 대기합니다. 검토자 단계가 없는 블루프린트에 대해 `checker`를 전송하면 400이 반환됩니다.",
        "operationId": "resolve_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "resolve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "resolution"
                ],
                "properties": {
                  "resolution": {
                    "type": "string",
                    "enum": [
                      "FALSE_POSITIVE",
                      "VALID_THREAT",
                      "INCONCLUSIVE",
                      "REQUIREMENTS_NOT_MET",
                      "REQUIREMENTS_SATISFIED"
                    ]
                  },
                  "note": {
                    "type": "string",
                    "nullable": true,
                    "description": "블루프린트에 require_resolution_note가 설정된 경우 필수입니다."
                  },
                  "checker": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "상호 검토(Four-eyes) 블루프린트 전용입니다. 이 해결 처리를 승인해야 하는 멤버의 사용자 uuid입니다(케이스의 `assigned_to.uuid` 또는 검토 팀의 `members[].user_id`와 동일한 ID). 해당 멤버는 이 애플리케이션에 대한 케이스 접근 권한이 있어야 하며 해결 처리를 제출하는 담당자일 수 없습니다. 생략하거나 null을 전송하면 해결 처리가 검토자 대기열에 남겨집니다."
                  }
                }
              },
              "examples": {
                "Resolve": {
                  "value": {
                    "resolution": "FALSE_POSITIVE",
                    "note": "Confirmed legitimate activity after reviewing documents."
                  }
                },
                "Four-eyes blueprint with a named checker": {
                  "value": {
                    "resolution": "VALID_THREAT",
                    "note": "Document tampering confirmed.",
                    "checker": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/resolve/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"resolution\": \"FALSE_POSITIVE\", \"note\": \"Confirmed legitimate activity after reviewing documents.\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.resolve(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    resolution=\"FALSE_POSITIVE\",\n    note=\"Confirmed legitimate activity after reviewing documents.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.resolve(\"c1a5e000-0000-4000-8000-000000000001\", {\n  resolution: \"FALSE_POSITIVE\",\n  note: \"Confirmed legitimate activity after reviewing documents.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Resolve(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesResolveParams{\n\tResolution: \"FALSE_POSITIVE\",\n\tNote:       didit.String(\"Confirmed legitimate activity after reviewing documents.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesResolveParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().resolve(\"c1a5e000-0000-4000-8000-000000000001\", CasesResolveParams.builder()\n        .resolution(CasesResolveParams.Resolution.of(\"FALSE_POSITIVE\"))\n        .note(\"Confirmed legitimate activity after reviewing documents.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->resolve('c1a5e000-0000-4000-8000-000000000001', [\n    'resolution' => 'FALSE_POSITIVE',\n    'note' => 'Confirmed legitimate activity after reviewing documents.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.resolve(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  resolution: \"FALSE_POSITIVE\",\n  note: \"Confirmed legitimate activity after reviewing documents.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ResolveAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesResolveParams\n{\n    Resolution = \"FALSE_POSITIVE\",\n    Note = \"Confirmed legitimate activity after reviewing documents.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "해결되었거나 4-eyes 승인을 위해 스테이징되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "400": {
            "description": "해결이 거부되었습니다. 필드 외 오류는 문자열 목록으로 제공됩니다. 불완전한 체크리스트, 누락된 필수 메모, 확인될 수 없거나 이 애플리케이션에 대한 케이스 접근 권한이 있는 활성 검토자가 아닌 `checker` 등이 해당됩니다. `checker` 오류는 필드별로 키가 지정되어 반환됩니다. 지정된 멤버가 해결을 제출하는 담당자이거나, 케이스의 청사진에 검토자 단계가 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    {
                      "type": "object",
                      "additionalProperties": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "Incomplete checklist": {
                    "value": [
                      "Case has incomplete checklist items: Verify source of funds"
                    ]
                  },
                  "Resolution note required": {
                    "value": [
                      "A resolution note is required to resolve this case."
                    ]
                  },
                  "Reviewer access could not be verified": {
                    "value": [
                      "Reviewer access could not be verified. Try again."
                    ]
                  },
                  "Checker is not an active reviewer": {
                    "value": [
                      "Choose an active reviewer with case access to this application."
                    ]
                  },
                  "Checker is the submitting officer": {
                    "value": {
                      "checker": [
                        "The officer who submitted the resolution cannot be its checker."
                      ]
                    }
                  },
                  "Policy has no checker step": {
                    "value": {
                      "checker": [
                        "This review policy has no checker step, so the case resolves directly."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/reopen/": {
      "post": {
        "summary": "케이스 다시 열기",
        "description": "사용자 대기 중 또는 해결된 케이스를 다시 열림 상태로 이동하고 resolution, resolution_notes, resolved_at, resolved_by_email을 삭제합니다.",
        "operationId": "reopen_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "reopen",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/reopen/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.reopen(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.reopen(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Reopen(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().reopen(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->reopen('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.reopen(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ReopenAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "케이스를 다시 엽니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/request-info/": {
      "post": {
        "summary": "정보 요청(사용자 대기 중)",
        "description": "인증된 사용자로부터 추가 정보를 수집하는 동안 열린 케이스를 awaiting_user 상태로 이동합니다. 현재 해결이 4-eyes 승인을 대기 중인 경우 400 오류로 실패합니다.",
        "operationId": "request_case_info",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "request_info",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/request-info/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.request_info(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requestInfo(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RequestInfo(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requestInfo(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->requestInfo('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.request_info(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RequestInfoAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "정보 요청(사용자 대기 중)입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/escalate/": {
      "post": {
        "summary": "케이스 에스컬레이션",
        "description": "케이스를 블루프린트에 구성된 escalation_blueprint로 이동합니다. 현재 블루프린트에 escalation_enabled가 설정되어 있고 escalation_blueprint가 지정되어 있어야 하며, 그렇지 않으면 400 오류가 발생합니다.",
        "operationId": "escalate_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "escalate",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/escalate/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.escalate(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.escalate(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Escalate(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().escalate(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->escalate('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.escalate(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.EscalateAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "케이스를 에스컬레이션합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/transfer/": {
      "post": {
        "summary": "이체 케이스",
        "description": "케이스를 동일한 애플리케이션의 활성화된 다른 블루프린트로 이동합니다. 현재 블루프린트에 transfer_enabled가 설정되어 있어야 하며, 그렇지 않으면 400 오류가 발생합니다.",
        "operationId": "transfer_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "transfer",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "target_blueprint"
                ],
                "properties": {
                  "target_blueprint": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              },
              "example": {
                "target_blueprint": "b1de0000-0000-4000-8000-000000000002"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/transfer/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"target_blueprint\": \"b1de0000-0000-4000-8000-000000000002\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.transfer(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    target_blueprint=\"b1de0000-0000-4000-8000-000000000002\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.transfer(\"c1a5e000-0000-4000-8000-000000000001\", {\n  target_blueprint: \"b1de0000-0000-4000-8000-000000000002\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Transfer(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesTransferParams{\n\tTargetBlueprint: \"b1de0000-0000-4000-8000-000000000002\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesTransferParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().transfer(\"c1a5e000-0000-4000-8000-000000000001\", CasesTransferParams.builder()\n        .targetBlueprint(\"b1de0000-0000-4000-8000-000000000002\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->transfer('c1a5e000-0000-4000-8000-000000000001', [\n    'target_blueprint' => 'b1de0000-0000-4000-8000-000000000002',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.transfer(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  target_blueprint: \"b1de0000-0000-4000-8000-000000000002\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.TransferAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesTransferParams\n{\n    TargetBlueprint = \"b1de0000-0000-4000-8000-000000000002\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "케이스가 이전되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/approve/": {
      "post": {
        "summary": "단계적 해결(4-eyes) 승인",
        "description": "이중 승인 청사진에서 resolve에 의해 준비된 결정을 적용합니다. 호출자는 제출한 담당자와 다른 담당자여야 하며, 그렇지 않으면 403이 반환됩니다. 결정에 검토자(케이스의 `checker`)가 지정된 경우 해당 멤버만 승인할 수 있으며, API 키를 포함한 다른 모든 호출자는 403을 받습니다.",
        "operationId": "approve_case_resolution",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "approve_resolution",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/approve/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.approve_resolution(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.approveResolution(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ApproveResolution(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().approveResolution(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->approveResolution('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.approve_resolution(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ApproveResolutionAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "해결 방안이 적용되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "409": {
            "description": "케이스에 승인 대기 중인 결정 사항이 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "호출자가 이 해결안을 승인할 수 없습니다. 호출자가 이를 제출했거나, 케이스에 기록된 작성자가 없거나, 해결안에 다른 검토자가 지정되어 있습니다. 검토자가 지정된 경우 API 키는 항상 이 403 오류를 받습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Caller submitted the resolution": {
                    "value": {
                      "detail": "The officer who submitted the resolution cannot approve it."
                    }
                  },
                  "No recorded maker": {
                    "value": {
                      "detail": "Case has no recorded maker for this pending resolution; approve is not permitted."
                    }
                  },
                  "Caller is not the named checker": {
                    "value": {
                      "detail": "Only the named checker can approve this resolution."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/reject-approval/": {
      "post": {
        "summary": "스테이징된 해결안 거부(4-eyes)",
        "description": "resolve에 의해 스테이징된 해결안을 거부하고 케이스를 작성자 블루프린트로 되돌립니다. 호출자는 이를 제출한 담당자와 다른 담당자여야 하며, 그렇지 않으면 403이 반환됩니다. 해결안에 검토자(케이스의 `checker`)가 지정되어 있는 경우 해당 멤버만 이를 거부할 수 있으며, API 키를 포함한 다른 모든 호출자에게는 403이 반환됩니다.",
        "operationId": "reject_case_resolution",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "reject_resolution",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "notes": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "example": {
                "notes": "Needs a clearer rationale before this can be approved."
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/reject-approval/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"notes\": \"Needs a clearer rationale before this can be approved.\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.reject_resolution(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    notes=\"Needs a clearer rationale before this can be approved.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.rejectResolution(\"c1a5e000-0000-4000-8000-000000000001\", {\n  notes: \"Needs a clearer rationale before this can be approved.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RejectResolution(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesRejectResolutionParams{\n\tNotes: didit.String(\"Needs a clearer rationale before this can be approved.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesRejectResolutionParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().rejectResolution(\"c1a5e000-0000-4000-8000-000000000001\", CasesRejectResolutionParams.builder()\n        .notes(\"Needs a clearer rationale before this can be approved.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->rejectResolution('c1a5e000-0000-4000-8000-000000000001', [\n    'notes' => 'Needs a clearer rationale before this can be approved.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.reject_resolution(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  notes: \"Needs a clearer rationale before this can be approved.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RejectResolutionAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesRejectResolutionParams\n{\n    Notes = \"Needs a clearer rationale before this can be approved.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "해결 방안이 거부되어 케이스가 메이커 청사진으로 반환되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "409": {
            "description": "케이스에 승인 대기 중인 결정 사항이 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "호출자가 이 해결안을 거부할 수 없습니다. 호출자가 이를 제출했거나, 케이스에 기록된 작성자가 없거나, 해결안에 다른 검토자가 지정되어 있습니다. 검토자가 지정된 경우 API 키는 항상 이 403 오류를 받습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Caller submitted the resolution": {
                    "value": {
                      "detail": "The officer who submitted the resolution cannot reject it."
                    }
                  },
                  "No recorded maker": {
                    "value": {
                      "detail": "Case has no recorded maker for this pending resolution; reject is not permitted."
                    }
                  },
                  "Caller is not the named checker": {
                    "value": {
                      "detail": "Only the named checker can reject this resolution."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/entity-actions/": {
      "post": {
        "operationId": "apply_case_entity_action",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "apply_entity_action",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CaseActionCaseEntityActionRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseActionCaseEntityActionRequest"
              },
              "example": {
                "client_reference": "e1a00000-0000-4000-8000-000000000001",
                "action": "add_tags",
                "tags": [
                  "source-of-funds-reviewed"
                ]
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CaseActionCaseEntityActionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseActionCaseEntityActionResult"
                }
              }
            },
            "description": ""
          },
          "409": {
            "description": "참조가 다른 작업 payload에 속해 있습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "케이스 대상에 하나의 명시적 작업을 적용합니다. 고유한 client_reference를 제공하여 작업 영수증을 받고 재시도를 멱등하게 만드십시오. 다른 payload로 해당 참조를 재사용하면 409가 반환됩니다. 참조가 있는 경우 HTTP 상태가 200이더라도 receipt.status를 검사하십시오. FAILED는 작업이 적용되지 않았음을 의미합니다. 실패한 요청을 반복해도 retry가 true가 아니면 다시 실행되지 않습니다. client_reference를 생략하면 기존 레거시 응답이 유지됩니다.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.apply_entity_action(\n    \"11111111-2222-3333-4444-555555555555\",\n    client_reference=\"e1a00000-0000-4000-8000-000000000001\",\n    action=\"add_tags\",\n    tags=[\"source-of-funds-reviewed\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.applyEntityAction(\"11111111-2222-3333-4444-555555555555\", {\n  client_reference: \"e1a00000-0000-4000-8000-000000000001\",\n  action: \"add_tags\",\n  tags: [\"source-of-funds-reviewed\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ApplyEntityAction(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CaseActionCaseEntityActionRequest{\n\tClientReference: didit.String(\"e1a00000-0000-4000-8000-000000000001\"),\n\tAction:          didit.CaseActionActionEnum(\"add_tags\"),\n\tTags:            didit.Some([]string{\"source-of-funds-reviewed\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CaseActionActionEnum;\nimport me.didit.types.CaseActionCaseEntityActionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().applyEntityAction(\"11111111-2222-3333-4444-555555555555\", CaseActionCaseEntityActionRequest.builder()\n        .clientReference(\"e1a00000-0000-4000-8000-000000000001\")\n        .action(CaseActionActionEnum.of(\"add_tags\"))\n        .tags(List.of(\"source-of-funds-reviewed\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->applyEntityAction('11111111-2222-3333-4444-555555555555', [\n    'client_reference' => 'e1a00000-0000-4000-8000-000000000001',\n    'action' => 'add_tags',\n    'tags' => ['source-of-funds-reviewed'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.apply_entity_action(\n  \"11111111-2222-3333-4444-555555555555\",\n  client_reference: \"e1a00000-0000-4000-8000-000000000001\",\n  action: \"add_tags\",\n  tags: [\"source-of-funds-reviewed\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ApplyEntityActionAsync(\"11111111-2222-3333-4444-555555555555\", new CaseActionCaseEntityActionRequest\n{\n    ClientReference = \"e1a00000-0000-4000-8000-000000000001\",\n    Action = \"add_tags\",\n    Tags = new string[] { \"source-of-funds-reviewed\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/print/": {
      "get": {
        "summary": "케이스 인쇄(PDF)",
        "description": "전체 케이스(요약, 대상자, 체크리스트 상태, 메모, 첨부된 세션/거래, 이벤트, FIU 보고서 목록)를 PDF로 렌더링하고 사전 서명된 다운로드 URL을 반환합니다.",
        "operationId": "print_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "print",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/print/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.print(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.print(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Print(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().print(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->print('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.print(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.PrintAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "사전 서명된 PDF URL입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/notes/": {
      "get": {
        "operationId": "list_case_notes",
        "x-didit-sdk": {
          "resource": "cases.notes",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "결과를 정렬할 때 사용할 필드입니다.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "페이지당 반환할 결과 수입니다.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "description": "결과 반환을 시작할 초기 인덱스입니다.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseCollaborationPaginatedCaseNoteList"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "호출자에게 필요한 케이스 권한이 없습니다."
          },
          "404": {
            "description": "이 호출자는 해당 케이스 또는 메모를 사용할 수 없습니다."
          }
        },
        "tags": [
          "Case Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.notes.list(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.notes.list(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Notes.ListAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesNotesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().notes().list(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->notes->list('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.notes.list(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Notes.ListAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "operationId": "create_case_note",
        "x-didit-sdk": {
          "resource": "cases.notes",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CaseCollaborationCaseNoteCreateRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseCollaborationCaseNoteCreateRequest"
              },
              "example": {
                "comment": "Proof of address matches the ID document."
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CaseCollaborationCaseNoteCreateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseCollaborationCaseNote"
                }
              }
            },
            "description": ""
          },
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseCollaborationCaseNote"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "호출자에게 필요한 케이스 권한이 없습니다."
          },
          "404": {
            "description": "이 호출자는 해당 케이스 또는 메모를 사용할 수 없습니다."
          },
          "409": {
            "description": "이 클라이언트 참조는 이미 다른 메모에 사용되었거나 삭제된 메모에 사용되었습니다."
          }
        },
        "tags": [
          "Case Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "케이스 범위의 메모를 추가합니다. 선택적 client_reference를 사용하면 변경되지 않은 재시도 시 활동이나 알림이 중복되지 않고 동일한 메모가 반환됩니다. reply_to는 이 케이스 내의 활성 메모를 식별해야 합니다. 응답에는 저장된 답글에 해당 발췌문을 복사하지 않고도 제한된 상위 발췌문이 포함됩니다.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.notes.create(\n    \"11111111-2222-3333-4444-555555555555\",\n    comment=\"Proof of address matches the ID document.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.notes.create(\"11111111-2222-3333-4444-555555555555\", {\n  comment: \"Proof of address matches the ID document.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Notes.Create(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CaseCollaborationCaseNoteCreateRequest{\n\tComment: \"Proof of address matches the ID document.\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CaseCollaborationCaseNoteCreateRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().notes().create(\"11111111-2222-3333-4444-555555555555\", CaseCollaborationCaseNoteCreateRequest.builder()\n        .comment(\"Proof of address matches the ID document.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->notes->create('11111111-2222-3333-4444-555555555555', [\n    'comment' => 'Proof of address matches the ID document.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.notes.create(\n  \"11111111-2222-3333-4444-555555555555\",\n  comment: \"Proof of address matches the ID document.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Notes.CreateAsync(\"11111111-2222-3333-4444-555555555555\", new CaseCollaborationCaseNoteCreateRequest\n{\n    Comment = \"Proof of address matches the ID document.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/notes/{note_uuid}/": {
      "patch": {
        "operationId": "root_partial_update",
        "x-didit-sdk": {
          "resource": "cases.notes",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "note_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CaseCollaborationPatchedCaseNoteUpdateRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseCollaborationPatchedCaseNoteUpdateRequest"
              },
              "example": {
                "is_pinned": true
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CaseCollaborationPatchedCaseNoteUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseCollaborationCaseNote"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "호출자에게 필요한 케이스 권한이 없습니다."
          },
          "404": {
            "description": "이 호출자는 해당 케이스 또는 메모를 사용할 수 없습니다."
          }
        },
        "tags": [
          "Case Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "기존 메모를 고정하거나 고정 해제합니다. 고정된 메모가 먼저 표시됩니다. 고정 변경 사항은 케이스 활동에 기록되며 증거 또는 출처 결정에는 영향을 주지 않습니다.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.notes.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n    is_pinned=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.notes.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n  {\n    is_pinned: true,\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Notes.Update(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", didit.CaseCollaborationPatchedCaseNoteUpdateRequest{\n\tIsPinned: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CaseCollaborationPatchedCaseNoteUpdateRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().notes().update(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", CaseCollaborationPatchedCaseNoteUpdateRequest.builder()\n        .isPinned(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->notes->update('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555', [\n    'is_pinned' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.notes.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n  is_pinned: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Notes.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", new CaseCollaborationPatchedCaseNoteUpdateRequest\n{\n    IsPinned = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "operationId": "delete_case_note",
        "x-didit-sdk": {
          "resource": "cases.notes",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "note_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "메모가 영구적으로 삭제됩니다. 삭제된 상위 발췌문 없이 답글은 유지됩니다. 첨부 파일은 다른 메모에서 여전히 사용 중인 경우를 제외하고 삭제됩니다."
          },
          "403": {
            "description": "호출자에게 필요한 케이스 권한이 없습니다."
          },
          "404": {
            "description": "이 호출자는 해당 케이스 또는 메모를 사용할 수 없습니다."
          }
        },
        "tags": [
          "Case Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.notes.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.notes.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Notes.Delete(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().notes().delete(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->cases->notes->delete('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.notes.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\"\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.Notes.DeleteAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/notes/presign/": {
      "post": {
        "summary": "메모 첨부 파일 업로드",
        "description": "메모에 첨부할 파일(JPEG, PNG, WebP, PDF, 일반 텍스트 또는 CSV, 최대 5MB)을 업로드합니다. 메모의 attachments 배열에 전달할 s3_key를 반환합니다.",
        "operationId": "upload_case_note_attachment",
        "x-didit-sdk": {
          "resource": "cases.notes",
          "method": "create_attachment_upload",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/notes/presign/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'file=@evidence.pdf'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.notes.create_attachment_upload(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    file=open(\"document.pdf\", \"rb\"),\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.notes.createAttachmentUpload(\"c1a5e000-0000-4000-8000-000000000001\", {\n  file: await fileFromPath(\"document.pdf\"),\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Notes.CreateAttachmentUpload(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesNotesCreateAttachmentUploadParams{\n\tFile: didit.FileFromPath(\"document.pdf\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.CasesNotesCreateAttachmentUploadParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().notes().createAttachmentUpload(\"c1a5e000-0000-4000-8000-000000000001\", CasesNotesCreateAttachmentUploadParams.builder()\n        .file(Path.of(\"document.pdf\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->notes->createAttachmentUpload('c1a5e000-0000-4000-8000-000000000001', [\n    'file' => File::fromPath('document.pdf'),\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.notes.create_attachment_upload(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  file: Pathname(\"document.pdf\")\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Notes.CreateAttachmentUploadAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesNotesCreateAttachmentUploadParams\n{\n    File = FileUpload.FromPath(\"document.pdf\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "파일이 업로드되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "s3_key": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "filename": {
                      "type": "string"
                    },
                    "file_size": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "파일이 없거나, 지원되지 않는 콘텐츠 유형이거나, 파일이 5MB를 초과합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "get": {
        "summary": "메모 첨부 파일 URL 조회",
        "description": "케이스 노트 중 하나에 이미 저장된 첨부 파일에 대해 새로운 사전 서명된 다운로드 URL을 생성합니다.",
        "operationId": "get_case_note_attachment_url",
        "x-didit-sdk": {
          "resource": "cases.notes",
          "method": "retrieve_attachment_url",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          },
          {
            "name": "s3_key",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "업로드 시 반환되거나 메모에 나열된 첨부 파일의 s3_key입니다.",
            "required": true
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/notes/presign/?s3_key=case-notes/c1a5e000-0000-4000-8000-000000000001/evidence.pdf' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.notes.retrieve_attachment_url(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    s3_key=\"your-s3-key\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.notes.retrieveAttachmentUrl(\"c1a5e000-0000-4000-8000-000000000001\", {\n  s3_key: \"your-s3-key\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Notes.RetrieveAttachmentURL(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesNotesRetrieveAttachmentURLParams{\n\tS3Key: \"your-s3-key\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesNotesRetrieveAttachmentUrlParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().notes().retrieveAttachmentUrl(\"c1a5e000-0000-4000-8000-000000000001\", CasesNotesRetrieveAttachmentUrlParams.builder()\n        .s3Key(\"your-s3-key\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->notes->retrieveAttachmentUrl('c1a5e000-0000-4000-8000-000000000001', [\n    's3_key' => 'your-s3-key',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.notes.retrieve_attachment_url(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  s3_key: \"your-s3-key\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Notes.RetrieveAttachmentUrlAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesNotesRetrieveAttachmentUrlParams\n{\n    S3Key = \"your-s3-key\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "사전 서명된 URL입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "s3_key": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "filename": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "s3_key가 누락되었거나 이 케이스에 속하지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/links/": {
      "get": {
        "summary": "케이스 링크 목록 조회",
        "description": "케이스에 연결된 세션, 기업 세션 및 거래를 나열합니다.",
        "operationId": "list_case_links",
        "x-didit-sdk": {
          "resource": "cases.links",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/links/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.links.list(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.links.list(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Links.List(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().links().list(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->links->list('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.links.list(\"c1a5e000-0000-4000-8000-000000000001\").each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Links.ListAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "케이스 링크.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CaseLink"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "케이스 링크 추가",
        "description": "세션, 기업 세션 또는 거래를 케이스에 첨부합니다. 엔터티가 케이스와 다른 주체에 속한 경우 400으로 거부됩니다.",
        "operationId": "create_case_link",
        "x-didit-sdk": {
          "resource": "cases.links",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "entity_type",
                  "entity_uuid"
                ],
                "properties": {
                  "entity_type": {
                    "type": "string",
                    "enum": [
                      "session",
                      "business_session",
                      "transaction"
                    ]
                  },
                  "entity_uuid": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              },
              "example": {
                "entity_type": "transaction",
                "entity_uuid": "77000000-0000-4000-8000-000000000077"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/links/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"entity_type\": \"transaction\", \"entity_uuid\": \"77000000-0000-4000-8000-000000000077\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.links.create(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    entity_type=\"transaction\",\n    entity_uuid=\"77000000-0000-4000-8000-000000000077\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.links.create(\"c1a5e000-0000-4000-8000-000000000001\", {\n  entity_type: \"transaction\",\n  entity_uuid: \"77000000-0000-4000-8000-000000000077\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Links.Create(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesLinksCreateParams{\n\tEntityType: \"transaction\",\n\tEntityUUID: \"77000000-0000-4000-8000-000000000077\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesLinksCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().links().create(\"c1a5e000-0000-4000-8000-000000000001\", CasesLinksCreateParams.builder()\n        .entityType(CasesLinksCreateParams.EntityType.of(\"transaction\"))\n        .entityUuid(\"77000000-0000-4000-8000-000000000077\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->links->create('c1a5e000-0000-4000-8000-000000000001', [\n    'entity_type' => 'transaction',\n    'entity_uuid' => '77000000-0000-4000-8000-000000000077',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.links.create(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  entity_type: \"transaction\",\n  entity_uuid: \"77000000-0000-4000-8000-000000000077\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Links.CreateAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesLinksCreateParams\n{\n    EntityType = \"transaction\",\n    EntityUuid = \"77000000-0000-4000-8000-000000000077\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "링크가 생성되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseLink"
                }
              }
            }
          },
          "400": {
            "description": "엔티티가 케이스 주체와 다른 프로필에 속합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/links/{link_uuid}/": {
      "delete": {
        "summary": "케이스 링크 제거",
        "description": "케이스에서 연결된 세션, 기업 세션 또는 거래의 연결을 해제합니다.",
        "operationId": "delete_case_link",
        "x-didit-sdk": {
          "resource": "cases.links",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          },
          {
            "name": "link_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11000000-0000-4000-8000-000000000004"
            },
            "description": "링크 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/links/11000000-0000-4000-8000-000000000004/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.links.delete(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    \"11000000-0000-4000-8000-000000000004\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.links.delete(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  \"11000000-0000-4000-8000-000000000004\",\n);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Links.Delete(ctx, \"c1a5e000-0000-4000-8000-000000000001\", \"11000000-0000-4000-8000-000000000004\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().links().delete(\"c1a5e000-0000-4000-8000-000000000001\", \"11000000-0000-4000-8000-000000000004\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->cases->links->delete('c1a5e000-0000-4000-8000-000000000001', '11000000-0000-4000-8000-000000000004');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.links.delete(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  \"11000000-0000-4000-8000-000000000004\"\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.Links.DeleteAsync(\"c1a5e000-0000-4000-8000-000000000001\", \"11000000-0000-4000-8000-000000000004\");"
          }
        ],
        "responses": {
          "204": {
            "description": "링크가 제거되었습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/events/": {
      "get": {
        "summary": "케이스 이벤트 목록 조회",
        "description": "케이스의 읽기 전용 감사 타임라인입니다(생성, 상태 변경, 담당자 배정, 해결, 에스컬레이션, 이관, 태그/우선순위/마감일 변경, 엔터티 작업 등).",
        "operationId": "list_case_events",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "list_events",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "페이지 크기입니다."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "0부터 시작하는 오프셋입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/events/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.list_events(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.listEvents(\"c1a5e000-0000-4000-8000-000000000001\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.ListEventsAutoPaging(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesListEventsParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().listEvents(\"c1a5e000-0000-4000-8000-000000000001\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->listEvents('c1a5e000-0000-4000-8000-000000000001') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.list_events(\"c1a5e000-0000-4000-8000-000000000001\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.ListEventsAsync(\"c1a5e000-0000-4000-8000-000000000001\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "페이지 단위로 제공되는 이벤트 목록(최신순)입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "일치하는 행의 수입니다. 최대 100개까지는 정확하며, 성능상의 이유로 100개를 초과하면 100으로 제한됩니다. 마지막 페이지를 감지하려면 `next`가 null인지 확인하십시오."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "다음 페이지의 절대 URL이거나 null입니다."
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "이전 페이지의 절대 URL이거나 null입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaseEvent"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/checklist/": {
      "get": {
        "summary": "케이스 체크리스트 목록 조회",
        "description": "생성 시 청사진의 content_config.checklist.items에서 복사된 케이스의 체크리스트 항목을 정렬된 순서로 나열합니다.",
        "operationId": "list_case_checklist",
        "x-didit-sdk": {
          "resource": "cases.checklist",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/checklist/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.checklist.list(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.checklist.list(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Checklist.List(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().checklist().list(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->checklist->list('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.checklist.list(\"c1a5e000-0000-4000-8000-000000000001\").each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Checklist.ListAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "체크리스트 항목입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CaseChecklistItem"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/checklist/{item_uuid}/": {
      "patch": {
        "summary": "체크리스트 항목 토글",
        "description": "체크리스트 항목을 완료 또는 미완료로 표시합니다. 청사진에서 체크리스트를 선택 사항으로 표시하지 않는 한, 미완료 항목이 있는 동안에는 처리가 차단됩니다.",
        "operationId": "toggle_case_checklist_item",
        "x-didit-sdk": {
          "resource": "cases.checklist",
          "method": "toggle_item",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          },
          {
            "name": "item_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c4ec0000-0000-4000-8000-000000000005"
            },
            "description": "체크리스트 항목 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "is_completed"
                ],
                "properties": {
                  "is_completed": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "is_completed": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/checklist/c4ec0000-0000-4000-8000-000000000005/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"is_completed\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.checklist.toggle_item(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    \"c4ec0000-0000-4000-8000-000000000005\",\n    is_completed=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.checklist.toggleItem(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  \"c4ec0000-0000-4000-8000-000000000005\",\n  {\n    is_completed: true,\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Checklist.ToggleItem(ctx, \"c1a5e000-0000-4000-8000-000000000001\", \"c4ec0000-0000-4000-8000-000000000005\", didit.CasesChecklistToggleItemParams{\n\tIsCompleted: true,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesChecklistToggleItemParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().checklist().toggleItem(\"c1a5e000-0000-4000-8000-000000000001\", \"c4ec0000-0000-4000-8000-000000000005\", CasesChecklistToggleItemParams.builder()\n        .isCompleted(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->checklist->toggleItem('c1a5e000-0000-4000-8000-000000000001', 'c4ec0000-0000-4000-8000-000000000005', [\n    'is_completed' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.checklist.toggle_item(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  \"c4ec0000-0000-4000-8000-000000000005\",\n  is_completed: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Checklist.ToggleItemAsync(\"c1a5e000-0000-4000-8000-000000000001\", \"c4ec0000-0000-4000-8000-000000000005\", new CasesChecklistToggleItemParams\n{\n    IsCompleted = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "업데이트된 체크리스트 항목입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseChecklistItem"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/aml/": {
      "get": {
        "summary": "케이스 AML 적발 항목 목록 조회",
        "description": "케이스 대상자의 AML 스크리닝 히트를 조회합니다. POST /v3/aml/에서 반환하는 히트와 동일한 형식입니다.",
        "operationId": "list_case_aml_hits",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "list_aml_hits",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/aml/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.list_aml_hits(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.listAmlHits(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ListAMLHits(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().listAmlHits(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->listAmlHits('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.list_aml_hits(\"c1a5e000-0000-4000-8000-000000000001\").each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ListAmlHitsAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "AML 일치 항목입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AMLScreening"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/statistics/": {
      "get": {
        "summary": "케이스 분석",
        "description": "해당 날짜 범위에 대한 케이스 집계 분석입니다(기본값은 지난 30일, 최대 731일). 차트, 테이블, 총계, 할당 이벤트 및 현재 대기열 수는 동일한 애플리케이션 스코프 필터를 사용합니다. 필터는 현재 케이스 값을 사용합니다. 날짜는 각 지표 이벤트에 적용되므로 해당 기간 동안 할당되거나 해결된 이전 케이스도 계속 포함됩니다. 대기열 깊이는 날짜 범위와 무관합니다. 잘못된 필터는 400을 반환하며, 알 수 없는 블루프린트나 담당자는 빈 결과를 반환합니다.",
        "operationId": "get_case_analytics",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "retrieve_statistics",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "date_from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "범위 시작일(포함). 기본값은 30일 전입니다."
          },
          {
            "name": "date_to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "범위 종료일(포함). 기본값은 오늘입니다."
          },
          {
            "name": "blueprint",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "현재 블루프린트 UUID로 필터링합니다."
          },
          {
            "name": "assigned_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "현재 배정된 검토자 사용자 UUID로 필터링합니다."
          },
          {
            "name": "priority",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "LOW",
                "MEDIUM",
                "HIGH"
              ]
            },
            "description": "현재 케이스 우선순위로 필터링합니다."
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "MANUAL",
                "AML_SCREENING",
                "TRANSACTION_RULE",
                "WORKFLOW_BUILDER"
              ]
            },
            "description": "케이스 생성 소스로 필터링합니다."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "OPEN",
                "AWAITING_USER",
                "RESOLVED"
              ]
            },
            "description": "현재 케이스 상태로 필터링합니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/statistics/?date_from=2026-06-01&date_to=2026-06-30' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.retrieve_statistics()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.retrieveStatistics();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RetrieveStatistics(ctx, didit.CasesRetrieveStatisticsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().retrieveStatistics();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->retrieveStatistics();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.retrieve_statistics\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RetrieveStatisticsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "애널리틱스 payload.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "series": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "date": {
                            "type": "string",
                            "format": "date"
                          },
                          "created": {
                            "type": "integer"
                          },
                          "reviewed": {
                            "type": "integer"
                          }
                        }
                      }
                    },
                    "tables": {
                      "type": "object",
                      "properties": {
                        "officer": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "key": {
                                "type": "string",
                                "description": "차원 값: 담당자 이메일, \"blueprint_name:uuid\", 소스 또는 상태입니다. 누락된 차원의 경우 \"unassigned\"/\"none\"입니다."
                              },
                              "created": {
                                "type": "integer"
                              },
                              "assigned": {
                                "type": "integer"
                              },
                              "resolved": {
                                "type": "integer"
                              },
                              "threat_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "false_positive_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "unresolved": {
                                "type": "integer"
                              },
                              "reassignment_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "escalation_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_assign_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_resolve_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_handling_hours": {
                                "type": "number",
                                "format": "float"
                              }
                            }
                          }
                        },
                        "blueprint": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "key": {
                                "type": "string",
                                "description": "차원 값: 담당자 이메일, \"blueprint_name:uuid\", 소스 또는 상태입니다. 누락된 차원의 경우 \"unassigned\"/\"none\"입니다."
                              },
                              "created": {
                                "type": "integer"
                              },
                              "assigned": {
                                "type": "integer"
                              },
                              "resolved": {
                                "type": "integer"
                              },
                              "threat_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "false_positive_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "unresolved": {
                                "type": "integer"
                              },
                              "reassignment_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "escalation_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_assign_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_resolve_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_handling_hours": {
                                "type": "number",
                                "format": "float"
                              }
                            }
                          }
                        },
                        "source": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "key": {
                                "type": "string",
                                "description": "차원 값: 담당자 이메일, \"blueprint_name:uuid\", 소스 또는 상태입니다. 누락된 차원의 경우 \"unassigned\"/\"none\"입니다."
                              },
                              "created": {
                                "type": "integer"
                              },
                              "assigned": {
                                "type": "integer"
                              },
                              "resolved": {
                                "type": "integer"
                              },
                              "threat_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "false_positive_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "unresolved": {
                                "type": "integer"
                              },
                              "reassignment_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "escalation_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_assign_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_resolve_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_handling_hours": {
                                "type": "number",
                                "format": "float"
                              }
                            }
                          }
                        },
                        "status": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "key": {
                                "type": "string",
                                "description": "차원 값: 담당자 이메일, \"blueprint_name:uuid\", 소스 또는 상태입니다. 누락된 차원의 경우 \"unassigned\"/\"none\"입니다."
                              },
                              "created": {
                                "type": "integer"
                              },
                              "assigned": {
                                "type": "integer"
                              },
                              "resolved": {
                                "type": "integer"
                              },
                              "threat_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "false_positive_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "unresolved": {
                                "type": "integer"
                              },
                              "reassignment_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "escalation_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_assign_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_resolve_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_handling_hours": {
                                "type": "number",
                                "format": "float"
                              }
                            }
                          }
                        }
                      }
                    },
                    "totals": {
                      "type": "object",
                      "properties": {
                        "created": {
                          "type": "integer"
                        },
                        "assigned": {
                          "type": "integer"
                        },
                        "resolved": {
                          "type": "integer"
                        },
                        "threat_rate": {
                          "type": "number",
                          "format": "float"
                        },
                        "false_positive_rate": {
                          "type": "number",
                          "format": "float"
                        },
                        "unresolved": {
                          "type": "integer"
                        },
                        "reassignment_rate": {
                          "type": "number",
                          "format": "float"
                        },
                        "escalation_rate": {
                          "type": "number",
                          "format": "float"
                        },
                        "avg_assign_hours": {
                          "type": "number",
                          "format": "float"
                        },
                        "avg_resolve_hours": {
                          "type": "number",
                          "format": "float"
                        },
                        "avg_handling_hours": {
                          "type": "number",
                          "format": "float"
                        }
                      }
                    },
                    "queue": {
                      "type": "object",
                      "description": "실시간 스냅샷이며 날짜 범위로 제한되지 않습니다.",
                      "properties": {
                        "open": {
                          "type": "integer"
                        },
                        "overdue": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/bulk/status/": {
      "post": {
        "summary": "케이스 상태 일괄 업데이트",
        "description": "한 번의 호출로 여러 케이스에 동일한 상태 전환을 적용합니다. OPEN은 재개, AWAITING_USER는 정보 요청, RESOLVED는 해결(해결 사유 필수)을 나타냅니다. 각 케이스는 독립적으로 평가되며, 게이트 실패(체크리스트 미완료, 필수 메모 누락)는 배치를 중단하지 않고 케이스별로 보고됩니다.",
        "operationId": "bulk_update_case_status",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "bulk_update_status",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "case_uuids",
                  "status"
                ],
                "properties": {
                  "case_uuids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "OPEN",
                      "AWAITING_USER",
                      "RESOLVED"
                    ]
                  },
                  "resolution": {
                    "type": "string",
                    "enum": [
                      "FALSE_POSITIVE",
                      "VALID_THREAT",
                      "INCONCLUSIVE",
                      "REQUIREMENTS_NOT_MET",
                      "REQUIREMENTS_SATISFIED"
                    ],
                    "description": "status가 RESOLVED일 때 필수입니다."
                  },
                  "note": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "example": {
                "case_uuids": [
                  "c1a5e000-0000-4000-8000-000000000001"
                ],
                "status": "RESOLVED",
                "resolution": "FALSE_POSITIVE"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/bulk/status/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"case_uuids\": [\"c1a5e000-0000-4000-8000-000000000001\"], \"status\": \"RESOLVED\", \"resolution\": \"FALSE_POSITIVE\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.bulk_update_status(\n    case_uuids=[\"c1a5e000-0000-4000-8000-000000000001\"],\n    status=\"RESOLVED\",\n    resolution=\"FALSE_POSITIVE\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.bulkUpdateStatus({\n  case_uuids: [\"c1a5e000-0000-4000-8000-000000000001\"],\n  status: \"RESOLVED\",\n  resolution: \"FALSE_POSITIVE\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.BulkUpdateStatus(ctx, didit.CasesBulkUpdateStatusParams{\n\tCaseUUIDs:  []string{\"c1a5e000-0000-4000-8000-000000000001\"},\n\tStatus:     \"RESOLVED\",\n\tResolution: didit.Some(didit.CasesBulkUpdateStatusParamsResolution(\"FALSE_POSITIVE\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CasesBulkUpdateStatusParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().bulkUpdateStatus(CasesBulkUpdateStatusParams.builder()\n        .caseUuids(List.of(\"c1a5e000-0000-4000-8000-000000000001\"))\n        .status(CasesBulkUpdateStatusParams.Status.of(\"RESOLVED\"))\n        .resolution(CasesBulkUpdateStatusParams.Resolution.of(\"FALSE_POSITIVE\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->bulkUpdateStatus([\n    'case_uuids' => ['c1a5e000-0000-4000-8000-000000000001'],\n    'status' => 'RESOLVED',\n    'resolution' => 'FALSE_POSITIVE',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.bulk_update_status(\n  case_uuids: [\"c1a5e000-0000-4000-8000-000000000001\"],\n  status: \"RESOLVED\",\n  resolution: \"FALSE_POSITIVE\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.BulkUpdateStatusAsync(new CasesBulkUpdateStatusParams\n{\n    CaseUuids = new string[] { \"c1a5e000-0000-4000-8000-000000000001\" },\n    Status = \"RESOLVED\",\n    Resolution = new CasesBulkUpdateStatusParamsResolution(\"FALSE_POSITIVE\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "케이스별 결과입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBulkUpdateResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/bulk/assign/": {
      "post": {
        "summary": "케이스 일괄 배정",
        "description": "여러 케이스를 한 번에 할당(또는 assignee_user_id: null로 할당 해제)합니다. 모든 케이스는 동일한 블루프린트를 공유해야 하며, 불일치는 배치를 중단하지 않고 케이스별로 보고됩니다.",
        "operationId": "bulk_assign_cases",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "bulk_assign",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "case_uuids",
                  "assignee_user_id"
                ],
                "properties": {
                  "case_uuids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1
                  },
                  "assignee_user_id": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true
                  },
                  "assignee_email": {
                    "type": "string",
                    "format": "email",
                    "nullable": true
                  },
                  "assignee_name": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "example": {
                "case_uuids": [
                  "c1a5e000-0000-4000-8000-000000000001"
                ],
                "assignee_user_id": "9a000000-0000-4000-8000-0000000000aa"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/bulk/assign/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"case_uuids\": [\"c1a5e000-0000-4000-8000-000000000001\"], \"assignee_user_id\": \"9a000000-0000-4000-8000-0000000000aa\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.bulk_assign(\n    case_uuids=[\"c1a5e000-0000-4000-8000-000000000001\"],\n    assignee_user_id=\"9a000000-0000-4000-8000-0000000000aa\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.bulkAssign({\n  case_uuids: [\"c1a5e000-0000-4000-8000-000000000001\"],\n  assignee_user_id: \"9a000000-0000-4000-8000-0000000000aa\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.BulkAssign(ctx, didit.CasesBulkAssignParams{\n\tCaseUUIDs:      []string{\"c1a5e000-0000-4000-8000-000000000001\"},\n\tAssigneeUserID: didit.String(\"9a000000-0000-4000-8000-0000000000aa\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CasesBulkAssignParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().bulkAssign(CasesBulkAssignParams.builder()\n        .caseUuids(List.of(\"c1a5e000-0000-4000-8000-000000000001\"))\n        .assigneeUserId(\"9a000000-0000-4000-8000-0000000000aa\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->bulkAssign([\n    'case_uuids' => ['c1a5e000-0000-4000-8000-000000000001'],\n    'assignee_user_id' => '9a000000-0000-4000-8000-0000000000aa',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.bulk_assign(\n  case_uuids: [\"c1a5e000-0000-4000-8000-000000000001\"],\n  assignee_user_id: \"9a000000-0000-4000-8000-0000000000aa\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.BulkAssignAsync(new CasesBulkAssignParams\n{\n    CaseUuids = new string[] { \"c1a5e000-0000-4000-8000-000000000001\" },\n    AssigneeUserId = \"9a000000-0000-4000-8000-0000000000aa\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "케이스별 결과입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBulkUpdateResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/": {
      "get": {
        "summary": "블루프린트 목록 조회",
        "description": "애플리케이션의 케이스 블루프린트 목록을 조회합니다.",
        "operationId": "list_case_blueprints",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "페이지 크기입니다."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "0부터 시작하는 오프셋입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.blueprints.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.blueprints.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Blueprints.ListAutoPaging(ctx, didit.CasesBlueprintsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().blueprints().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->blueprints->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.blueprints.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Blueprints.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "페이지 단위로 제공되는 청사진 목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "일치하는 행 수이며, 성능을 위해 최대 100개로 제한됩니다."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaseBlueprintListItem"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "청사진 생성",
        "description": "케이스 청사진을 생성합니다. 일반 설정(할당, 에스컬레이션, 이관, 상호 검토 페어링) 및 케이스 페이지를 구동하는 6개 섹션인 content_config를 포함합니다. 게시되지 않은 초안을 생성하려면 publish=false로 설정하십시오. 게시하면 첫 번째 라이브 버전이 생성됩니다. 한 번도 게시되지 않은 초안을 폐기하면 삭제됩니다.",
        "operationId": "create_case_blueprint",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "assignee_pool"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 24,
                    "description": "최대 24자(예: \"AML investigation\")."
                  },
                  "description": {
                    "type": "string",
                    "nullable": true
                  },
                  "assignee_pool": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1,
                    "description": "사용자 UUID 목록입니다. 빈 배열은 \"Pick at least one assignee\" 오류와 함께 거부됩니다."
                  },
                  "assignment_method": {
                    "type": "string",
                    "enum": [
                      "MANUAL",
                      "AUTOMATIC"
                    ],
                    "default": "MANUAL"
                  },
                  "max_active_cases": {
                    "type": "integer",
                    "nullable": true,
                    "minimum": 1,
                    "description": "자동 모드 임계값: \"이 청사진에 할당된 케이스가 N개 미만\"."
                  },
                  "escalation_enabled": {
                    "type": "boolean",
                    "default": false
                  },
                  "escalation_blueprint": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "대상 청사진 UUID입니다. 저장 시에는 강제되지 않지만, escalation_enabled와 escalation_blueprint가 모두 설정될 때까지 에스컬레이션 작업은 400으로 실패합니다."
                  },
                  "transfer_enabled": {
                    "type": "boolean",
                    "default": false
                  },
                  "four_eyes_checker_blueprint": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "이를 설정하면 4-eyes 검토가 활성화됩니다. 이 청사진의 결정 사항이 검사자 청사진의 대기열에 스테이징됩니다."
                  },
                  "require_resolution_note": {
                    "type": "boolean",
                    "default": false
                  },
                  "content_config": {
                    "$ref": "#/components/schemas/CaseContentConfig"
                  },
                  "is_active": {
                    "type": "boolean",
                    "default": true
                  },
                  "default_deadline_hours": {
                    "type": "integer",
                    "nullable": true,
                    "minimum": 1,
                    "maximum": 8760,
                    "description": "새로 열린 케이스의 기본 기한입니다. 기존 케이스의 기한은 변경되지 않습니다."
                  },
                  "publish": {
                    "type": "boolean",
                    "writeOnly": true,
                    "default": true,
                    "description": "게시된 적 없는 초안으로 저장하려면 false로 설정합니다. 초안이 명시적으로 게시될 때까지 레코드는 버전 0인 비활성 상태로 유지됩니다. 이 필드를 생략하면 기존 연동에 대해 즉시 생성이 유지됩니다."
                  }
                }
              },
              "example": {
                "name": "AML investigation",
                "assignee_pool": [
                  "9a000000-0000-4000-8000-0000000000aa"
                ],
                "assignment_method": "AUTOMATIC",
                "max_active_cases": 15,
                "require_resolution_note": true,
                "content_config": {
                  "aml_control": {
                    "enabled": true,
                    "financial": true,
                    "identity": false
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"name\": \"AML investigation\", \"assignee_pool\": [\"9a000000-0000-4000-8000-0000000000aa\"], \"assignment_method\": \"AUTOMATIC\", \"max_active_cases\": 15, \"require_resolution_note\": true, \"content_config\": {\"aml_control\": {\"enabled\": true, \"financial\": true, \"identity\": false}}}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.create(\n    name=\"AML investigation\",\n    assignee_pool=[\"9a000000-0000-4000-8000-0000000000aa\"],\n    assignment_method=\"AUTOMATIC\",\n    max_active_cases=15,\n    require_resolution_note=True,\n    content_config={\n        \"aml_control\": {\n            \"enabled\": True,\n            \"financial\": True,\n            \"identity\": False,\n        },\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.create({\n  name: \"AML investigation\",\n  assignee_pool: [\"9a000000-0000-4000-8000-0000000000aa\"],\n  assignment_method: \"AUTOMATIC\",\n  max_active_cases: 15,\n  require_resolution_note: true,\n  content_config: {\n    aml_control: {\n      enabled: true,\n      financial: true,\n      identity: false,\n    },\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.Create(ctx, didit.CasesBlueprintsCreateParams{\n\tName:                  \"AML investigation\",\n\tAssigneePool:          []string{\"9a000000-0000-4000-8000-0000000000aa\"},\n\tAssignmentMethod:      didit.Some(didit.CasesBlueprintsCreateParamsAssignmentMethod(\"AUTOMATIC\")),\n\tMaxActiveCases:        didit.Int(15),\n\tRequireResolutionNote: didit.Bool(true),\n\tContentConfig: didit.Some(didit.CaseContentConfigParam{\n\t\tAMLControl: didit.Some(didit.CaseContentConfigParamAMLControl{\n\t\t\tEnabled:   didit.Bool(true),\n\t\t\tFinancial: didit.Bool(true),\n\t\t\tIdentity:  didit.Bool(false),\n\t\t}),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CaseContentConfig;\nimport me.didit.types.CasesBlueprintsCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().create(CasesBlueprintsCreateParams.builder()\n        .name(\"AML investigation\")\n        .assigneePool(List.of(\"9a000000-0000-4000-8000-0000000000aa\"))\n        .assignmentMethod(CasesBlueprintsCreateParams.AssignmentMethod.of(\"AUTOMATIC\"))\n        .maxActiveCases(15L)\n        .requireResolutionNote(true)\n        .contentConfig(CaseContentConfig.builder()\n                .amlControl(CaseContentConfig.AmlControl.builder()\n                        .enabled(true)\n                        .financial(true)\n                        .identity(false)\n                        .build())\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->create([\n    'name' => 'AML investigation',\n    'assignee_pool' => ['9a000000-0000-4000-8000-0000000000aa'],\n    'assignment_method' => 'AUTOMATIC',\n    'max_active_cases' => 15,\n    'require_resolution_note' => true,\n    'content_config' => [\n        'aml_control' => [\n            'enabled' => true,\n            'financial' => true,\n            'identity' => false,\n        ],\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.create(\n  name: \"AML investigation\",\n  assignee_pool: [\"9a000000-0000-4000-8000-0000000000aa\"],\n  assignment_method: \"AUTOMATIC\",\n  max_active_cases: 15,\n  require_resolution_note: true,\n  content_config: {\n    aml_control: {\n      enabled: true,\n      financial: true,\n      identity: false,\n    },\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.CreateAsync(new CasesBlueprintsCreateParams\n{\n    Name = \"AML investigation\",\n    AssigneePool = new string[] { \"9a000000-0000-4000-8000-0000000000aa\" },\n    AssignmentMethod = new CasesBlueprintsCreateParamsAssignmentMethod(\"AUTOMATIC\"),\n    MaxActiveCases = 15,\n    RequireResolutionNote = true,\n    ContentConfig = new CaseContentConfig\n    {\n        AmlControl = new CaseContentConfigAmlControl\n        {\n            Enabled = true,\n            Financial = true,\n            Identity = false,\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "청사진이 생성되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBlueprintDetail"
                }
              }
            }
          },
          "400": {
            "description": "이름이 24자를 초과하거나, assignee_pool이 비어 있거나, 상호 참조된 청사진(escalation/checker)을 찾을 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/{blueprint_uuid}/": {
      "get": {
        "summary": "청사진 조회",
        "description": "연결된 생성 소스(AML 설정, 거래 규칙, 워크플로 노드) 및 해당 블루프린트로 에스컬레이션되는 블루프린트를 포함하여 블루프린트를 조회합니다.",
        "operationId": "get_case_blueprint",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "blueprint_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "b1de0000-0000-4000-8000-000000000002"
            },
            "description": "청사진 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/b1de0000-0000-4000-8000-000000000002/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.retrieve(\n    \"b1de0000-0000-4000-8000-000000000002\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.retrieve(\"b1de0000-0000-4000-8000-000000000002\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.Retrieve(ctx, \"b1de0000-0000-4000-8000-000000000002\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().retrieve(\"b1de0000-0000-4000-8000-000000000002\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->retrieve('b1de0000-0000-4000-8000-000000000002');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.retrieve(\"b1de0000-0000-4000-8000-000000000002\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.RetrieveAsync(\"b1de0000-0000-4000-8000-000000000002\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "청사진 세부 정보입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBlueprintDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "청사진 업데이트",
        "description": "청사진의 일반 설정 또는 content_config를 부분 업데이트합니다.",
        "operationId": "update_case_blueprint",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "blueprint_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "b1de0000-0000-4000-8000-000000000002"
            },
            "description": "청사진 UUID입니다."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 24,
                    "description": "최대 24자(예: \"AML investigation\")."
                  },
                  "description": {
                    "type": "string",
                    "nullable": true
                  },
                  "assignee_pool": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1,
                    "description": "사용자 UUID 목록입니다. 빈 배열은 \"Pick at least one assignee\" 오류와 함께 거부됩니다."
                  },
                  "assignment_method": {
                    "type": "string",
                    "enum": [
                      "MANUAL",
                      "AUTOMATIC"
                    ]
                  },
                  "max_active_cases": {
                    "type": "integer",
                    "nullable": true,
                    "minimum": 1,
                    "description": "자동 모드 임계값: \"이 청사진에 할당된 케이스가 N개 미만\"."
                  },
                  "escalation_enabled": {
                    "type": "boolean"
                  },
                  "escalation_blueprint": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "대상 청사진 UUID입니다. 저장 시에는 강제되지 않지만, escalation_enabled와 escalation_blueprint가 모두 설정될 때까지 에스컬레이션 작업은 400으로 실패합니다."
                  },
                  "transfer_enabled": {
                    "type": "boolean"
                  },
                  "four_eyes_checker_blueprint": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "이를 설정하면 4-eyes 검토가 활성화됩니다. 이 청사진의 결정 사항이 검사자 청사진의 대기열에 스테이징됩니다."
                  },
                  "require_resolution_note": {
                    "type": "boolean"
                  },
                  "content_config": {
                    "$ref": "#/components/schemas/CaseContentConfig"
                  },
                  "is_active": {
                    "type": "boolean"
                  },
                  "default_deadline_hours": {
                    "type": "integer",
                    "nullable": true,
                    "minimum": 1,
                    "maximum": 8760,
                    "description": "새로 열린 케이스의 기본 기한입니다. 기존 케이스의 기한은 변경되지 않습니다."
                  },
                  "expected_version": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "에디터에서 연 버전입니다. 오래된 버전은 검토 정책을 변경하지 않고 409를 반환합니다."
                  }
                }
              },
              "example": {
                "transfer_enabled": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/b1de0000-0000-4000-8000-000000000002/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"transfer_enabled\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.update(\n    \"b1de0000-0000-4000-8000-000000000002\",\n    transfer_enabled=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.update(\"b1de0000-0000-4000-8000-000000000002\", {\n  transfer_enabled: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.Update(ctx, \"b1de0000-0000-4000-8000-000000000002\", didit.CasesBlueprintsUpdateParams{\n\tTransferEnabled: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesBlueprintsUpdateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().update(\"b1de0000-0000-4000-8000-000000000002\", CasesBlueprintsUpdateParams.builder()\n        .transferEnabled(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->update('b1de0000-0000-4000-8000-000000000002', [\n    'transfer_enabled' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.update(\n  \"b1de0000-0000-4000-8000-000000000002\",\n  transfer_enabled: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.UpdateAsync(\"b1de0000-0000-4000-8000-000000000002\", new CasesBlueprintsUpdateParams\n{\n    TransferEnabled = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "업데이트된 청사진입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBlueprintDetail"
                }
              }
            }
          },
          "409": {
            "description": "expected_version 이후 검토 정책이 변경되었습니다. 재시도하기 전에 최신 버전을 검토하십시오."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "summary": "청사진 삭제",
        "description": "청사진을 삭제합니다. 삭제는 항상 성공하며 청사진의 케이스에는 영향을 주지 않습니다. 기존 케이스는 청사진 참조를 유지하고 해당 설정이 계속 적용됩니다. 삭제된 청사진은 더 이상 청사진 목록에 나타나지 않으며 이관 대상으로 선택할 수 없습니다. 상호 검토(4-eyes) 승인 대기 중인 해결안이 있는 상태에서 작성자 청사진이 삭제되면, 해결안이 거부될 경우 케이스는 검토자 청사진에 유지됩니다.",
        "operationId": "delete_case_blueprint",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "blueprint_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "b1de0000-0000-4000-8000-000000000002"
            },
            "description": "청사진 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/b1de0000-0000-4000-8000-000000000002/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.blueprints.delete(\n    \"b1de0000-0000-4000-8000-000000000002\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.blueprints.delete(\"b1de0000-0000-4000-8000-000000000002\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Blueprints.Delete(ctx, \"b1de0000-0000-4000-8000-000000000002\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().blueprints().delete(\"b1de0000-0000-4000-8000-000000000002\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->cases->blueprints->delete('b1de0000-0000-4000-8000-000000000002');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.blueprints.delete(\"b1de0000-0000-4000-8000-000000000002\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.Blueprints.DeleteAsync(\"b1de0000-0000-4000-8000-000000000002\");"
          }
        ],
        "responses": {
          "204": {
            "description": "청사진이 삭제되었습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/presets/": {
      "get": {
        "summary": "블루프린트 프리셋 목록 조회",
        "description": "4가지 기본 제공 프리셋(스크리닝 히트, AML 조사, 의심스러운 활동, KYC 검토)을 해당 content_config 및 각 프리셋이 이 애플리케이션에 이미 설치되어 있는지 여부와 함께 나열합니다.",
        "operationId": "list_case_blueprint_presets",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "list_presets",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/presets/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.list_presets()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.listPresets();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.ListPresets(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().listPresets();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->listPresets();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.list_presets\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.ListPresetsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "프리셋 카탈로그입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "preset_key": {
                            "type": "string",
                            "enum": [
                              "screening_hit",
                              "aml_investigation",
                              "suspicious_activity",
                              "kyc"
                            ]
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "content_config": {
                            "$ref": "#/components/schemas/CaseContentConfig"
                          },
                          "installed": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/presets/install/": {
      "post": {
        "summary": "청사진 프리셋 설치",
        "description": "하나 이상의 프리셋을 수정 가능한 청사진으로 애플리케이션에 복사합니다. preset_key마다 멱등성을 가집니다. 아직 설치되지 않은 모든 프리셋을 설치하려면 preset_keys를 생략하십시오.",
        "operationId": "install_case_blueprint_presets",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "install_presets",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "preset_keys": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "nullable": true,
                    "description": "screening_hit, aml_investigation, suspicious_activity, kyc의 하위 집합입니다. 모두 설치하려면 생략합니다."
                  }
                }
              },
              "example": {
                "preset_keys": [
                  "aml_investigation",
                  "kyc"
                ]
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/presets/install/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"preset_keys\": [\"aml_investigation\", \"kyc\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.install_presets(\n    preset_keys=[\"aml_investigation\", \"kyc\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.installPresets({\n  preset_keys: [\"aml_investigation\", \"kyc\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.InstallPresets(ctx, didit.CasesBlueprintsInstallPresetsParams{\n\tPresetKeys: didit.Some([]string{\"aml_investigation\", \"kyc\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CasesBlueprintsInstallPresetsParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().installPresets(CasesBlueprintsInstallPresetsParams.builder()\n        .presetKeys(List.of(\"aml_investigation\", \"kyc\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->installPresets([\n    'preset_keys' => ['aml_investigation', 'kyc'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.install_presets(preset_keys: [\"aml_investigation\", \"kyc\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.InstallPresetsAsync(new CasesBlueprintsInstallPresetsParams\n{\n    PresetKeys = new string[] { \"aml_investigation\", \"kyc\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "하나 이상의 프리셋이 설치되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBlueprintPresetInstallResult"
                }
              }
            }
          },
          "200": {
            "description": "설치할 새 프리셋이 없습니다(요청된 모든 프리셋이 이미 존재함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBlueprintPresetInstallResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/report-templates/": {
      "get": {
        "summary": "보고서 템플릿 목록 조회",
        "description": "애플리케이션의 FIU 보고서 템플릿 목록을 조회합니다.",
        "operationId": "list_report_templates",
        "x-didit-sdk": {
          "resource": "report_templates",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Report Templates"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "페이지 크기입니다."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "0부터 시작하는 오프셋입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.report_templates.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.reportTemplates.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.ReportTemplates.ListAutoPaging(ctx, didit.ReportTemplatesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.reportTemplates().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->reportTemplates->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.report_templates.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.ReportTemplates.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "페이지네이션된 템플릿 목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "일치하는 행 수이며, 성능을 위해 최대 100개로 제한됩니다."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ReportTemplateDetail"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "보고서 템플릿 생성",
        "description": "관할권별, 보고서 유형별로 재사용 가능한 goAML 헤더 템플릿을 생성합니다. field_config에 템플릿 수준의 필수 필드(rentity_id, submission_code, currency_code_local) 중 하나라도 누락된 경우 400으로 거부됩니다. 유효하지 않은 템플릿은 저장하거나 보고서를 생성하는 데 사용할 수 없습니다. 신고별 헤더 필드(action, submission_date, transactions)는 보고서 유효성 검사/확정 시점에 대신 적용됩니다.",
        "operationId": "create_report_template",
        "x-didit-sdk": {
          "resource": "report_templates",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Report Templates"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "jurisdiction",
                  "report_type"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "jurisdiction": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2,
                    "description": "저장 시 대문자로 변환되는 ISO 3166-1 alpha-2 국가 코드입니다."
                  },
                  "report_type": {
                    "type": "string",
                    "enum": [
                      "SAR",
                      "STR",
                      "CTR",
                      "TTR",
                      "UTR",
                      "IFT",
                      "CBR",
                      "TFR"
                    ]
                  },
                  "field_config": {
                    "type": "object",
                    "description": "재사용 가능한 goAML 헤더 기본값입니다. 템플릿 수준 필수 필드: rentity_id, submission_code 및 currency_code_local(3자리 문자). 선택 사항: enabled_fields(포함할 선택적 보고서 블록)와 reporting_person, location, reason 및 action 기본값. 제출 건별 헤더 필드(action, submission_date, transactions, jurisdiction)는 템플릿이 아닌 보고서가 검증되거나 완료될 때 적용됩니다."
                  }
                }
              },
              "example": {
                "name": "US SAR default",
                "jurisdiction": "US",
                "report_type": "SAR",
                "field_config": {
                  "rentity_id": "FIU-US-00123",
                  "submission_code": "E",
                  "currency_code_local": "USD"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"name\": \"US SAR default\", \"jurisdiction\": \"US\", \"report_type\": \"SAR\", \"field_config\": {\"rentity_id\": \"FIU-US-00123\", \"submission_code\": \"E\", \"currency_code_local\": \"USD\"}}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.report_templates.create(\n    name=\"US SAR default\",\n    jurisdiction=\"US\",\n    report_type=\"SAR\",\n    field_config={\"rentity_id\": \"FIU-US-00123\", \"submission_code\": \"E\", \"currency_code_local\": \"USD\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.reportTemplates.create({\n  name: \"US SAR default\",\n  jurisdiction: \"US\",\n  report_type: \"SAR\",\n  field_config: { rentity_id: \"FIU-US-00123\", submission_code: \"E\", currency_code_local: \"USD\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.ReportTemplates.Create(ctx, didit.ReportTemplatesCreateParams{\n\tName:         \"US SAR default\",\n\tJurisdiction: \"US\",\n\tReportType:   \"SAR\",\n\tFieldConfig:  didit.Some(map[string]any{\"rentity_id\": \"FIU-US-00123\", \"submission_code\": \"E\", \"currency_code_local\": \"USD\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.ReportTemplatesCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.reportTemplates().create(ReportTemplatesCreateParams.builder()\n        .name(\"US SAR default\")\n        .jurisdiction(\"US\")\n        .reportType(ReportTemplatesCreateParams.ReportType.of(\"SAR\"))\n        .fieldConfig(Map.of(\"rentity_id\", \"FIU-US-00123\", \"submission_code\", \"E\", \"currency_code_local\", \"USD\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->reportTemplates->create([\n    'name' => 'US SAR default',\n    'jurisdiction' => 'US',\n    'report_type' => 'SAR',\n    'field_config' => ['rentity_id' => 'FIU-US-00123', 'submission_code' => 'E', 'currency_code_local' => 'USD'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.report_templates.create(\n  name: \"US SAR default\",\n  jurisdiction: \"US\",\n  report_type: \"SAR\",\n  field_config: { rentity_id: \"FIU-US-00123\", submission_code: \"E\", currency_code_local: \"USD\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.ReportTemplates.CreateAsync(new ReportTemplatesCreateParams\n{\n    Name = \"US SAR default\",\n    Jurisdiction = \"US\",\n    ReportType = \"SAR\",\n    FieldConfig = new Dictionary<string, object> { [\"rentity_id\"] = \"FIU-US-00123\", [\"submission_code\"] = \"E\", [\"currency_code_local\"] = \"USD\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "템플릿이 생성되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportTemplateDetail"
                }
              }
            }
          },
          "400": {
            "description": "인식할 수 없는 관할권이거나, field_config가 필수 필드 유효성 검사에 실패했습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/report-templates/{template_uuid}/": {
      "get": {
        "summary": "보고서 템플릿 가져오기",
        "description": "보고서 템플릿 조회",
        "operationId": "get_report_template",
        "x-didit-sdk": {
          "resource": "report_templates",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Report Templates"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "template_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "7ec00000-0000-4000-8000-000000000006"
            },
            "description": "보고서 템플릿 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/7ec00000-0000-4000-8000-000000000006/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.report_templates.retrieve(\n    \"7ec00000-0000-4000-8000-000000000006\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.reportTemplates.retrieve(\"7ec00000-0000-4000-8000-000000000006\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.ReportTemplates.Retrieve(ctx, \"7ec00000-0000-4000-8000-000000000006\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.reportTemplates().retrieve(\"7ec00000-0000-4000-8000-000000000006\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->reportTemplates->retrieve('7ec00000-0000-4000-8000-000000000006');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.report_templates.retrieve(\"7ec00000-0000-4000-8000-000000000006\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.ReportTemplates.RetrieveAsync(\"7ec00000-0000-4000-8000-000000000006\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "템플릿 세부 정보입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportTemplateDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "보고서 템플릿 업데이트",
        "description": "보고서 템플릿을 부분 업데이트합니다. 저장 시 필수 goAML 필드를 다시 검증합니다.",
        "operationId": "update_report_template",
        "x-didit-sdk": {
          "resource": "report_templates",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Report Templates"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "template_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "7ec00000-0000-4000-8000-000000000006"
            },
            "description": "보고서 템플릿 UUID입니다."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "jurisdiction": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2,
                    "description": "저장 시 대문자로 변환되는 ISO 3166-1 alpha-2 국가 코드입니다."
                  },
                  "report_type": {
                    "type": "string",
                    "enum": [
                      "SAR",
                      "STR",
                      "CTR",
                      "TTR",
                      "UTR",
                      "IFT",
                      "CBR",
                      "TFR"
                    ]
                  },
                  "field_config": {
                    "type": "object",
                    "description": "재사용 가능한 goAML 헤더 기본값입니다. 템플릿 수준 필수 필드: rentity_id, submission_code 및 currency_code_local(3자리 문자). 선택 사항: enabled_fields(포함할 선택적 보고서 블록)와 reporting_person, location, reason 및 action 기본값. 제출 건별 헤더 필드(action, submission_date, transactions, jurisdiction)는 템플릿이 아닌 보고서가 검증되거나 완료될 때 적용됩니다."
                  }
                }
              },
              "example": {
                "field_config": {
                  "rentity_id": "FIU-US-00124"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/7ec00000-0000-4000-8000-000000000006/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"field_config\": {\"rentity_id\": \"FIU-US-00124\"}}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.report_templates.update(\n    \"7ec00000-0000-4000-8000-000000000006\",\n    field_config={\"rentity_id\": \"FIU-US-00124\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.reportTemplates.update(\"7ec00000-0000-4000-8000-000000000006\", {\n  field_config: { rentity_id: \"FIU-US-00124\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.ReportTemplates.Update(ctx, \"7ec00000-0000-4000-8000-000000000006\", didit.ReportTemplatesUpdateParams{\n\tFieldConfig: didit.Some(map[string]any{\"rentity_id\": \"FIU-US-00124\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.ReportTemplatesUpdateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.reportTemplates().update(\"7ec00000-0000-4000-8000-000000000006\", ReportTemplatesUpdateParams.builder()\n        .fieldConfig(Map.of(\"rentity_id\", \"FIU-US-00124\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->reportTemplates->update('7ec00000-0000-4000-8000-000000000006', [\n    'field_config' => ['rentity_id' => 'FIU-US-00124'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.report_templates.update(\n  \"7ec00000-0000-4000-8000-000000000006\",\n  field_config: { rentity_id: \"FIU-US-00124\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.ReportTemplates.UpdateAsync(\"7ec00000-0000-4000-8000-000000000006\", new ReportTemplatesUpdateParams\n{\n    FieldConfig = new Dictionary<string, object> { [\"rentity_id\"] = \"FIU-US-00124\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "업데이트된 템플릿입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportTemplateDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "summary": "보고서 템플릿 삭제",
        "description": "보고서 템플릿을 삭제합니다. 해당 템플릿으로 이미 생성된 보고서에는 영향을 주지 않습니다.",
        "operationId": "delete_report_template",
        "x-didit-sdk": {
          "resource": "report_templates",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Report Templates"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "template_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "7ec00000-0000-4000-8000-000000000006"
            },
            "description": "보고서 템플릿 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/7ec00000-0000-4000-8000-000000000006/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.report_templates.delete(\n    \"7ec00000-0000-4000-8000-000000000006\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.reportTemplates.delete(\"7ec00000-0000-4000-8000-000000000006\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.ReportTemplates.Delete(ctx, \"7ec00000-0000-4000-8000-000000000006\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.reportTemplates().delete(\"7ec00000-0000-4000-8000-000000000006\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->reportTemplates->delete('7ec00000-0000-4000-8000-000000000006');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.report_templates.delete(\"7ec00000-0000-4000-8000-000000000006\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.ReportTemplates.DeleteAsync(\"7ec00000-0000-4000-8000-000000000006\");"
          }
        ],
        "responses": {
          "204": {
            "description": "템플릿이 삭제되었습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/regulatory-reports/": {
      "get": {
        "summary": "케이스 보고서 목록 조회",
        "description": "케이스에 대해 생성된 FIU 보고서 목록을 조회합니다.",
        "operationId": "list_case_regulatory_reports",
        "x-didit-sdk": {
          "resource": "cases.regulatory_reports",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "페이지 크기입니다."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "0부터 시작하는 오프셋입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/regulatory-reports/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.regulatory_reports.list(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.regulatoryReports.list(\"c1a5e000-0000-4000-8000-000000000001\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.RegulatoryReports.ListAutoPaging(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesRegulatoryReportsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().regulatoryReports().list(\"c1a5e000-0000-4000-8000-000000000001\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->regulatoryReports->list('c1a5e000-0000-4000-8000-000000000001') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.regulatory_reports.list(\"c1a5e000-0000-4000-8000-000000000001\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.RegulatoryReports.ListAsync(\"c1a5e000-0000-4000-8000-000000000001\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "케이스에 대한 페이지네이션된 보고서 목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportList"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "케이스에서 보고서 생성",
        "description": "케이스에 대한 FIU 보고서 초안을 생성합니다. DRAFT 상태이며, 선택적 템플릿과 케이스의 대상, 연결된 거래 및 설명문에서 자동으로 채워집니다. 유효성을 검사한 후 확정하여 goAML XML 및 PDF를 생성합니다.",
        "operationId": "create_case_regulatory_report",
        "x-didit-sdk": {
          "resource": "cases.regulatory_reports",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "케이스 UUID."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "report_type": {
                    "type": "string",
                    "enum": [
                      "SAR",
                      "STR",
                      "CTR",
                      "TTR",
                      "UTR",
                      "IFT",
                      "CBR",
                      "TFR"
                    ],
                    "description": "템플릿이 제공되지 않으면 필수입니다. 그렇지 않은 경우 템플릿의 report_type이 사용됩니다."
                  },
                  "jurisdiction": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2,
                    "description": "템플릿이 제공되지 않으면 필수입니다."
                  },
                  "template": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "보고서 템플릿 UUID입니다. 케이스 파생 데이터가 병합되기 전에 해당 field_config가 초안의 초기값을 설정합니다."
                  },
                  "transactions": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "nullable": true,
                    "description": "첨부할 거래입니다. 기본값은 케이스의 연결된 거래입니다."
                  },
                  "rentity_id": {
                    "type": "string",
                    "nullable": true
                  },
                  "rentity_branch": {
                    "type": "string",
                    "nullable": true
                  },
                  "submission_code": {
                    "type": "string",
                    "enum": [
                      "E",
                      "M"
                    ],
                    "default": "E"
                  },
                  "entity_reference": {
                    "type": "string",
                    "nullable": true
                  },
                  "fiu_ref_number": {
                    "type": "string",
                    "nullable": true
                  },
                  "currency_code_local": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 3,
                    "nullable": true
                  },
                  "submission_date": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  },
                  "reporting_person": {
                    "type": "object"
                  },
                  "location": {
                    "type": "object"
                  },
                  "reason": {
                    "type": "string",
                    "nullable": true
                  },
                  "action": {
                    "type": "string",
                    "nullable": true
                  },
                  "activity": {
                    "type": "string",
                    "nullable": true
                  },
                  "narrative": {
                    "type": "object",
                    "properties": {
                      "who": {
                        "type": "string"
                      },
                      "what": {
                        "type": "string"
                      },
                      "when": {
                        "type": "string"
                      },
                      "where": {
                        "type": "string"
                      },
                      "why": {
                        "type": "string"
                      },
                      "how": {
                        "type": "string"
                      }
                    }
                  },
                  "report_indicators": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "included_fields": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "example": {
                "template": "7ec00000-0000-4000-8000-000000000006"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/regulatory-reports/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"template\": \"7ec00000-0000-4000-8000-000000000006\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.regulatory_reports.create(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    template=\"7ec00000-0000-4000-8000-000000000006\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.regulatoryReports.create(\"c1a5e000-0000-4000-8000-000000000001\", {\n  template: \"7ec00000-0000-4000-8000-000000000006\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RegulatoryReports.Create(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesRegulatoryReportsCreateParams{\n\tTemplate: didit.String(\"7ec00000-0000-4000-8000-000000000006\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesRegulatoryReportsCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().regulatoryReports().create(\"c1a5e000-0000-4000-8000-000000000001\", CasesRegulatoryReportsCreateParams.builder()\n        .template(\"7ec00000-0000-4000-8000-000000000006\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->regulatoryReports->create('c1a5e000-0000-4000-8000-000000000001', [\n    'template' => '7ec00000-0000-4000-8000-000000000006',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.regulatory_reports.create(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  template: \"7ec00000-0000-4000-8000-000000000006\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RegulatoryReports.CreateAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesRegulatoryReportsCreateParams\n{\n    Template = \"7ec00000-0000-4000-8000-000000000006\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "초안 보고서가 생성되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportDetail"
                }
              }
            }
          },
          "400": {
            "description": "참조된 템플릿을 찾을 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/regulatory-reports/": {
      "get": {
        "summary": "보고서 목록 조회",
        "description": "상태, report_type 또는 케이스별로 필터링할 수 있는 애플리케이션 전체 FIU 보고서 목록입니다.",
        "operationId": "list_regulatory_reports",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "페이지 크기입니다."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "0부터 시작하는 오프셋입니다."
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "VALIDATED",
                "FINALIZED"
              ]
            },
            "description": "상태별로 필터링합니다."
          },
          {
            "name": "report_type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "SAR",
                "STR",
                "CTR",
                "TTR",
                "UTR",
                "IFT",
                "CBR",
                "TFR"
              ]
            },
            "description": "보고서 유형으로 필터링합니다."
          },
          {
            "name": "case",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "이 케이스의 보고서로 필터링합니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.regulatory_reports.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.regulatoryReports.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.RegulatoryReports.ListAutoPaging(ctx, didit.RegulatoryReportsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.regulatoryReports().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->regulatoryReports->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.regulatory_reports.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.RegulatoryReports.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "애플리케이션 전체에서 페이지 단위로 제공되는 보고서 목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportList"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "독립형 보고서 생성",
        "description": "독립된 보고서 페이지에서 FIU 보고서 초안을 생성합니다. 케이스와 템플릿이 모두 필요합니다(템플릿을 생략할 수 있는 케이스 범위 생성과 다름).",
        "operationId": "create_standalone_regulatory_report",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "case",
                  "template"
                ],
                "properties": {
                  "case": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "template": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "report_type": {
                    "type": "string",
                    "enum": [
                      "SAR",
                      "STR",
                      "CTR",
                      "TTR",
                      "UTR",
                      "IFT",
                      "CBR",
                      "TFR"
                    ],
                    "description": "템플릿이 제공되지 않으면 필수입니다. 그렇지 않은 경우 템플릿의 report_type이 사용됩니다."
                  },
                  "jurisdiction": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2,
                    "description": "템플릿이 제공되지 않으면 필수입니다."
                  },
                  "transactions": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "nullable": true,
                    "description": "첨부할 거래입니다. 기본값은 케이스의 연결된 거래입니다."
                  },
                  "rentity_id": {
                    "type": "string",
                    "nullable": true
                  },
                  "rentity_branch": {
                    "type": "string",
                    "nullable": true
                  },
                  "submission_code": {
                    "type": "string",
                    "enum": [
                      "E",
                      "M"
                    ],
                    "default": "E"
                  },
                  "entity_reference": {
                    "type": "string",
                    "nullable": true
                  },
                  "fiu_ref_number": {
                    "type": "string",
                    "nullable": true
                  },
                  "currency_code_local": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 3,
                    "nullable": true
                  },
                  "submission_date": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  },
                  "reporting_person": {
                    "type": "object"
                  },
                  "location": {
                    "type": "object"
                  },
                  "reason": {
                    "type": "string",
                    "nullable": true
                  },
                  "action": {
                    "type": "string",
                    "nullable": true
                  },
                  "activity": {
                    "type": "string",
                    "nullable": true
                  },
                  "narrative": {
                    "type": "object",
                    "properties": {
                      "who": {
                        "type": "string"
                      },
                      "what": {
                        "type": "string"
                      },
                      "when": {
                        "type": "string"
                      },
                      "where": {
                        "type": "string"
                      },
                      "why": {
                        "type": "string"
                      },
                      "how": {
                        "type": "string"
                      }
                    }
                  },
                  "report_indicators": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "included_fields": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "example": {
                "case": "c1a5e000-0000-4000-8000-000000000001",
                "template": "7ec00000-0000-4000-8000-000000000006"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"case\": \"c1a5e000-0000-4000-8000-000000000001\", \"template\": \"7ec00000-0000-4000-8000-000000000006\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.create(\n    case=\"c1a5e000-0000-4000-8000-000000000001\",\n    template=\"7ec00000-0000-4000-8000-000000000006\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.create({\n  case: \"c1a5e000-0000-4000-8000-000000000001\",\n  template: \"7ec00000-0000-4000-8000-000000000006\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Create(ctx, didit.RegulatoryReportsCreateParams{\n\tCase:     \"c1a5e000-0000-4000-8000-000000000001\",\n\tTemplate: \"7ec00000-0000-4000-8000-000000000006\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.RegulatoryReportsCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().create(RegulatoryReportsCreateParams.builder()\n        .case_(\"c1a5e000-0000-4000-8000-000000000001\")\n        .template(\"7ec00000-0000-4000-8000-000000000006\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->regulatoryReports->create([\n    'case' => 'c1a5e000-0000-4000-8000-000000000001',\n    'template' => '7ec00000-0000-4000-8000-000000000006',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.create(\n  case: \"c1a5e000-0000-4000-8000-000000000001\",\n  template: \"7ec00000-0000-4000-8000-000000000006\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.CreateAsync(new RegulatoryReportsCreateParams\n{\n    Case = \"c1a5e000-0000-4000-8000-000000000001\",\n    Template = \"7ec00000-0000-4000-8000-000000000006\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "초안 보고서가 생성되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportDetail"
                }
              }
            }
          },
          "400": {
            "description": "참조된 템플릿을 찾을 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/regulatory-reports/{report_uuid}/": {
      "get": {
        "summary": "보고서 가져오기",
        "description": "규제 보고서를 조회합니다.",
        "operationId": "get_regulatory_report",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "report_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5ec00000-0000-4000-8000-000000000007"
            },
            "description": "보고서 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.retrieve(\n    \"5ec00000-0000-4000-8000-000000000007\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.retrieve(\"5ec00000-0000-4000-8000-000000000007\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Retrieve(ctx, \"5ec00000-0000-4000-8000-000000000007\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().retrieve(\"5ec00000-0000-4000-8000-000000000007\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->regulatoryReports->retrieve('5ec00000-0000-4000-8000-000000000007');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.retrieve(\"5ec00000-0000-4000-8000-000000000007\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.RetrieveAsync(\"5ec00000-0000-4000-8000-000000000007\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "보고서 세부 정보입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "보고서 업데이트",
        "description": "초안 또는 검증된 보고서의 필드를 수정합니다. 확정된 보고서는 수정할 수 없습니다(409).",
        "operationId": "update_regulatory_report",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "report_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5ec00000-0000-4000-8000-000000000007"
            },
            "description": "보고서 UUID입니다."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "jurisdiction": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2
                  },
                  "rentity_id": {
                    "type": "string",
                    "nullable": true
                  },
                  "rentity_branch": {
                    "type": "string",
                    "nullable": true
                  },
                  "submission_code": {
                    "type": "string",
                    "enum": [
                      "E",
                      "M"
                    ],
                    "default": "E"
                  },
                  "entity_reference": {
                    "type": "string",
                    "nullable": true
                  },
                  "fiu_ref_number": {
                    "type": "string",
                    "nullable": true
                  },
                  "currency_code_local": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 3,
                    "nullable": true
                  },
                  "submission_date": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  },
                  "reporting_person": {
                    "type": "object"
                  },
                  "location": {
                    "type": "object"
                  },
                  "reason": {
                    "type": "string",
                    "nullable": true
                  },
                  "action": {
                    "type": "string",
                    "nullable": true
                  },
                  "activity": {
                    "type": "string",
                    "nullable": true
                  },
                  "narrative": {
                    "type": "object",
                    "properties": {
                      "who": {
                        "type": "string"
                      },
                      "what": {
                        "type": "string"
                      },
                      "when": {
                        "type": "string"
                      },
                      "where": {
                        "type": "string"
                      },
                      "why": {
                        "type": "string"
                      },
                      "how": {
                        "type": "string"
                      }
                    }
                  },
                  "report_indicators": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "included_fields": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "example": {
                "rentity_id": "FIU-US-00123",
                "currency_code_local": "USD"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"rentity_id\": \"FIU-US-00123\", \"currency_code_local\": \"USD\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.update(\n    \"5ec00000-0000-4000-8000-000000000007\",\n    rentity_id=\"FIU-US-00123\",\n    currency_code_local=\"USD\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.update(\"5ec00000-0000-4000-8000-000000000007\", {\n  rentity_id: \"FIU-US-00123\",\n  currency_code_local: \"USD\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Update(ctx, \"5ec00000-0000-4000-8000-000000000007\", didit.RegulatoryReportsUpdateParams{\n\tRentityID:         didit.String(\"FIU-US-00123\"),\n\tCurrencyCodeLocal: didit.String(\"USD\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.RegulatoryReportsUpdateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().update(\"5ec00000-0000-4000-8000-000000000007\", RegulatoryReportsUpdateParams.builder()\n        .rentityId(\"FIU-US-00123\")\n        .currencyCodeLocal(\"USD\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->regulatoryReports->update('5ec00000-0000-4000-8000-000000000007', [\n    'rentity_id' => 'FIU-US-00123',\n    'currency_code_local' => 'USD',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.update(\n  \"5ec00000-0000-4000-8000-000000000007\",\n  rentity_id: \"FIU-US-00123\",\n  currency_code_local: \"USD\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.UpdateAsync(\"5ec00000-0000-4000-8000-000000000007\", new RegulatoryReportsUpdateParams\n{\n    RentityId = \"FIU-US-00123\",\n    CurrencyCodeLocal = \"USD\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "업데이트된 보고서입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportDetail"
                }
              }
            }
          },
          "409": {
            "description": "보고서가 이미 확정되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "summary": "보고서 삭제",
        "description": "규제 보고서를 영구적으로 삭제합니다. 보고서, 복사된 설명 및 사유, 거래 링크, 생성된 goAML XML 및 PDF가 해당 파일의 저장된 모든 버전을 포함하여 완전히 삭제됩니다. 보고서는 목록에서 사라지며 다운로드 URL도 작동을 멈춥니다. 케이스, 거래, 인물, 기업을 포함한 다른 레코드는 삭제되지 않습니다. 실행 취소는 불가능합니다.\n\n임시 저장 또는 검증된 보고서는 요청 본문 없이 삭제할 수 있습니다. 최종 확정된 보고서를 삭제하려면 요청 본문에 `confirm_delete: true`가 필요합니다. 보고서가 없으면 요청은 `404`를 반환하며, 최종 확정된 보고서 요청이 확인 없이 전송되면 `400`을 반환하고 아무것도 삭제되지 않습니다.",
        "operationId": "delete_regulatory_report",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "report_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5ec00000-0000-4000-8000-000000000007"
            },
            "description": "보고서 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl (draft report)",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "curl",
            "label": "curl (finalized report)",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"confirm_delete\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.regulatory_reports.delete(\n    \"5ec00000-0000-4000-8000-000000000007\",\n    confirm_delete=True,\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.regulatoryReports.delete(\"5ec00000-0000-4000-8000-000000000007\", {\n  confirm_delete: true,\n});"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.RegulatoryReportsDeleteParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.regulatoryReports().delete(\"5ec00000-0000-4000-8000-000000000007\", RegulatoryReportsDeleteParams.builder()\n        .confirmDelete(true)\n        .build());"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->regulatoryReports->delete('5ec00000-0000-4000-8000-000000000007', [\n    'confirm_delete' => true,\n]);"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.regulatory_reports.delete(\n  \"5ec00000-0000-4000-8000-000000000007\",\n  confirm_delete: true\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.RegulatoryReports.DeleteAsync(\"5ec00000-0000-4000-8000-000000000007\", new RegulatoryReportsDeleteParams\n{\n    ConfirmDelete = true,\n});"
          }
        ],
        "responses": {
          "204": {
            "description": "생성된 파일을 포함하여 보고서가 삭제되었습니다."
          },
          "400": {
            "description": "`confirm_delete: true` 없이 완료된 보고서가 전송되었습니다. 아무것도 삭제되지 않았습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "confirm_delete": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "confirm_delete": [
                    "This field is required to delete a finalized report."
                  ]
                }
              }
            }
          },
          "403": {
            "description": "API 키로 보고서를 삭제할 수 없습니다. 이 엔드포인트에는 `write:cases` 권한이 필요합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에서 보고서를 찾을 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "보고서가 이미 삭제 중입니다. 요청을 다시 시도하여 파일 삭제를 완료하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "This report is being deleted. Retry deleting it to finish erasing its files.",
                  "code": "report_deletion_pending"
                }
              }
            }
          },
          "503": {
            "description": "지금은 보고서 파일을 삭제할 수 없습니다. 보고서는 그대로 유지됩니다. 요청을 다시 시도하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "The report files could not be erased. Please retry deleting the report.",
                  "code": "report_storage_unavailable"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "description": "완료된 보고서에만 필수입니다.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm_delete": {
                    "type": "boolean",
                    "description": "완료된 보고서 및 생성된 파일이 영구적으로 삭제됨을 확인하려면 true로 설정합니다."
                  }
                },
                "example": {
                  "confirm_delete": true
                }
              },
              "example": {
                "confirm_delete": true
              }
            }
          }
        }
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/regulatory-reports/{report_uuid}/validate/": {
      "post": {
        "summary": "보고서 검증",
        "description": "파일을 생성하지 않고 필수 goAML 헤더 필드(보고 기관 ID, 제출 코드, 현지 통화, 취해진 조치, 제출 날짜)와 최소 하나의 첨부된 거래 및 2자리 관할 구역에 대해 보고서를 검사합니다. 또한 결과를 보고서에 저장합니다. validation_errors 및 validated_at이 업데이트되고, 확정되지 않은 보고서의 상태는 VALIDATED(오류 없음)로 이동하거나 DRAFT(오류 있음)로 되돌아갑니다.",
        "operationId": "validate_regulatory_report",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "validate",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "report_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5ec00000-0000-4000-8000-000000000007"
            },
            "description": "보고서 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/validate/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.validate(\n    \"5ec00000-0000-4000-8000-000000000007\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.validate(\"5ec00000-0000-4000-8000-000000000007\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Validate(ctx, \"5ec00000-0000-4000-8000-000000000007\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().validate(\"5ec00000-0000-4000-8000-000000000007\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->regulatoryReports->validate('5ec00000-0000-4000-8000-000000000007');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.validate(\"5ec00000-0000-4000-8000-000000000007\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.ValidateAsync(\"5ec00000-0000-4000-8000-000000000007\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "검증 결과입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "DRAFT",
                        "VALIDATED",
                        "FINALIZED"
                      ]
                    },
                    "is_valid": {
                      "type": "boolean"
                    },
                    "errors": {
                      "type": "array",
                      "description": "유효한 경우 비어 있습니다.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "field": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/regulatory-reports/{report_uuid}/finalize/": {
      "post": {
        "summary": "보고서 확정",
        "description": "다시 검증한 다음 goAML XML 및 PDF를 렌더링하고 둘 다 S3에 업로드합니다. SAR/STR/TFR 보고서에서는 케이스의 거래 알림을 SAR 보류 중에서 SAR 제출됨으로 이동하기도 합니다.",
        "operationId": "finalize_regulatory_report",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "finalize",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "report_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5ec00000-0000-4000-8000-000000000007"
            },
            "description": "보고서 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/finalize/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.finalize(\n    \"5ec00000-0000-4000-8000-000000000007\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.finalize(\"5ec00000-0000-4000-8000-000000000007\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Finalize(ctx, \"5ec00000-0000-4000-8000-000000000007\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().finalize_(\"5ec00000-0000-4000-8000-000000000007\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->regulatoryReports->finalize('5ec00000-0000-4000-8000-000000000007');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.finalize(\"5ec00000-0000-4000-8000-000000000007\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.FinalizeAsync(\"5ec00000-0000-4000-8000-000000000007\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "보고서가 확정되었으며 xml_s3_key 및 pdf_s3_key가 설정되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportDetail"
                }
              }
            }
          },
          "400": {
            "description": "보고서 유효성 검사에 실패했습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "field": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "보고서가 완료 가능한 상태가 아닙니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/regulatory-reports/{report_uuid}/download-url/": {
      "get": {
        "summary": "보고서 다운로드 URL 가져오기",
        "description": "확정된 보고서의 goAML XML 또는 PDF에 대한 사전 서명된 URL을 생성합니다.",
        "operationId": "get_regulatory_report_download_url",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "retrieve_download_url",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "report_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5ec00000-0000-4000-8000-000000000007"
            },
            "description": "보고서 UUID입니다."
          },
          {
            "name": "file",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pdf",
                "xml"
              ],
              "default": "pdf"
            },
            "description": "다운로드할 파일입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/download-url/?file=xml' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.retrieve_download_url(\n    \"5ec00000-0000-4000-8000-000000000007\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.retrieveDownloadUrl(\"5ec00000-0000-4000-8000-000000000007\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.RetrieveDownloadURL(ctx, \"5ec00000-0000-4000-8000-000000000007\", didit.RegulatoryReportsRetrieveDownloadURLParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().retrieveDownloadUrl(\"5ec00000-0000-4000-8000-000000000007\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->regulatoryReports->retrieveDownloadUrl('5ec00000-0000-4000-8000-000000000007');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.retrieve_download_url(\"5ec00000-0000-4000-8000-000000000007\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.RetrieveDownloadUrlAsync(\"5ec00000-0000-4000-8000-000000000007\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "사전 서명된 다운로드 URL입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "download_url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "file": {
                      "type": "string",
                      "enum": [
                        "pdf",
                        "xml"
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "보고서가 아직 확정되지 않았습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/transactions/rules/": {
      "get": {
        "summary": "규칙 목록 조회",
        "description": "애플리케이션의 거래 모니터링 규칙(사용자 지정 규칙 및 설치한 라이브러리 프리셋)을 나열합니다. 소스, 카테고리, 모드, 번들 또는 자유 텍스트 검색으로 필터링할 수 있으며, `ordering`(run_count, approved_pct, reviewed_pct, declined_pct, latest_triggered_at, title, created_at, source, 각각 선택적으로 `-` 접두사 사용 가능)으로 정렬할 수 있습니다.",
        "operationId": "listTransactionRules",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "PRESET",
                "CUSTOM"
              ]
            },
            "description": "PRESET 또는 CUSTOM"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "규칙 카테고리로 필터링합니다."
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "DISABLED",
                "TEST"
              ]
            },
            "description": "ACTIVE, DISABLED 또는 TEST"
          },
          {
            "name": "bundle",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "번들별로 프리셋 필터링"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "제목 및 설명을 대소문자 구분 없이 일치 검색"
          },
          {
            "name": "ordering",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "쉼표로 구분된 정렬 필드이며, 기본값은 source,-run_count입니다."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "페이지 크기"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "페이지 오프셋"
          }
        ],
        "responses": {
          "200": {
            "description": "페이지네이션된 규칙 목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TransactionRuleDetail"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/rules/?source=CUSTOM&ordering=-run_count' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.rules.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.rules.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.Rules.ListAutoPaging(ctx, didit.TransactionsRulesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().rules().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->transactions->rules->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.rules.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.Rules.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "summary": "규칙 생성",
        "description": "CUSTOM 거래 모니터링 규칙을 생성합니다. 제목은 애플리케이션당 고유해야 합니다(중복 시 -> 400). `AWAITING_USER`를 대상으로 하는 `change_status` 작업에는 반드시 `workflow_id`가 포함되어야 합니다. ACTIVE 모드로 생성된 규칙은 새 거래에 즉시 적용됩니다. 권장되는 워크플로는 TEST 모드로 생성하여 백테스트를 수행한 다음 모드를 ACTIVE로 전환하는 것입니다. 라이브러리 규칙을 변경하려면 복사본으로 생성하세요. `metadata.based_on`(해당 라이브러리 키) 및 `metadata.based_on_rule_uuid`와 함께 라이브러리 규칙 정의를 전송하면 됩니다.",
        "operationId": "createTransactionRule",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRuleCreateRequest"
              },
              "example": {
                "title": "Structuring - inbound (custom)",
                "description": "20+ inbound EUR transfers, all under 10,000 EUR, 30 days",
                "category": "finance",
                "mode": "TEST",
                "evaluation_mode": "ALL",
                "scope": {
                  "transaction_types": [
                    "finance"
                  ],
                  "directions": [
                    "INBOUND"
                  ]
                },
                "conditions": [
                  {
                    "field": "currency",
                    "operator": "eq",
                    "value": "EUR"
                  },
                  {
                    "field": "amount",
                    "operator": "lt",
                    "value": 10000
                  }
                ],
                "aggregation": [
                  {
                    "metric": "count",
                    "operator": "gte",
                    "value": 20,
                    "window": "30d",
                    "filters": {
                      "direction": "INBOUND",
                      "transaction_type": "finance",
                      "subject_vendor_data": "__current__",
                      "currency": "EUR"
                    }
                  },
                  {
                    "metric": "max",
                    "field": "amount",
                    "operator": "lt",
                    "value": 10000,
                    "window": "30d",
                    "filters": {
                      "direction": "INBOUND",
                      "transaction_type": "finance",
                      "subject_vendor_data": "__current__",
                      "currency": "EUR"
                    }
                  }
                ],
                "actions": [
                  {
                    "type": "add_score",
                    "value": 35
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "생성된 규칙입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionRuleDetail"
                }
              }
            }
          },
          "400": {
            "description": "검증 오류 - 중복된 제목, 알 수 없는 연산자/메트릭, 잘못된 형식의 윈도우, 유효하지 않은 범위 방향, 또는 workflow_id가 없는 AWAITING_USER.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "title": [
                    "A rule with this name already exists."
                  ]
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/transactions/rules/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"title\": \"Structuring - inbound (custom)\", \"description\": \"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\", \"category\": \"finance\", \"mode\": \"TEST\", \"evaluation_mode\": \"ALL\", \"scope\": {\"transaction_types\": [\"finance\"], \"directions\": [\"INBOUND\"]}, \"conditions\": [{\"field\": \"currency\", \"operator\": \"eq\", \"value\": \"EUR\"}, {\"field\": \"amount\", \"operator\": \"lt\", \"value\": 10000}], \"aggregation\": [{\"metric\": \"count\", \"operator\": \"gte\", \"value\": 20, \"window\": \"30d\", \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}}, {\"metric\": \"max\", \"field\": \"amount\", \"operator\": \"lt\", \"value\": 10000, \"window\": \"30d\", \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}}], \"actions\": [{\"type\": \"add_score\", \"value\": 35}]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.create(\n    title=\"Structuring - inbound (custom)\",\n    description=\"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n    category=\"finance\",\n    mode=\"TEST\",\n    evaluation_mode=\"ALL\",\n    scope={\n        \"transaction_types\": [\"finance\"],\n        \"directions\": [\"INBOUND\"],\n    },\n    conditions=[{\n        \"field\": \"currency\",\n        \"operator\": \"eq\",\n        \"value\": \"EUR\",\n    }, {\n        \"field\": \"amount\",\n        \"operator\": \"lt\",\n        \"value\": 10000,\n    }],\n    aggregation=[{\n        \"metric\": \"count\",\n        \"operator\": \"gte\",\n        \"value\": 20.0,\n        \"window\": \"30d\",\n        \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"},\n    }, {\n        \"metric\": \"max\",\n        \"field\": \"amount\",\n        \"operator\": \"lt\",\n        \"value\": 10000.0,\n        \"window\": \"30d\",\n        \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"},\n    }],\n    actions=[{\n        \"type\": \"add_score\",\n        \"value\": 35,\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.create({\n  title: \"Structuring - inbound (custom)\",\n  description: \"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n  category: \"finance\",\n  mode: \"TEST\",\n  evaluation_mode: \"ALL\",\n  scope: {\n    transaction_types: [\"finance\"],\n    directions: [\"INBOUND\"],\n  },\n  conditions: [{\n    field: \"currency\",\n    operator: \"eq\",\n    value: \"EUR\",\n  }, {\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000,\n  }],\n  aggregation: [{\n    metric: \"count\",\n    operator: \"gte\",\n    value: 20.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }, {\n    metric: \"max\",\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }],\n  actions: [{\n    type: \"add_score\",\n    value: 35,\n  }],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.Create(ctx, didit.TransactionRuleCreateRequest{\n\tTitle:          \"Structuring - inbound (custom)\",\n\tDescription:    didit.String(\"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\"),\n\tCategory:       \"finance\",\n\tMode:           \"TEST\",\n\tEvaluationMode: didit.Some(didit.TransactionRuleCreateRequestEvaluationMode(\"ALL\")),\n\tScope: didit.Some(didit.TransactionRuleScopeParam{\n\t\tTransactionTypes: didit.Some([]string{\"finance\"}),\n\t\tDirections:       didit.Some([]didit.TransactionRuleScopeDirections{\"INBOUND\"}),\n\t}),\n\tConditions: didit.Some([]didit.TransactionRuleConditionParam{{\n\t\tField:    \"currency\",\n\t\tOperator: \"eq\",\n\t\tValue:    didit.Some[any](\"EUR\"),\n\t}, {\n\t\tField:    \"amount\",\n\t\tOperator: \"lt\",\n\t\tValue:    didit.Some[any](10000),\n\t}}),\n\tAggregation: didit.Some([]didit.TransactionRuleAggregationParam{{\n\t\tMetric:   didit.Some(didit.TransactionRuleAggregationMetric(\"count\")),\n\t\tOperator: didit.Some(didit.TransactionRuleAggregationOperator(\"gte\")),\n\t\tValue:    20.0,\n\t\tWindow:   didit.String(\"30d\"),\n\t\tFilters:  didit.Some(map[string]any{\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}),\n\t}, {\n\t\tMetric:   didit.Some(didit.TransactionRuleAggregationMetric(\"max\")),\n\t\tField:    didit.String(\"amount\"),\n\t\tOperator: didit.Some(didit.TransactionRuleAggregationOperator(\"lt\")),\n\t\tValue:    10000.0,\n\t\tWindow:   didit.String(\"30d\"),\n\t\tFilters:  didit.Some(map[string]any{\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}),\n\t}}),\n\tActions: didit.Some([]didit.TransactionRuleActionParam{{\n\t\tType:  \"add_score\",\n\t\tValue: didit.Some[any](35),\n\t}}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.TransactionRuleAction;\nimport me.didit.types.TransactionRuleActionAddScore;\nimport me.didit.types.TransactionRuleAggregation;\nimport me.didit.types.TransactionRuleCondition;\nimport me.didit.types.TransactionRuleCreateRequest;\nimport me.didit.types.TransactionRuleScope;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().create(TransactionRuleCreateRequest.builder()\n        .title(\"Structuring - inbound (custom)\")\n        .description(\"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\")\n        .category(\"finance\")\n        .mode(TransactionRuleCreateRequest.Mode.of(\"TEST\"))\n        .evaluationMode(TransactionRuleCreateRequest.EvaluationMode.of(\"ALL\"))\n        .scope(TransactionRuleScope.builder()\n                .transactionTypes(List.of(\"finance\"))\n                .directions(List.of(TransactionRuleScope.Directions.of(\"INBOUND\")))\n                .build())\n        .conditions(List.of(\n                TransactionRuleCondition.builder()\n                        .field(\"currency\")\n                        .operator(TransactionRuleCondition.Operator.of(\"eq\"))\n                        .value(\"EUR\")\n                        .build(),\n                TransactionRuleCondition.builder()\n                        .field(\"amount\")\n                        .operator(TransactionRuleCondition.Operator.of(\"lt\"))\n                        .value(10000)\n                        .build()))\n        .aggregation(List.of(\n                TransactionRuleAggregation.builder()\n                        .metric(TransactionRuleAggregation.Metric.of(\"count\"))\n                        .operator(TransactionRuleAggregation.Operator.of(\"gte\"))\n                        .value(20.0)\n                        .window(\"30d\")\n                        .filters(Map.of(\"direction\", \"INBOUND\", \"transaction_type\", \"finance\", \"subject_vendor_data\", \"__current__\", \"currency\", \"EUR\"))\n                        .build(),\n                TransactionRuleAggregation.builder()\n                        .metric(TransactionRuleAggregation.Metric.of(\"max\"))\n                        .field(\"amount\")\n                        .operator(TransactionRuleAggregation.Operator.of(\"lt\"))\n                        .value(10000.0)\n                        .window(\"30d\")\n                        .filters(Map.of(\"direction\", \"INBOUND\", \"transaction_type\", \"finance\", \"subject_vendor_data\", \"__current__\", \"currency\", \"EUR\"))\n                        .build()))\n        .actions(List.of(TransactionRuleAction.ofAddScore(TransactionRuleActionAddScore.builder()\n                .type(TransactionRuleActionAddScore.Type.of(\"add_score\"))\n                .value(35L)\n                .build())))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->rules->create([\n    'title' => 'Structuring - inbound (custom)',\n    'description' => '20+ inbound EUR transfers, all under 10,000 EUR, 30 days',\n    'category' => 'finance',\n    'mode' => 'TEST',\n    'evaluation_mode' => 'ALL',\n    'scope' => [\n        'transaction_types' => ['finance'],\n        'directions' => ['INBOUND'],\n    ],\n    'conditions' => [[\n        'field' => 'currency',\n        'operator' => 'eq',\n        'value' => 'EUR',\n    ], [\n        'field' => 'amount',\n        'operator' => 'lt',\n        'value' => 10000,\n    ]],\n    'aggregation' => [[\n        'metric' => 'count',\n        'operator' => 'gte',\n        'value' => 20.0,\n        'window' => '30d',\n        'filters' => ['direction' => 'INBOUND', 'transaction_type' => 'finance', 'subject_vendor_data' => '__current__', 'currency' => 'EUR'],\n    ], [\n        'metric' => 'max',\n        'field' => 'amount',\n        'operator' => 'lt',\n        'value' => 10000.0,\n        'window' => '30d',\n        'filters' => ['direction' => 'INBOUND', 'transaction_type' => 'finance', 'subject_vendor_data' => '__current__', 'currency' => 'EUR'],\n    ]],\n    'actions' => [[\n        'type' => 'add_score',\n        'value' => 35,\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.create(\n  title: \"Structuring - inbound (custom)\",\n  description: \"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n  category: \"finance\",\n  mode: \"TEST\",\n  evaluation_mode: \"ALL\",\n  scope: {\n    transaction_types: [\"finance\"],\n    directions: [\"INBOUND\"],\n  },\n  conditions: [{\n    field: \"currency\",\n    operator: \"eq\",\n    value: \"EUR\",\n  }, {\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000,\n  }],\n  aggregation: [{\n    metric: \"count\",\n    operator: \"gte\",\n    value: 20.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }, {\n    metric: \"max\",\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }],\n  actions: [{\n    type: \"add_score\",\n    value: 35,\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.CreateAsync(new TransactionRuleCreateRequest\n{\n    Title = \"Structuring - inbound (custom)\",\n    Description = \"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n    Category = \"finance\",\n    Mode = \"TEST\",\n    EvaluationMode = new TransactionRuleCreateRequestEvaluationMode(\"ALL\"),\n    Scope = new TransactionRuleScope\n    {\n        TransactionTypes = new string[] { \"finance\" },\n        Directions = new TransactionRuleScopeDirections[] { \"INBOUND\" },\n    },\n    Conditions = new TransactionRuleCondition[]\n    {\n        new()\n        {\n            Field = \"currency\",\n            Operator = \"eq\",\n            Value = \"EUR\",\n        },\n        new()\n        {\n            Field = \"amount\",\n            Operator = \"lt\",\n            Value = 10000,\n        },\n    },\n    Aggregation = new TransactionRuleAggregation[]\n    {\n        new()\n        {\n            Metric = new TransactionRuleAggregationMetric(\"count\"),\n            Operator = new TransactionRuleAggregationOperator(\"gte\"),\n            Value = 20.0,\n            Window = \"30d\",\n            Filters = new Dictionary<string, object> { [\"direction\"] = \"INBOUND\", [\"transaction_type\"] = \"finance\", [\"subject_vendor_data\"] = \"__current__\", [\"currency\"] = \"EUR\" },\n        },\n        new()\n        {\n            Metric = new TransactionRuleAggregationMetric(\"max\"),\n            Field = \"amount\",\n            Operator = new TransactionRuleAggregationOperator(\"lt\"),\n            Value = 10000.0,\n            Window = \"30d\",\n            Filters = new Dictionary<string, object> { [\"direction\"] = \"INBOUND\", [\"transaction_type\"] = \"finance\", [\"subject_vendor_data\"] = \"__current__\", [\"currency\"] = \"EUR\" },\n        },\n    },\n    Actions = new TransactionRuleAction[]\n    {\n        new()\n        {\n            Type = new TransactionRuleActionType(\"add_score\"),\n            Value = 35,\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/transactions/rules/{rule_uuid}/": {
      "parameters": [
        {
          "name": "rule_uuid",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          },
          "description": "목록 조회 또는 생성 시 반환된 규칙의 uuid입니다."
        }
      ],
      "get": {
        "summary": "규칙 가져오기",
        "description": "전체 구성 및 실행 카운터가 포함된 단일 규칙을 조회합니다.",
        "operationId": "getTransactionRule",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "규칙입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionRuleDetail"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에 해당 규칙이 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/rules/RULE_UUID/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->rules->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "patch": {
        "summary": "규칙 업데이트",
        "description": "규칙을 부분 업데이트합니다. 커스텀 규칙은 모든 구성 필드를 허용합니다. 라이브러리(PRESET) 규칙은 `mode`만 허용합니다. 프리셋을 활성화, 비활성화하거나 TEST로 전환하는 데 사용하세요. Didit이 라이브러리 규칙을 유지 관리하고 업데이트를 자동으로 적용하므로 다른 필드를 전달하면 400이 반환됩니다. 라이브러리 규칙의 조건을 변경하려면 라이브러리 규칙의 정의와 `metadata.based_on`(라이브러리 키) 및 `metadata.based_on_rule_uuid`를 사용하여 `POST /v3/transactions/rules/`로 커스텀 사본을 생성한 다음, 거래에서 중복 알림이 발생하지 않도록 라이브러리 규칙을 `mode: DISABLED`로 끕니다. 보류된 라이브러리 규칙의 설치된 사본은 비활성화됩니다. `mode`를 `DISABLED` 이외의 값으로 설정하면 400(\"This library rule cannot run yet: its conditions read data the rules engine cannot evaluate.\")으로 응답합니다.",
        "operationId": "updateTransactionRule",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRuleUpdateRequest"
              },
              "example": {
                "mode": "ACTIVE"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "업데이트된 규칙입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionRuleDetail"
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류, 라이브러리 규칙의 비모드 필드, 또는 보류된 라이브러리 규칙에서 DISABLED가 아닌 모드입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/transactions/rules/RULE_UUID/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"mode\": \"ACTIVE\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    mode=\"ACTIVE\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.update(\"11111111-2222-3333-4444-555555555555\", {\n  mode: \"ACTIVE\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TransactionRuleUpdateRequest{\n\tMode: didit.Some(didit.TransactionRuleUpdateRequestMode(\"ACTIVE\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TransactionRuleUpdateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().update(\"11111111-2222-3333-4444-555555555555\", TransactionRuleUpdateRequest.builder()\n        .mode(TransactionRuleUpdateRequest.Mode.of(\"ACTIVE\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->rules->update('11111111-2222-3333-4444-555555555555', [\n    'mode' => 'ACTIVE',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  mode: \"ACTIVE\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new TransactionRuleUpdateRequest\n{\n    Mode = new TransactionRuleUpdateRequestMode(\"ACTIVE\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "summary": "규칙 삭제",
        "description": "CUSTOM 규칙을 삭제합니다. 삭제는 즉시 영구적으로 적용됩니다. 규칙은 새 거래에 대한 평가를 중단하고 목록에서 사라지지만, 이미 평가된 거래에 대한 과거 규칙 실행 결과는 그대로 유지됩니다. 라이브러리 규칙은 삭제할 수 없습니다. 대신 설치 endpoint를 통해 설치를 해제하세요(라이브러리에서 언제든지 다시 설치할 수 있습니다).",
        "operationId": "deleteTransactionRule",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "삭제되었습니다."
          },
          "400": {
            "description": "이 규칙은 라이브러리 프리셋입니다. 대신 제거하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "detail": "Library rules cannot be deleted. Uninstall them via the rules install endpoint instead."
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에 해당 규칙이 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/transactions/rules/RULE_UUID/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.transactions.rules.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.transactions.rules.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Transactions.Rules.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.transactions().rules().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->transactions->rules->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.rules.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Transactions.Rules.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ]
      }
    },
    "/v3/transactions/rules/backtest/": {
      "post": {
        "summary": "백테스트 규칙 구성",
        "description": "규칙을 생성하거나 트랜잭션을 변경하지 않고 최근 거래(가장 최근 거래부터 역테스트 한도까지)를 대상으로 가상의 규칙 구성을 평가합니다. 규칙을 활성화하기 전에 얼마나 자주 일치했을지, 얼마나 많은 대상에게 영향을 미쳤을지 확인하는 용도로 사용하십시오.",
        "operationId": "backtestTransactionRules",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "backtest",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRuleBacktestRequest"
              },
              "example": {
                "conditions": [
                  {
                    "field": "currency",
                    "operator": "eq",
                    "value": "EUR"
                  },
                  {
                    "field": "amount",
                    "operator": "lt",
                    "value": 10000
                  }
                ],
                "aggregation": [
                  {
                    "metric": "count",
                    "operator": "gte",
                    "value": 20,
                    "window": "30d",
                    "filters": {
                      "direction": "INBOUND",
                      "transaction_type": "finance",
                      "subject_vendor_data": "__current__",
                      "currency": "EUR"
                    }
                  },
                  {
                    "metric": "max",
                    "field": "amount",
                    "operator": "lt",
                    "value": 10000,
                    "window": "30d",
                    "filters": {
                      "direction": "INBOUND",
                      "transaction_type": "finance",
                      "subject_vendor_data": "__current__",
                      "currency": "EUR"
                    }
                  }
                ],
                "evaluation_mode": "ALL",
                "scope": {
                  "transaction_types": [
                    "finance"
                  ],
                  "directions": [
                    "INBOUND"
                  ]
                },
                "period_days": 90
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "백테스트 통계입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionRuleBacktestResult"
                },
                "example": {
                  "evaluated": 4820,
                  "matched": 12,
                  "affected_entities": 4,
                  "period_days": 90
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/transactions/rules/backtest/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"conditions\": [{\"field\": \"currency\", \"operator\": \"eq\", \"value\": \"EUR\"}, {\"field\": \"amount\", \"operator\": \"lt\", \"value\": 10000}], \"aggregation\": [{\"metric\": \"count\", \"operator\": \"gte\", \"value\": 20, \"window\": \"30d\", \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}}, {\"metric\": \"max\", \"field\": \"amount\", \"operator\": \"lt\", \"value\": 10000, \"window\": \"30d\", \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}}], \"evaluation_mode\": \"ALL\", \"scope\": {\"transaction_types\": [\"finance\"], \"directions\": [\"INBOUND\"]}, \"period_days\": 90}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.backtest(\n    conditions=[{\n        \"field\": \"currency\",\n        \"operator\": \"eq\",\n        \"value\": \"EUR\",\n    }, {\n        \"field\": \"amount\",\n        \"operator\": \"lt\",\n        \"value\": 10000,\n    }],\n    aggregation=[{\n        \"metric\": \"count\",\n        \"operator\": \"gte\",\n        \"value\": 20.0,\n        \"window\": \"30d\",\n        \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"},\n    }, {\n        \"metric\": \"max\",\n        \"field\": \"amount\",\n        \"operator\": \"lt\",\n        \"value\": 10000.0,\n        \"window\": \"30d\",\n        \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"},\n    }],\n    evaluation_mode=\"ALL\",\n    scope={\n        \"transaction_types\": [\"finance\"],\n        \"directions\": [\"INBOUND\"],\n    },\n    period_days=90,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.backtest({\n  conditions: [{\n    field: \"currency\",\n    operator: \"eq\",\n    value: \"EUR\",\n  }, {\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000,\n  }],\n  aggregation: [{\n    metric: \"count\",\n    operator: \"gte\",\n    value: 20.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }, {\n    metric: \"max\",\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }],\n  evaluation_mode: \"ALL\",\n  scope: {\n    transaction_types: [\"finance\"],\n    directions: [\"INBOUND\"],\n  },\n  period_days: 90,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.Backtest(ctx, didit.TransactionRuleBacktestRequest{\n\tConditions: didit.Some([]didit.TransactionRuleConditionParam{{\n\t\tField:    \"currency\",\n\t\tOperator: \"eq\",\n\t\tValue:    didit.Some[any](\"EUR\"),\n\t}, {\n\t\tField:    \"amount\",\n\t\tOperator: \"lt\",\n\t\tValue:    didit.Some[any](10000),\n\t}}),\n\tAggregation: didit.Some([]didit.TransactionRuleAggregationParam{{\n\t\tMetric:   didit.Some(didit.TransactionRuleAggregationMetric(\"count\")),\n\t\tOperator: didit.Some(didit.TransactionRuleAggregationOperator(\"gte\")),\n\t\tValue:    20.0,\n\t\tWindow:   didit.String(\"30d\"),\n\t\tFilters:  didit.Some(map[string]any{\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}),\n\t}, {\n\t\tMetric:   didit.Some(didit.TransactionRuleAggregationMetric(\"max\")),\n\t\tField:    didit.String(\"amount\"),\n\t\tOperator: didit.Some(didit.TransactionRuleAggregationOperator(\"lt\")),\n\t\tValue:    10000.0,\n\t\tWindow:   didit.String(\"30d\"),\n\t\tFilters:  didit.Some(map[string]any{\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}),\n\t}}),\n\tEvaluationMode: didit.Some(didit.TransactionRuleBacktestRequestEvaluationMode(\"ALL\")),\n\tScope: didit.Some(didit.TransactionRuleScopeParam{\n\t\tTransactionTypes: didit.Some([]string{\"finance\"}),\n\t\tDirections:       didit.Some([]didit.TransactionRuleScopeDirections{\"INBOUND\"}),\n\t}),\n\tPeriodDays: didit.Int(90),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.TransactionRuleAggregation;\nimport me.didit.types.TransactionRuleBacktestRequest;\nimport me.didit.types.TransactionRuleCondition;\nimport me.didit.types.TransactionRuleScope;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().backtest(TransactionRuleBacktestRequest.builder()\n        .conditions(List.of(\n                TransactionRuleCondition.builder()\n                        .field(\"currency\")\n                        .operator(TransactionRuleCondition.Operator.of(\"eq\"))\n                        .value(\"EUR\")\n                        .build(),\n                TransactionRuleCondition.builder()\n                        .field(\"amount\")\n                        .operator(TransactionRuleCondition.Operator.of(\"lt\"))\n                        .value(10000)\n                        .build()))\n        .aggregation(List.of(\n                TransactionRuleAggregation.builder()\n                        .metric(TransactionRuleAggregation.Metric.of(\"count\"))\n                        .operator(TransactionRuleAggregation.Operator.of(\"gte\"))\n                        .value(20.0)\n                        .window(\"30d\")\n                        .filters(Map.of(\"direction\", \"INBOUND\", \"transaction_type\", \"finance\", \"subject_vendor_data\", \"__current__\", \"currency\", \"EUR\"))\n                        .build(),\n                TransactionRuleAggregation.builder()\n                        .metric(TransactionRuleAggregation.Metric.of(\"max\"))\n                        .field(\"amount\")\n                        .operator(TransactionRuleAggregation.Operator.of(\"lt\"))\n                        .value(10000.0)\n                        .window(\"30d\")\n                        .filters(Map.of(\"direction\", \"INBOUND\", \"transaction_type\", \"finance\", \"subject_vendor_data\", \"__current__\", \"currency\", \"EUR\"))\n                        .build()))\n        .evaluationMode(TransactionRuleBacktestRequest.EvaluationMode.of(\"ALL\"))\n        .scope(TransactionRuleScope.builder()\n                .transactionTypes(List.of(\"finance\"))\n                .directions(List.of(TransactionRuleScope.Directions.of(\"INBOUND\")))\n                .build())\n        .periodDays(90L)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->rules->backtest([\n    'conditions' => [[\n        'field' => 'currency',\n        'operator' => 'eq',\n        'value' => 'EUR',\n    ], [\n        'field' => 'amount',\n        'operator' => 'lt',\n        'value' => 10000,\n    ]],\n    'aggregation' => [[\n        'metric' => 'count',\n        'operator' => 'gte',\n        'value' => 20.0,\n        'window' => '30d',\n        'filters' => ['direction' => 'INBOUND', 'transaction_type' => 'finance', 'subject_vendor_data' => '__current__', 'currency' => 'EUR'],\n    ], [\n        'metric' => 'max',\n        'field' => 'amount',\n        'operator' => 'lt',\n        'value' => 10000.0,\n        'window' => '30d',\n        'filters' => ['direction' => 'INBOUND', 'transaction_type' => 'finance', 'subject_vendor_data' => '__current__', 'currency' => 'EUR'],\n    ]],\n    'evaluation_mode' => 'ALL',\n    'scope' => [\n        'transaction_types' => ['finance'],\n        'directions' => ['INBOUND'],\n    ],\n    'period_days' => 90,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.backtest(\n  conditions: [{\n    field: \"currency\",\n    operator: \"eq\",\n    value: \"EUR\",\n  }, {\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000,\n  }],\n  aggregation: [{\n    metric: \"count\",\n    operator: \"gte\",\n    value: 20.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }, {\n    metric: \"max\",\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }],\n  evaluation_mode: \"ALL\",\n  scope: {\n    transaction_types: [\"finance\"],\n    directions: [\"INBOUND\"],\n  },\n  period_days: 90\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.BacktestAsync(new TransactionRuleBacktestRequest\n{\n    Conditions = new TransactionRuleCondition[]\n    {\n        new()\n        {\n            Field = \"currency\",\n            Operator = \"eq\",\n            Value = \"EUR\",\n        },\n        new()\n        {\n            Field = \"amount\",\n            Operator = \"lt\",\n            Value = 10000,\n        },\n    },\n    Aggregation = new TransactionRuleAggregation[]\n    {\n        new()\n        {\n            Metric = new TransactionRuleAggregationMetric(\"count\"),\n            Operator = new TransactionRuleAggregationOperator(\"gte\"),\n            Value = 20.0,\n            Window = \"30d\",\n            Filters = new Dictionary<string, object> { [\"direction\"] = \"INBOUND\", [\"transaction_type\"] = \"finance\", [\"subject_vendor_data\"] = \"__current__\", [\"currency\"] = \"EUR\" },\n        },\n        new()\n        {\n            Metric = new TransactionRuleAggregationMetric(\"max\"),\n            Field = \"amount\",\n            Operator = new TransactionRuleAggregationOperator(\"lt\"),\n            Value = 10000.0,\n            Window = \"30d\",\n            Filters = new Dictionary<string, object> { [\"direction\"] = \"INBOUND\", [\"transaction_type\"] = \"finance\", [\"subject_vendor_data\"] = \"__current__\", [\"currency\"] = \"EUR\" },\n        },\n    },\n    EvaluationMode = new TransactionRuleBacktestRequestEvaluationMode(\"ALL\"),\n    Scope = new TransactionRuleScope\n    {\n        TransactionTypes = new string[] { \"finance\" },\n        Directions = new TransactionRuleScopeDirections[] { \"INBOUND\" },\n    },\n    PeriodDays = 90,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/transactions/rules/library/": {
      "get": {
        "summary": "규칙 라이브러리 목록 조회",
        "description": "각 항목의 전체 구성 및 이 애플리케이션에 대한 `is_installed` 플래그와 함께 전체 사전 설정 규칙 라이브러리(150+ 규칙)를 탐색합니다. 번들, 카테고리 또는 자유 텍스트 검색으로 필터링할 수 있습니다. 규칙 엔진이 아직 평가할 수 없는 데이터를 조건에서 읽는 라이브러리 규칙은 실행할 수 있을 때까지 보류됩니다. 보류된 규칙은 목록에 표시되지 않습니다.",
        "operationId": "listTransactionRuleLibrary",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "list_library",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "bundle",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "번들로 필터링합니다(예: finance, aml_ctf, crypto_monitoring, travel_rule)."
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "카테고리로 필터링합니다."
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "제목 및 설명을 대소문자 구분 없이 일치 검색"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "페이지 크기"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "페이지 오프셋"
          }
        ],
        "responses": {
          "200": {
            "description": "페이지 단위로 제공되는 라이브러리 항목 목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TransactionRuleLibraryEntry"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/rules/library/?bundle=finance' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.rules.list_library():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.rules.listLibrary()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.Rules.ListLibraryAutoPaging(ctx, didit.TransactionsRulesListLibraryParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().rules().listLibrary()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->transactions->rules->listLibrary() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.rules.list_library.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.Rules.ListLibraryAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/transactions/rules/install/": {
      "post": {
        "summary": "라이브러리 규칙 설치",
        "description": "`library_keys` 또는 전체 `bundle`을 통해 하나 이상의 프리셋을 애플리케이션에 설치합니다. 설치된 프리셋은 거래 모니터링이 켜져 있는 동안 즉시 활성화되며, 그렇지 않은 경우 비활성화됩니다. 이미 설치된 키는 건너뜁니다. 규칙 엔진이 아직 평가할 수 없는 데이터를 조건에서 읽는 라이브러리 규칙은 실행할 수 있을 때까지 보류됩니다. `library_keys`에 해당 규칙을 지정한 요청은 400을 반환하고 아무것도 설치하지 않으며(\"These library rules cannot run yet: their conditions read data the rules engine cannot evaluate.\"에 이어 키 목록 표시), `bundle` 설치에서는 이를 건너뜁니다. 보류된 규칙은 조건을 평가할 수 있게 되면 자동으로 다시 활성화됩니다. 라이브러리에 없는 `library_keys` 항목은 거부되지 않고 건너뜁니다.",
        "operationId": "installTransactionRuleLibrary",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "install_library",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRuleInstallRequest"
              },
              "example": {
                "library_keys": [
                  "structuring-inbound",
                  "structuring-outbound"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "설치된 항목입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionRuleInstallResult"
                },
                "example": {
                  "installed_library_keys": [
                    "structuring-inbound",
                    "structuring-outbound"
                  ],
                  "installed_count": 2
                }
              }
            }
          },
          "400": {
            "description": "library_keys와 bundle이 모두 제공되지 않았거나, `library_keys`가 목록이 아니거나, `library_keys` 항목이 보류되었습니다. 알 수 없는 항목은 건너뛰고 해당 항목 없이 200으로 응답합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/transactions/rules/install/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"library_keys\": [\"structuring-inbound\", \"structuring-outbound\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.install_library(\n    library_keys=[\"structuring-inbound\", \"structuring-outbound\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.installLibrary({\n  library_keys: [\"structuring-inbound\", \"structuring-outbound\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.InstallLibrary(ctx, didit.TransactionRuleInstallRequest{\n\tLibraryKeys: didit.Some([]string{\"structuring-inbound\", \"structuring-outbound\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.TransactionRuleInstallRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().installLibrary(TransactionRuleInstallRequest.builder()\n        .libraryKeys(List.of(\"structuring-inbound\", \"structuring-outbound\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->rules->installLibrary([\n    'library_keys' => ['structuring-inbound', 'structuring-outbound'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.install_library(library_keys: [\"structuring-inbound\", \"structuring-outbound\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.InstallLibraryAsync(new TransactionRuleInstallRequest\n{\n    LibraryKeys = new string[] { \"structuring-inbound\", \"structuring-outbound\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "summary": "라이브러리 규칙 제거",
        "description": "`library_keys` 또는 전체 `bundle`을 지정하여 애플리케이션에서 설치된 프리셋을 제거합니다. 제거된 프리셋은 즉시 평가가 중단되며, 언제든지 라이브러리에서 다시 설치할 수 있습니다.",
        "operationId": "uninstallTransactionRuleLibrary",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "uninstall_library",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRuleInstallRequest"
              },
              "example": {
                "bundle": "responsible_gaming"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "제거된 프리셋 수입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionRuleInstallResult"
                },
                "example": {
                  "uninstalled_count": 5
                }
              }
            }
          },
          "400": {
            "description": "library_keys와 bundle이 모두 제공되지 않았습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/transactions/rules/install/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"bundle\": \"responsible_gaming\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.uninstall_library(\n    bundle=\"responsible_gaming\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.uninstallLibrary({\n  bundle: \"responsible_gaming\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.UninstallLibrary(ctx, didit.TransactionRuleInstallRequest{\n\tBundle: didit.String(\"responsible_gaming\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TransactionRuleInstallRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().uninstallLibrary(TransactionRuleInstallRequest.builder()\n        .bundle(\"responsible_gaming\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->rules->uninstallLibrary([\n    'bundle' => 'responsible_gaming',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.uninstall_library(bundle: \"responsible_gaming\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.UninstallLibraryAsync(new TransactionRuleInstallRequest\n{\n    Bundle = \"responsible_gaming\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/": {
      "get": {
        "summary": "네트워크 목록 조회",
        "description": "이 애플리케이션의 조직 내에서 감지된 사기 네트워크를 기본적으로 위험 수준이 가장 높은 순서대로 나열합니다. 기본적으로 기각된 네트워크는 제외되며, 이를 포함하려면 status를 전달합니다. 샌드박스 데이터는 클러스터링에서 완전히 제외되므로 샌드박스 애플리케이션에는 네트워크가 존재하지 않습니다. 모든 응답에는 조직의 `sharing_mode`와 조직 간 신호의 적용 여부(`cross_org_available`, `cross_org_unavailable_reason`)가 포함됩니다. `kpis`는 필터와 일치하는 네트워크를 집계하고 `counts`는 애플리케이션이 조회할 수 있는 모든 네트워크를 집계합니다. 페이지만 필요한 경우 둘 다 건너뛰려면 `summary=false`를 전달합니다. 전체 액세스 권한 API 키가 필요하거나, 콘솔 멤버의 경우 `list:networks` 권한이 필요합니다.",
        "operationId": "list_networks",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "포함할 쉼표로 구분된 상태: active,in_review,resolved,dismissed. dismissed를 제외하려면 이 파라미터를 생략하십시오."
          },
          {
            "name": "scope",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "identity",
                "transactions"
              ]
            },
            "description": "`transactions`는 멤버가 모두 거래 당사자인 네트워크를 유지하고, `identity`는 그 외의 모든 네트워크를 유지합니다. 둘 다 유지하려면 생략하십시오. 이는 `counts.views` 및 `counts.facets`의 범위도 좁힙니다. 다른 값은 400을 반환합니다."
          },
          {
            "name": "signal_type",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "쉼표로 구분된 시그널 유형: ip_address,device,face,document_number,phone,email,address."
          },
          {
            "name": "pattern_type",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "쉼표로 구분된 패턴 유형입니다(예: exact_same_device,same_email)."
          },
          {
            "name": "risk_band",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "쉼표로 구분된 구간: low,medium,high."
          },
          {
            "name": "min_size",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "최소 멤버 수입니다."
          },
          {
            "name": "max_size",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "최대 멤버 수."
          },
          {
            "name": "assignee",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "쉼표로 구분된 담당자: `unassigned`, 멤버 이메일(대소문자 구분 없이 일치) 또는 호출한 콘솔 멤버를 나타내는 `me`. 네트워크는 어떤 값과도 일치합니다. `me`는 콘솔 멤버 token이 필요합니다. API 키는 400 `{\"assignee\": [\"\\\"me\\\" needs a user token; an API key has no assignee identity.\"]}`을 수신합니다."
          },
          {
            "name": "priority",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "쉼표로 구분된 우선순위: `low`, `medium`, `high`, 또는 우선순위가 없는 네트워크의 경우 `none`입니다. 다른 모든 값은 400 `{\"priority\": \"Unknown priority: <values>.\"}`을 반환합니다."
          },
          {
            "name": "risk_min",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100
            },
            "description": "최소 위험 점수로, 0에서 100 사이의 정수입니다. 정수가 아닌 값은 400 `{\"risk_min\": \"Use a whole number from 0 to 100.\"}`을 반환합니다."
          },
          {
            "name": "has_case",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "`true`는 애플리케이션에서 케이스를 생성한 네트워크만 유지하고, `false`는 그 외의 네트워크를 유지합니다. 그 외의 값은 무시됩니다."
          },
          {
            "name": "date_from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "last_activity_at의 하한값(ISO 8601 날짜 또는 날짜/시간)."
          },
          {
            "name": "date_to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "first_activity_at의 상한(ISO 8601 날짜 또는 날짜/시간)입니다."
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "네트워크 이름, 멤버 이름, network_id(N-0001) 및 정확한 pattern_type 토큰에 대한 자유 형식 검색입니다."
          },
          {
            "name": "ordering",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "risk_score, -risk_score, last_activity_at, -last_activity_at, first_activity_at, -first_activity_at, network_number, -network_number 중 하나입니다. 기본값은 -risk_score,-last_activity_at입니다."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "minimum": 1,
              "maximum": 500
            },
            "description": "페이지 크기(1-500)입니다. 기본값은 100입니다."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "첫 번째 레코드의 0부터 시작하는 오프셋입니다."
          },
          {
            "name": "summary",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "`false`는 `kpis` 및 `counts` 없이 페이지와 해당 `count`만 반환합니다. 기본값은 `true`입니다. `true` 또는 `false` 이외의 값은 400을 반환합니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/?status=active,in_review&ordering=-risk_score' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.networks.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.networks.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Networks.ListAutoPaging(ctx, didit.NetworksListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.networks().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->networks->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.networks.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Networks.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "조직의 공유 모드 및 조직 간 가용성을 포함하는 페이지 단위로 제공되는 네트워크 목록이며, `summary=false`가 아닌 경우 `kpis` 및 `counts`도 함께 제공됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "integer",
                      "nullable": true,
                      "description": "다음 페이지의 오프셋이며, 마지막 페이지에서는 null입니다."
                    },
                    "previous": {
                      "type": "integer",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NetworkListItem"
                      }
                    },
                    "kpis": {
                      "type": "object",
                      "description": "각 키는 현재 필터와 일치하는 결과에 대한 {value, delta}입니다. `summary=false`인 경우 생략됩니다.",
                      "properties": {
                        "active": {
                          "type": "object"
                        },
                        "in_review": {
                          "type": "object"
                        },
                        "applicants_involved": {
                          "type": "object"
                        },
                        "detected_this_period": {
                          "type": "object"
                        },
                        "false_positive_rate": {
                          "type": "object"
                        }
                      }
                    },
                    "counts": {
                      "$ref": "#/components/schemas/NetworkListCounts"
                    },
                    "sharing_mode": {
                      "type": "string",
                      "enum": [
                        "off",
                        "private",
                        "global"
                      ],
                      "description": "조직의 조직 간 공유 모드입니다. `global`만 조직 간 네트워크를 비교하며, `private` 및 `off`는 해당 조직 자체의 이력으로만 제한합니다.",
                      "example": "global"
                    },
                    "cross_org_available": {
                      "type": "boolean",
                      "description": "조직 간 신호가 이 조직에 적용되는지 여부입니다. 엔터프라이즈 플랜과 `global` 공유 모드가 모두 필요합니다.",
                      "example": true
                    },
                    "cross_org_unavailable_reason": {
                      "type": "string",
                      "enum": [
                        "plan",
                        "sharing_mode"
                      ],
                      "nullable": true,
                      "description": "조직 간 신호가 적용되지 않는 이유(확인 순서 기준). `plan`: 공유 모드와 관계없이 조직의 요금제에 조직 간 사기 방지 네트워크가 포함되어 있지 않습니다(Enterprise 요금제 필요). `sharing_mode`: 요금제에는 포함되어 있으나 공유 모드가 `private` 또는 `off`입니다. `cross_org_available`이 `true`인 경우 null입니다.",
                      "example": null
                    }
                  },
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results",
                    "sharing_mode",
                    "cross_org_available",
                    "cross_org_unavailable_reason"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 필터, 정렬, 페이지네이션 또는 `summary` 값입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid summary": {
                    "summary": "유효하지 않은 요약",
                    "value": {
                      "summary": [
                        "Must be \"true\" or \"false\"."
                      ]
                    }
                  },
                  "Invalid scope": {
                    "summary": "유효하지 않은 범위",
                    "value": {
                      "scope": [
                        "Use identity or transactions."
                      ]
                    }
                  },
                  "Unsupported ordering": {
                    "summary": "지원되지 않는 정렬 방식",
                    "value": [
                      "Unsupported ordering."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "자격 증명이 누락되었거나 유효하지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "코드화된 오류에 표시됩니다(예: `networks_not_entitled`)."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "자격 증명이 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 다른 애플리케이션에 속해 있거나 접근 권한이 제한된 키입니다. Networks 엔드포인트에는 전체 접근 권한 키가 필요합니다. 콘솔 멤버 토큰에는 `list:networks` 권한이 필요합니다. 조직에 Networks가 활성화되어 있지 않은 경우 `code: networks_not_entitled`와 함께 반환되기도 합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "코드화된 오류에 표시됩니다(예: `networks_not_entitled`)."
                    }
                  }
                },
                "examples": {
                  "Networks not enabled": {
                    "summary": "네트워크가 활성화되지 않았습니다",
                    "value": {
                      "detail": "Networks is disabled for this organization. Contact Didit support if you believe this is an error.",
                      "code": "networks_not_entitled"
                    }
                  },
                  "Restricted API key": {
                    "summary": "제한된 API 키",
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "No permission": {
                    "summary": "권한 없음",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/": {
      "get": {
        "summary": "네트워크 조회",
        "description": "단일 네트워크의 전체 세부 정보를 조회합니다: 통계, 사기 태그 및 위험 신호, 조직의 `sharing_mode` 및 조직 간 가용성, 해당 네트워크에 대한 애플리케이션의 `tags`, 멤버 `outcomes` 및 패턴 점수(`patterns`). 전체 접근 권한이 있는 API 키가 필요하거나, 콘솔 멤버의 경우 `read:networks` 권한이 필요합니다.",
        "operationId": "get_network",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "n3a5e000-0000-4000-8000-000000000001"
            },
            "description": "네트워크 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.retrieve(\n    \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.retrieve(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.Retrieve(ctx, \"n3a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().retrieve(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->retrieve('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.retrieve(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RetrieveAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "네트워크 세부 정보입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkDetailResponse"
                },
                "example": {
                  "uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "network_id": "N-0042",
                  "name": null,
                  "status": "in_review",
                  "risk": {
                    "score": 82,
                    "band": "high",
                    "bar": 0.82
                  },
                  "pattern_types": [
                    "exact_same_device",
                    "same_email"
                  ],
                  "signal_types": [
                    "device",
                    "email"
                  ],
                  "member_counts": {
                    "total": 3,
                    "users": 3,
                    "businesses": 0,
                    "transaction_parties": 0
                  },
                  "member_status": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "not_completed": 1
                  },
                  "signal_coverage": {
                    "device": {
                      "signals": 1,
                      "subjects": 3,
                      "coverage": 1.0
                    },
                    "email": {
                      "signals": 1,
                      "subjects": 2,
                      "coverage": 0.6667
                    }
                  },
                  "first_activity_at": "2026-10-01T09:12:44Z",
                  "last_activity_at": "2026-10-12T16:03:10Z",
                  "stats": {
                    "members": {
                      "total": 3,
                      "users": 3,
                      "businesses": 0,
                      "transaction_parties": 0
                    },
                    "member_status": {
                      "approved": 1,
                      "declined": 1,
                      "in_review": 0,
                      "not_completed": 1
                    },
                    "signals": {
                      "total": 2,
                      "by_type": {
                        "device": {
                          "signals": 1,
                          "subjects": 3,
                          "coverage": 1.0
                        },
                        "email": {
                          "signals": 1,
                          "subjects": 2,
                          "coverage": 0.6667
                        }
                      }
                    }
                  },
                  "fraud_tags": [],
                  "risk_signals": {
                    "residential_proxy_reuse": {
                      "detected": false,
                      "signal_count": 0,
                      "max_subject_count": 0
                    },
                    "email_intelligence": {
                      "enriched_signal_count": 1,
                      "high_risk_count": 0,
                      "social_profile_count": 0
                    },
                    "phone_intelligence": {
                      "enriched_signal_count": 0,
                      "high_risk_count": 0
                    }
                  },
                  "reviewed_at": "2026-10-12T16:30:00Z",
                  "reviewed_by": "reviewer@example.com",
                  "review_reason": "Shared device across three new accounts.",
                  "notes_count": 0,
                  "sharing_mode": "global",
                  "cross_org_available": true,
                  "cross_org_unavailable_reason": null,
                  "tags": [
                    {
                      "uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "name": "SUSPICIOUS",
                      "color": "#6366F1",
                      "source": "custom",
                      "added_by": null,
                      "added_at": "2026-10-13T08:15:00Z"
                    }
                  ],
                  "outcomes": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "total": 3
                  },
                  "patterns": [
                    {
                      "type": "background",
                      "score": 0.8125,
                      "members": 3,
                      "reason": null,
                      "computed_at": "2026-10-13T08:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "네트워크를 찾을 수 없습니다(또는 이 애플리케이션에 표시되지 않음).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "자격 증명이 누락되었거나 유효하지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "코드화된 오류에 표시됩니다(예: `networks_not_entitled`)."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "자격 증명이 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 다른 애플리케이션에 속해 있거나 접근 권한이 제한된 키입니다. Networks 엔드포인트에는 전체 접근 권한 키가 필요합니다. 콘솔 멤버 토큰에는 `read:networks` 권한이 필요합니다. 조직에 Networks가 활성화되어 있지 않은 경우 `code: networks_not_entitled`와 함께 반환되기도 합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "코드화된 오류에 표시됩니다(예: `networks_not_entitled`)."
                    }
                  }
                },
                "examples": {
                  "Networks not enabled": {
                    "summary": "네트워크가 활성화되지 않았습니다",
                    "value": {
                      "detail": "Networks is disabled for this organization. Contact Didit support if you believe this is an error.",
                      "code": "networks_not_entitled"
                    }
                  },
                  "Restricted API key": {
                    "summary": "제한된 API 키",
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "No permission": {
                    "summary": "권한 없음",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/graph/": {
      "get": {
        "summary": "네트워크 그래프 조회",
        "description": "주체 노드(벤더 사용자, 벤더 기업, 거래 당사자)와 이들을 연결하는 신호 노드(공유된 기기/IP/얼굴/문서/전화번호/이메일/주소 값)의 그래프로 네트워크를 조회하며, 엣지는 멤버십을 나타냅니다.",
        "operationId": "get_network_graph",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "retrieve_graph",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "n3a5e000-0000-4000-8000-000000000001"
            },
            "description": "네트워크 UUID입니다."
          },
          {
            "name": "depth",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "2",
                "3",
                "all"
              ]
            },
            "description": "포함할 대상 주체로부터의 홉 수입니다. 기본값은 전체(무제한)입니다."
          },
          {
            "name": "focus_kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "vendor_user",
                "vendor_business",
                "transaction_party"
              ]
            },
            "description": "그래프의 중심이 될 주체 유형입니다. focus_id와 함께 제공해야 합니다. 깊이가 제한되어 있고 둘 다 제공되지 않은 경우 임의의 멤버로 기본 설정됩니다."
          },
          {
            "name": "focus_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "그래프의 중심이 될 주체 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/graph/?depth=2' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.retrieve_graph(\n    \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.retrieveGraph(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.RetrieveGraph(ctx, \"n3a5e000-0000-4000-8000-000000000001\", didit.NetworksRetrieveGraphParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().retrieveGraph(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->retrieveGraph('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.retrieve_graph(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RetrieveGraphAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "네트워크 그래프입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkGraph"
                }
              }
            }
          },
          "404": {
            "description": "네트워크를 찾을 수 없습니다(또는 이 애플리케이션에 표시되지 않음).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/members/": {
      "get": {
        "summary": "네트워크 멤버 목록 조회",
        "description": "이 네트워크에 속한 주체(공급업체 사용자, 공급업체 기업 또는 거래 당사자) 목록을 조회합니다.",
        "operationId": "list_network_members",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "list_members",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "n3a5e000-0000-4000-8000-000000000001"
            },
            "description": "네트워크 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/members/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.list_members(\n    \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.listMembers(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.ListMembers(ctx, \"n3a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().listMembers(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->listMembers('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.list_members(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.ListMembersAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "네트워크 멤버입니다. 페이지로 나뉘지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NetworkMember"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "네트워크를 찾을 수 없습니다(또는 이 애플리케이션에 표시되지 않음).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/signals/": {
      "get": {
        "summary": "네트워크 신호 목록 조회",
        "description": "이 네트워크의 멤버들을 연결하는 신호(공유된 기기, IP, 얼굴, 문서 번호, 전화번호, 이메일 또는 주소 값) 목록을 조회합니다.",
        "operationId": "list_network_signals",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "list_signals",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "n3a5e000-0000-4000-8000-000000000001"
            },
            "description": "네트워크 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/signals/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.list_signals(\n    \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.listSignals(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.ListSignals(ctx, \"n3a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().listSignals(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->listSignals('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.list_signals(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.ListSignalsAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "네트워크 신호입니다. 페이지로 나뉘지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NetworkSignal"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "네트워크를 찾을 수 없습니다(또는 이 애플리케이션에 표시되지 않음).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/timeline/": {
      "get": {
        "summary": "네트워크 타임라인 조회",
        "description": "`contract` 미지정 시: 네트워크 자체 이벤트(감지, 각 신호의 최신 관측 및 해당 검토)가 오래된 순서대로 페이지네이션 없이 반환됩니다. `limit`, `cursor`, `event_type`은 무시됩니다. `contract=2` 지정 시: 커서 기반 페이지네이션이 적용된 형식화된 타임라인이 최신순으로 반환됩니다. 멤버 계정이 수행한 작업(인증 시도, 거래, 이벤트 API를 통해 전송한 로그인 및 트리거된 실시간 규칙)과 네트워크에 대해 생성된 케이스가 추가됩니다. `note_added` 이벤트는 콘솔 멤버에게만 반환되며, API 키에는 절대 반환되지 않습니다. 전체 접근 권한이 있는 API 키 또는 콘솔 멤버의 `read:networks` 권한이 필요합니다.",
        "operationId": "get_network_timeline",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "retrieve_timeline",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "n3a5e000-0000-4000-8000-000000000001"
            },
            "description": "네트워크 UUID입니다."
          },
          {
            "name": "contract",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "2"
              ]
            },
            "description": "`2`는 유형이 지정된 타임라인을 반환합니다. 기본 타임라인의 경우 생략합니다. 그 외의 값은 400을 반환합니다."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "description": "유형별 타임라인 전용입니다. 페이지당 이벤트 수이며, 1에서 500 사이입니다. 기본값은 100입니다."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "유형별 타임라인 전용입니다. 이전 페이지의 `next_cursor`입니다. 유효하지 않거나 비어 있는 커서는 400을 반환합니다."
          },
          {
            "name": "event_type",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "maxItems": 20,
              "items": {
                "type": "string",
                "enum": [
                  "network_detected",
                  "signal_observed",
                  "network_active",
                  "network_in_review",
                  "network_resolved",
                  "network_dismissed",
                  "verification_attempt",
                  "transaction",
                  "login",
                  "rule_hit",
                  "case_linked",
                  "note_added"
                ]
              }
            },
            "description": "유형별 타임라인 전용입니다. 유지할 이벤트 유형으로, 반복하거나 쉼표로 구분하여 최대 20개 값까지 지정할 수 있습니다. 기본값은 모든 유형입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/timeline/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "curl",
            "label": "curl (typed timeline)",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/3fa85f64-5717-4562-b3fc-2c963f66afa6/timeline/?contract=2&limit=50&event_type=verification_attempt,login' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.retrieve_timeline(\n    \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.retrieveTimeline(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.RetrieveTimeline(ctx, \"n3a5e000-0000-4000-8000-000000000001\", didit.NetworksRetrieveTimelineParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().retrieveTimeline(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->retrieveTimeline('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.retrieve_timeline(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RetrieveTimelineAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "`contract` 미지정 시: 페이지 매김 없는 `{results}`(오래된 순)입니다. `contract=2`인 경우: `{results, next_cursor}`(최신순)입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/NetworkTimeline"
                    },
                    {
                      "$ref": "#/components/schemas/NetworkTimelinePage"
                    }
                  ]
                },
                "examples": {
                  "Default timeline": {
                    "summary": "contract 미지정",
                    "value": {
                      "results": [
                        {
                          "event_type": "network_detected",
                          "occurred_at": "2026-10-01T09:12:44Z",
                          "label": "Network detected",
                          "metadata": {
                            "network_id": "N-0042"
                          }
                        },
                        {
                          "event_type": "signal_observed",
                          "occurred_at": "2026-10-12T16:03:10Z",
                          "label": "device observed",
                          "metadata": {
                            "signal_type": "device",
                            "subject_count": 3,
                            "is_hub": false
                          }
                        },
                        {
                          "event_type": "network_in_review",
                          "occurred_at": "2026-10-12T16:30:00Z",
                          "label": "Network in_review",
                          "metadata": {
                            "reason": "Shared device across three new accounts."
                          }
                        }
                      ]
                    }
                  },
                  "Typed timeline": {
                    "summary": "contract=2인 경우",
                    "value": {
                      "results": [
                        {
                          "id": "monitoring_event:9b2f1c3e-4d5a-4b6c-8d7e-0f1a2b3c4d5e",
                          "event_type": "login",
                          "occurred_at": "2026-10-12T18:41:02Z",
                          "ingested_at": "2026-10-12T18:41:03Z",
                          "label": "Login",
                          "metadata": {},
                          "account": {
                            "node_id": "vendor_user:5f6e7d8c-9b0a-4c1d-8e2f-3a4b5c6d7e8f",
                            "node_type": "account",
                            "uuid": "5f6e7d8c-9b0a-4c1d-8e2f-3a4b5c6d7e8f",
                            "vendor_data": "user-1042",
                            "display_name": "Alex Example",
                            "ownership": "owned",
                            "route": {
                              "kind": "user",
                              "id": "5f6e7d8c-9b0a-4c1d-8e2f-3a4b5c6d7e8f",
                              "application_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
                            }
                          },
                          "source_ref": {
                            "kind": "monitoring_event",
                            "id": "9b2f1c3e-4d5a-4b6c-8d7e-0f1a2b3c4d5e",
                            "ownership": "owned"
                          },
                          "verification_attempt": null,
                          "transaction": null,
                          "login": {
                            "action": "auth.login",
                            "succeeded": true,
                            "status": "APPROVED",
                            "ip": {
                              "address": "203.0.113.24",
                              "country_code": "ES",
                              "city": "Madrid",
                              "connection_type": null,
                              "is_vpn_or_tor": false,
                              "is_data_center": false
                            },
                            "device": {
                              "fingerprint": "fp_0a1b2c3d",
                              "label": "Chrome · Android"
                            },
                            "is_first_login": false,
                            "is_new_device": true
                          },
                          "rule_hit": null,
                          "case_linked": null,
                          "note_added": null
                        },
                        {
                          "id": "session:1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                          "event_type": "verification_attempt",
                          "occurred_at": "2026-10-12T16:03:10Z",
                          "ingested_at": "2026-10-12T16:03:10Z",
                          "label": "Verification attempt 2 of 2",
                          "metadata": {},
                          "account": {
                            "node_id": "vendor_user:5f6e7d8c-9b0a-4c1d-8e2f-3a4b5c6d7e8f",
                            "node_type": "account",
                            "uuid": "5f6e7d8c-9b0a-4c1d-8e2f-3a4b5c6d7e8f",
                            "vendor_data": "user-1042",
                            "display_name": "Alex Example",
                            "ownership": "owned",
                            "route": {
                              "kind": "user",
                              "id": "5f6e7d8c-9b0a-4c1d-8e2f-3a4b5c6d7e8f",
                              "application_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
                            }
                          },
                          "source_ref": {
                            "kind": "session",
                            "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                            "ownership": "owned",
                            "route": {
                              "kind": "session",
                              "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                              "application_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
                            }
                          },
                          "verification_attempt": {
                            "session_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                            "session_number": 1287,
                            "attempt": 2,
                            "attempt_count": 2,
                            "status": "Approved",
                            "status_changed_at": "2026-10-12T16:05:41Z",
                            "decline_reasons": []
                          },
                          "transaction": null,
                          "login": null,
                          "rule_hit": null,
                          "case_linked": null,
                          "note_added": null
                        },
                        {
                          "id": "signal_observed:8d7c6b5a-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
                          "event_type": "signal_observed",
                          "occurred_at": "2026-10-12T16:03:10Z",
                          "ingested_at": "2026-10-01T09:12:44Z",
                          "label": "device observed",
                          "metadata": {
                            "signal_type": "device",
                            "subject_count": 3,
                            "is_hub": false
                          },
                          "account": null,
                          "source_ref": null,
                          "verification_attempt": null,
                          "transaction": null,
                          "login": null,
                          "rule_hit": null,
                          "case_linked": null,
                          "note_added": null
                        }
                      ],
                      "next_cursor": "eyJ0IjoiMjAyNi0xMC0xMlQxNjowMzoxMCswMDowMCIsImMiOiIyMDI2LTEwLTAxVDA5OjEyOjQ0KzAwOjAwIiwiciI6MSwidSI6IjhkN2M2YjVhLTRlM2YtNGEyYi05YzFkLTBlOWY4YTdiNmM1ZCJ9"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`contract`가 존재하는 경우: 유효하지 않은 `contract`, `limit`, `cursor` 또는 `event_type` 값입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Unsupported contract": {
                    "summary": "지원되지 않는 컨트랙트",
                    "value": {
                      "contract": [
                        "\"3\" is not a valid choice."
                      ]
                    }
                  },
                  "Invalid cursor": {
                    "summary": "유효하지 않은 커서",
                    "value": {
                      "cursor": [
                        "This cursor is not valid. Reload the feed."
                      ]
                    }
                  },
                  "Limit too large": {
                    "summary": "제한값이 너무 큼",
                    "value": {
                      "limit": [
                        "Ensure this value is less than or equal to 500."
                      ]
                    }
                  },
                  "Unknown event type": {
                    "summary": "알 수 없는 이벤트 유형",
                    "value": {
                      "event_type": {
                        "0": [
                          "\"logout\" is not a valid choice."
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "자격 증명이 누락되었거나 유효하지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "코드화된 오류에 표시됩니다(예: `networks_not_entitled`)."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "자격 증명이 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 다른 애플리케이션에 속해 있거나 접근 권한이 제한된 키입니다. Networks 엔드포인트에는 전체 접근 권한 키가 필요합니다. 콘솔 멤버 토큰에는 `read:networks` 권한이 필요합니다. 조직에 Networks가 활성화되어 있지 않은 경우 `code: networks_not_entitled`와 함께 반환되기도 합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "코드화된 오류에 표시됩니다(예: `networks_not_entitled`)."
                    }
                  }
                },
                "examples": {
                  "Networks not enabled": {
                    "summary": "네트워크가 활성화되지 않았습니다",
                    "value": {
                      "detail": "Networks is disabled for this organization. Contact Didit support if you believe this is an error.",
                      "code": "networks_not_entitled"
                    }
                  },
                  "Restricted API key": {
                    "summary": "제한된 API 키",
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "No permission": {
                    "summary": "권한 없음",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "네트워크를 찾을 수 없습니다(또는 이 애플리케이션에 표시되지 않음).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/map/": {
      "get": {
        "summary": "네트워크 지도 조회",
        "description": "멤버십을 뒷받침하는 세션, 기업 세션 및 거래에서 추출한, 이 네트워크 멤버들의 주소/위치가 수렴하는 지리적 지점입니다.",
        "operationId": "get_network_map",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "retrieve_map",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "n3a5e000-0000-4000-8000-000000000001"
            },
            "description": "네트워크 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/map/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.retrieve_map(\n    \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.retrieveMap(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.RetrieveMap(ctx, \"n3a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().retrieveMap(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->retrieveMap('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.retrieve_map(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RetrieveMapAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "네트워크 맵입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkMap"
                }
              }
            }
          },
          "404": {
            "description": "네트워크를 찾을 수 없습니다(또는 이 애플리케이션에 표시되지 않음).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/sessions/{session_id}/networks/": {
      "get": {
        "summary": "세션의 네트워크 목록 조회",
        "description": "세션의 벤더 사용자가 속한 네트워크를 나열합니다. 세션의 vendor_data에 연결된 사용자를 통해 확인합니다.",
        "operationId": "list_session_network_memberships",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list_networks",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "세션 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/sessions/aaaaaaaa-0000-4000-8000-000000000001/networks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.sessions.list_networks(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.sessions.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.sessions().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->sessions->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.sessions.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "이 엔티티가 속한 네트워크입니다. 페이지로 나뉘지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityNetworkMembershipList"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에서 엔티티를 찾을 수 없거나, 조회할 수 있는 연결된 주체가 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/business-sessions/{business_session_id}/networks/": {
      "get": {
        "summary": "기업 세션의 네트워크 목록 조회",
        "description": "기업 세션의 벤더 기업이 속한 네트워크를 나열합니다.",
        "operationId": "list_business_session_network_memberships",
        "x-didit-sdk": {
          "resource": "business_sessions",
          "method": "list_networks",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "business_session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "기업 세션 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/business-sessions/aaaaaaaa-0000-4000-8000-000000000002/networks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.business_sessions.list_networks(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businessSessions.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.BusinessSessions.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businessSessions().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->businessSessions->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.business_sessions.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.BusinessSessions.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "이 엔티티가 속한 네트워크입니다. 페이지로 나뉘지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityNetworkMembershipList"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에서 엔티티를 찾을 수 없거나, 조회할 수 있는 연결된 주체가 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/users/{vendor_user_uuid}/networks/": {
      "get": {
        "summary": "사용자의 네트워크 목록 조회",
        "description": "벤더 사용자가 속한 네트워크 목록 조회",
        "operationId": "list_user_network_memberships",
        "x-didit-sdk": {
          "resource": "users",
          "method": "list_networks",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "vendor_user_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "벤더 사용자 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/users/aaaaaaaa-0000-4000-8000-000000000003/networks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.users.list_networks(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.users.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Users.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.users().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->users->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.users.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Users.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "이 엔티티가 속한 네트워크입니다. 페이지로 나뉘지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityNetworkMembershipList"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에서 엔티티를 찾을 수 없거나, 조회할 수 있는 연결된 주체가 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/businesses/{vendor_business_uuid}/networks/": {
      "get": {
        "summary": "기업의 네트워크 목록 조회",
        "description": "벤더 기업이 속한 네트워크 목록 조회",
        "operationId": "list_business_network_memberships",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "list_networks",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "vendor_business_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "벤더 기업 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/businesses/aaaaaaaa-0000-4000-8000-000000000004/networks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.list_networks(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->businesses->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "이 엔티티가 속한 네트워크입니다. 페이지로 나뉘지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityNetworkMembershipList"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에서 엔티티를 찾을 수 없거나, 조회할 수 있는 연결된 주체가 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/transactions/{transaction_uuid}/networks/": {
      "get": {
        "summary": "거래의 네트워크 목록 조회",
        "description": "거래의 기본 KYC/KYB 주체가 속한 네트워크를 나열합니다(거래의 세션 또는 기업 세션을 통해 확인).",
        "operationId": "list_transaction_network_memberships",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "list_networks",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "transaction_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "거래 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/transactions/aaaaaaaa-0000-4000-8000-000000000005/networks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.transactions.list_networks(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.transactions.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.transactions().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->transactions->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.transactions.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "이 엔티티가 속한 네트워크입니다. 페이지로 나뉘지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityNetworkMembershipList"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에서 엔티티를 찾을 수 없거나, 조회할 수 있는 연결된 주체가 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/transactions/{transaction_uuid}/parties/{transaction_party_uuid}/networks/": {
      "get": {
        "summary": "거래 당사자의 네트워크 목록 조회",
        "description": "거래 당사자(송금인, 수취인 또는 거래 상대방)가 속한 네트워크를 거래의 기본 세션 대신 당사자 자체를 통해 확인하여 나열합니다.",
        "operationId": "list_transaction_party_network_memberships",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "list_party_networks",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "transaction_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "거래 UUID입니다."
          },
          {
            "name": "transaction_party_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "거래 당사자 UUID입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/transactions/aaaaaaaa-0000-4000-8000-000000000005/parties/bbbbbbbb-0000-4000-8000-000000000006/networks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.transactions.list_party_networks(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.transactions.listPartyNetworks(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.ListPartyNetworks(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.transactions().listPartyNetworks(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->transactions->listPartyNetworks('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.transactions.list_party_networks(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.ListPartyNetworksAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "이 엔티티가 속한 네트워크입니다. 페이지로 나뉘지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityNetworkMembershipList"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션에서 엔티티를 찾을 수 없거나, 조회할 수 있는 연결된 주체가 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/biometric-templates/": {
      "get": {
        "summary": "보존된 생체 인식 템플릿 목록 조회",
        "description": "옵트인된 애플리케이션은 세션이 삭제될 때 사용자에 연결된 별도로 관리되는 이미지가 없는 얼굴 생체 인식 템플릿 하나를 유지합니다(`DELETE /v3/session/{sessionId}/delete/` 참조). 템플릿은 유한한 `expires_at`을 가진 생체 인식 데이터입니다. 이미지, 세션 데이터 또는 신원 필드를 절대 포함하지 않으며, 사용자 삭제, 프라이버시 삭제, 만료 또는 명시적 영구 삭제 시 제거됩니다. 이 endpoint들은 애플리케이션 API 키(`x-api-key`)만 허용하며, Business Console 사용자 token은 `403`으로 거부됩니다.\n\n애플리케이션이 현재 보유하고 있는 템플릿의 페이지로 구분된 목록을 반환합니다. 영구 삭제된 템플릿은 나열되지 않습니다.",
        "operationId": "list_biometric_templates",
        "x-didit-sdk": {
          "resource": "biometric_templates",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Biometric Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "vendor_data",
            "required": false,
            "description": "소유 사용자의 현재 `vendor_data`에 대해 대소문자를 구분하지 않는 부분 문자열 일치 검색.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "vendor_user_uuid",
            "required": false,
            "description": "소유한 사용자에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "description": "수명 주기 상태입니다. 제거된 템플릿은 절대 나열되지 않습니다.",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "active",
                "expired",
                "held_out_of_use",
                "purge_pending",
                "purge_failed"
              ]
            }
          },
          {
            "in": "query",
            "name": "source_type",
            "required": false,
            "description": "템플릿이 생성된 방식입니다.",
            "schema": {
              "type": "string",
              "enum": [
                "session_delete",
                "automatic_retention",
                "backfill"
              ]
            }
          },
          {
            "in": "query",
            "name": "retained_from",
            "required": false,
            "description": "이 시간 이후(해당 시간 포함)에 보존된 템플릿입니다.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "retained_to",
            "required": false,
            "description": "이 시간 이전(해당 시간 포함)에 보존된 템플릿입니다. `retained_from`보다 이전일 수 없습니다(`400`).",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "ordering",
            "required": false,
            "description": "정렬 순서입니다.",
            "schema": {
              "type": "string",
              "enum": [
                "retained_at",
                "-retained_at",
                "expires_at",
                "-expires_at"
              ],
              "default": "-retained_at"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "페이지 크기입니다.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "description": "페이지네이션 오프셋입니다.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "페이지네이션된 템플릿 목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid",
                            "description": "템플릿 ID입니다. 무작위로 생성되며, 삭제된 세션이나 해당 얼굴에서 파생되지 않습니다."
                          },
                          "vendor_user_uuid": {
                            "type": "string",
                            "format": "uuid",
                            "description": "소유한 사용자입니다."
                          },
                          "vendor_data": {
                            "type": "string",
                            "nullable": true,
                            "description": "템플릿을 읽을 때 확인되는 사용자의 현재 `vendor_data`입니다(복사되지 않음)."
                          },
                          "source_type": {
                            "type": "string",
                            "enum": [
                              "session_delete",
                              "automatic_retention",
                              "backfill"
                            ],
                            "description": "템플릿이 생성된 방식: 세션 삭제(API 또는 콘솔), 애플리케이션의 자동 데이터 보존 기간 또는 귀하가 요청한 Didit 운영 백필입니다."
                          },
                          "provenance_reference": {
                            "type": "string",
                            "format": "uuid",
                            "description": "템플릿을 해당 감사 로그와 연결하는 불투명 참조입니다. 삭제된 세션의 id가 아니며 해당 id로 확인할 수 없습니다."
                          },
                          "retention_policy": {
                            "type": "string",
                            "enum": [
                              "delete_with_session",
                              "retain_until_user_deleted"
                            ],
                            "description": "보존 시점의 애플리케이션 정책입니다."
                          },
                          "retention_override": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "삭제 시 전송된 `retain_face_embeddings` 값이며, 정책이 적용된 경우 `null`입니다."
                          },
                          "retained_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "expires_at": {
                            "type": "string",
                            "format": "date-time",
                            "description": "템플릿이 만료되어 자동으로 파기되는 시점입니다. 항상 설정됩니다."
                          },
                          "retained_by": {
                            "type": "string",
                            "nullable": true,
                            "description": "지침을 내린 주체: API 키의 경우 애플리케이션 ID, 콘솔 작업의 경우 콘솔 멤버 ID, 자동 보존의 경우 `service:` 식별자입니다. 이메일 주소는 사용할 수 없습니다."
                          },
                          "retained_by_type": {
                            "type": "string",
                            "enum": [
                              "API_KEY",
                              "CONSOLE_USER",
                              "SYSTEM"
                            ]
                          },
                          "instruction_class": {
                            "type": "string",
                            "enum": [
                              "operational_session_delete",
                              "privacy_erasure"
                            ]
                          },
                          "instruction_source": {
                            "type": "string",
                            "enum": [
                              "api",
                              "console",
                              "automatic_retention",
                              "backfill",
                              "privacy_erasure",
                              "explicit_template_purge",
                              "vendor_user_delete",
                              "expiry",
                              "reconciliation",
                              "migration",
                              "system"
                            ]
                          },
                          "instruction_id": {
                            "type": "string",
                            "description": "삭제 시 전송된 `instruction_id` 또는 Didit에서 생성된 id입니다."
                          },
                          "held_out_of_use": {
                            "type": "boolean",
                            "description": "법적 보존 조치가 적용되는 동안에만 `true`입니다. 보존 조치된 템플릿은 모든 대조에서 제외됩니다."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "pending",
                              "active",
                              "expired",
                              "held_out_of_use",
                              "purge_pending",
                              "purge_failed",
                              "purged"
                            ],
                            "description": "보류되지 않고, `expires_at`이 지나지 않았으며, 해당 사용자가 여전히 존재하는 `active` 템플릿만 대조에 참여합니다."
                          },
                          "purged_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "One active template": {
                    "value": {
                      "count": 1,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                          "vendor_user_uuid": "2f7c1a9e-8b4d-4c6a-9e1f-3d5b7a9c1e2f",
                          "vendor_data": "user-42",
                          "source_type": "session_delete",
                          "provenance_reference": "6b1e8d2f-4a3c-4f9e-8c7d-1a2b3c4d5e6f",
                          "retention_policy": "retain_until_user_deleted",
                          "retention_override": null,
                          "retained_at": "2026-08-28T10:15:42.318402Z",
                          "expires_at": "2027-08-28T10:15:42.318402Z",
                          "retained_by": "3c9e2b1f-7d4a-4e8b-9c1d-5f6a7b8c9d0e",
                          "retained_by_type": "API_KEY",
                          "instruction_class": "operational_session_delete",
                          "instruction_source": "api",
                          "instruction_id": "post-approval-cleanup-2026-08",
                          "held_out_of_use": false,
                          "status": "active",
                          "purged_at": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 필터 값이거나, `retained_to`가 `retained_from`보다 이전입니다. 필드별 유효성 검사 오류가 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Bad range": {
                    "value": {
                      "retained_to": [
                        "Must be on or after retained_from."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "콘솔 사용자 token이거나 허용되지 않은 API 키입니다. 이 endpoint들은 애플리케이션 API 키만 허용합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/biometric-templates/?vendor_data=user-42&status=active' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.biometric_templates.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.biometricTemplates.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.BiometricTemplates.ListAutoPaging(ctx, didit.BiometricTemplatesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.biometricTemplates().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->biometricTemplates->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.biometric_templates.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.BiometricTemplates.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/biometric-templates/count/": {
      "get": {
        "summary": "보존된 생체 인식 템플릿 수 조회",
        "description": "옵트인된 애플리케이션은 세션이 삭제될 때 사용자에 연결된 별도로 관리되는 이미지가 없는 얼굴 생체 인식 템플릿 하나를 유지합니다(`DELETE /v3/session/{sessionId}/delete/` 참조). 템플릿은 유한한 `expires_at`을 가진 생체 인식 데이터입니다. 이미지, 세션 데이터 또는 신원 필드를 절대 포함하지 않으며, 사용자 삭제, 프라이버시 삭제, 만료 또는 명시적 영구 삭제 시 제거됩니다. 이 endpoint들은 애플리케이션 API 키(`x-api-key`)만 허용하며, Business Console 사용자 token은 `403`으로 거부됩니다.\n\n목록 endpoint와 동일한 필터와 일치하는 템플릿 수를 반환합니다. `delete_all: true`를 사용한 필터링된 대량 영구 삭제가 어떤 항목에 영향을 미치는지 확인하는 데 사용합니다.",
        "operationId": "count_biometric_templates",
        "x-didit-sdk": {
          "resource": "biometric_templates",
          "method": "count",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Biometric Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "vendor_data",
            "required": false,
            "description": "소유 사용자의 현재 `vendor_data`에 대해 대소문자를 구분하지 않는 부분 문자열 일치 검색.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "vendor_user_uuid",
            "required": false,
            "description": "소유한 사용자에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "description": "수명 주기 상태입니다. 제거된 템플릿은 절대 나열되지 않습니다.",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "active",
                "expired",
                "held_out_of_use",
                "purge_pending",
                "purge_failed"
              ]
            }
          },
          {
            "in": "query",
            "name": "source_type",
            "required": false,
            "description": "템플릿이 생성된 방식입니다.",
            "schema": {
              "type": "string",
              "enum": [
                "session_delete",
                "automatic_retention",
                "backfill"
              ]
            }
          },
          {
            "in": "query",
            "name": "retained_from",
            "required": false,
            "description": "이 시간 이후(해당 시간 포함)에 보존된 템플릿입니다.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "retained_to",
            "required": false,
            "description": "이 시간 이전(해당 시간 포함)에 보존된 템플릿입니다. `retained_from`보다 이전일 수 없습니다(`400`).",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "개수입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "minimum": 0
                    }
                  }
                },
                "examples": {
                  "Count": {
                    "value": {
                      "count": 128
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 필터 값이거나, `retained_to`가 `retained_from`보다 이전입니다. 필드별 유효성 검사 오류가 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Bad range": {
                    "value": {
                      "retained_to": [
                        "Must be on or after retained_from."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "콘솔 사용자 token이거나 허용되지 않은 API 키입니다. 이 endpoint들은 애플리케이션 API 키만 허용합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/biometric-templates/count/?status=active' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.biometric_templates.count()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.biometricTemplates.count();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.BiometricTemplates.Count(ctx, didit.BiometricTemplatesCountParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.biometricTemplates().count();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->biometricTemplates->count();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.biometric_templates.count\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.BiometricTemplates.CountAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/biometric-templates/{template_uuid}/": {
      "get": {
        "summary": "보존된 생체 인식 템플릿 조회",
        "description": "옵트인된 애플리케이션은 세션이 삭제될 때 사용자에 연결된 별도로 관리되는 이미지가 없는 얼굴 생체 인식 템플릿 하나를 유지합니다(`DELETE /v3/session/{sessionId}/delete/` 참조). 템플릿은 유한한 `expires_at`을 가진 생체 인식 데이터입니다. 이미지, 세션 데이터 또는 신원 필드를 절대 포함하지 않으며, 사용자 삭제, 프라이버시 삭제, 만료 또는 명시적 영구 삭제 시 제거됩니다. 이 endpoint들은 애플리케이션 API 키(`x-api-key`)만 허용하며, Business Console 사용자 token은 `403`으로 거부됩니다.\n\n템플릿 하나를 반환합니다. 응답에는 이미지, 벡터, 삭제된 세션의 id 또는 신원 데이터가 절대 포함되지 않습니다.",
        "operationId": "get_biometric_template",
        "x-didit-sdk": {
          "resource": "biometric_templates",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Biometric Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "template_uuid",
            "required": true,
            "description": "세션 삭제 endpoint에서 `biometric_template_uuid`로 반환되거나, 얼굴 검색 일치 시 `biometric_template_id`로 반환되거나, 목록 endpoint에서 반환된 템플릿 ID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "템플릿입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "템플릿 ID입니다. 무작위로 생성되며, 삭제된 세션이나 해당 얼굴에서 파생되지 않습니다."
                    },
                    "vendor_user_uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "소유한 사용자입니다."
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "템플릿을 읽을 때 확인되는 사용자의 현재 `vendor_data`입니다(복사되지 않음)."
                    },
                    "source_type": {
                      "type": "string",
                      "enum": [
                        "session_delete",
                        "automatic_retention",
                        "backfill"
                      ],
                      "description": "템플릿이 생성된 방식: 세션 삭제(API 또는 콘솔), 애플리케이션의 자동 데이터 보존 기간 또는 귀하가 요청한 Didit 운영 백필입니다."
                    },
                    "provenance_reference": {
                      "type": "string",
                      "format": "uuid",
                      "description": "템플릿을 해당 감사 로그와 연결하는 불투명 참조입니다. 삭제된 세션의 id가 아니며 해당 id로 확인할 수 없습니다."
                    },
                    "retention_policy": {
                      "type": "string",
                      "enum": [
                        "delete_with_session",
                        "retain_until_user_deleted"
                      ],
                      "description": "보존 시점의 애플리케이션 정책입니다."
                    },
                    "retention_override": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "삭제 시 전송된 `retain_face_embeddings` 값이며, 정책이 적용된 경우 `null`입니다."
                    },
                    "retained_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "템플릿이 만료되어 자동으로 파기되는 시점입니다. 항상 설정됩니다."
                    },
                    "retained_by": {
                      "type": "string",
                      "nullable": true,
                      "description": "지침을 내린 주체: API 키의 경우 애플리케이션 ID, 콘솔 작업의 경우 콘솔 멤버 ID, 자동 보존의 경우 `service:` 식별자입니다. 이메일 주소는 사용할 수 없습니다."
                    },
                    "retained_by_type": {
                      "type": "string",
                      "enum": [
                        "API_KEY",
                        "CONSOLE_USER",
                        "SYSTEM"
                      ]
                    },
                    "instruction_class": {
                      "type": "string",
                      "enum": [
                        "operational_session_delete",
                        "privacy_erasure"
                      ]
                    },
                    "instruction_source": {
                      "type": "string",
                      "enum": [
                        "api",
                        "console",
                        "automatic_retention",
                        "backfill",
                        "privacy_erasure",
                        "explicit_template_purge",
                        "vendor_user_delete",
                        "expiry",
                        "reconciliation",
                        "migration",
                        "system"
                      ]
                    },
                    "instruction_id": {
                      "type": "string",
                      "description": "삭제 시 전송된 `instruction_id` 또는 Didit에서 생성된 id입니다."
                    },
                    "held_out_of_use": {
                      "type": "boolean",
                      "description": "법적 보존 조치가 적용되는 동안에만 `true`입니다. 보존 조치된 템플릿은 모든 대조에서 제외됩니다."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "active",
                        "expired",
                        "held_out_of_use",
                        "purge_pending",
                        "purge_failed",
                        "purged"
                      ],
                      "description": "보류되지 않고, `expires_at`이 지나지 않았으며, 해당 사용자가 여전히 존재하는 `active` 템플릿만 대조에 참여합니다."
                    },
                    "purged_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    }
                  }
                },
                "examples": {
                  "Active template": {
                    "value": {
                      "uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                      "vendor_user_uuid": "2f7c1a9e-8b4d-4c6a-9e1f-3d5b7a9c1e2f",
                      "vendor_data": "user-42",
                      "source_type": "session_delete",
                      "provenance_reference": "6b1e8d2f-4a3c-4f9e-8c7d-1a2b3c4d5e6f",
                      "retention_policy": "retain_until_user_deleted",
                      "retention_override": null,
                      "retained_at": "2026-08-28T10:15:42.318402Z",
                      "expires_at": "2027-08-28T10:15:42.318402Z",
                      "retained_by": "3c9e2b1f-7d4a-4e8b-9c1d-5f6a7b8c9d0e",
                      "retained_by_type": "API_KEY",
                      "instruction_class": "operational_session_delete",
                      "instruction_source": "api",
                      "instruction_id": "post-approval-cleanup-2026-08",
                      "held_out_of_use": false,
                      "status": "active",
                      "purged_at": null
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "콘솔 사용자 token이거나 허용되지 않은 API 키입니다. 이 endpoint들은 애플리케이션 API 키만 허용합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 템플릿이거나, 다른 애플리케이션의 템플릿이거나, (`GET` 시) 영구 삭제된 템플릿입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Biometric template not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/biometric-templates/9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.biometric_templates.retrieve(\n    \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.biometricTemplates.retrieve(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.BiometricTemplates.Retrieve(ctx, \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.biometricTemplates().retrieve(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->biometricTemplates->retrieve('9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.biometric_templates.retrieve(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.BiometricTemplates.RetrieveAsync(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "summary": "보존된 생체 인식 템플릿 영구 삭제",
        "description": "옵트인된 애플리케이션은 세션이 삭제될 때 사용자에 연결된 별도로 관리되는 이미지가 없는 얼굴 생체 인식 템플릿 하나를 유지합니다(`DELETE /v3/session/{sessionId}/delete/` 참조). 템플릿은 유한한 `expires_at`을 가진 생체 인식 데이터입니다. 이미지, 세션 데이터 또는 신원 필드를 절대 포함하지 않으며, 사용자 삭제, 프라이버시 삭제, 만료 또는 명시적 영구 삭제 시 제거됩니다. 이 endpoint들은 애플리케이션 API 키(`x-api-key`)만 허용하며, Business Console 사용자 token은 `403`으로 거부됩니다.\n\n템플릿 하나를 영구 삭제합니다. 모든 종류의 매칭에서 제거되고 저장된 템플릿이 삭제됩니다. 되돌릴 수 없으며 작업을 수행한 주체와 함께 감사 로그에 기록됩니다.\n\n**재시도 시맨틱:** Didit은 저장된 템플릿을 먼저 삭제한 후에만 템플릿을 영구 삭제됨으로 표시합니다. 생체 인식 저장소를 사용할 수 없는 경우 호출은 `503`을 반환하고, 템플릿은 `status: purge_failed` 상태로 이동하며 매칭에서 이미 제외됩니다. 완료하려면 동일한 호출을 반복하십시오. 이미 영구 삭제된 템플릿의 영구 삭제를 반복하면 `already_purged`가 반환됩니다.\n\n템플릿은 소유 사용자에 대한 `POST /v3/users/delete/`, 해당 사용자의 세션에 대한 `deletion_instruction: privacy_erasure`를 사용한 삭제, 그리고 `expires_at` 도달 시 자동으로도 영구 삭제됩니다.",
        "operationId": "purge_biometric_template",
        "x-didit-sdk": {
          "resource": "biometric_templates",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Biometric Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "template_uuid",
            "required": true,
            "description": "세션 삭제 endpoint에서 `biometric_template_uuid`로 반환되거나, 얼굴 검색 일치 시 `biometric_template_id`로 반환되거나, 목록 endpoint에서 반환된 템플릿 ID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "영구 삭제 결과.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "outcome": {
                      "type": "string",
                      "enum": [
                        "purged",
                        "already_purged"
                      ]
                    }
                  }
                },
                "examples": {
                  "Purged": {
                    "value": {
                      "uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                      "outcome": "purged"
                    }
                  },
                  "Already purged": {
                    "value": {
                      "uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                      "outcome": "already_purged"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "콘솔 사용자 token이거나 허용되지 않은 API 키입니다. 이 endpoint들은 애플리케이션 API 키만 허용합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 템플릿이거나, 다른 애플리케이션의 템플릿이거나, (`GET` 시) 영구 삭제된 템플릿입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Biometric template not found."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "생체 인식 템플릿을 보존하거나 삭제하는 동안 생체 인식 저장소를 사용할 수 없었습니다. 아무것도 삭제되지 않았으므로 동일한 요청을 반복하십시오. 재시도는 멱등성을 가지며 단일 템플릿으로 수렴됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Retryable": {
                    "value": {
                      "detail": "The biometric-template operation could not finish because an external store is unavailable. The operation is retryable."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE https://verification.didit.me/v3/biometric-templates/9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.biometric_templates.delete(\n    \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.biometricTemplates.delete(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.BiometricTemplates.Delete(ctx, \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.biometricTemplates().delete(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->biometricTemplates->delete('9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.biometric_templates.delete(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.BiometricTemplates.DeleteAsync(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/biometric-templates/delete/": {
      "post": {
        "summary": "보존된 생체 인식 템플릿 일괄 삭제",
        "description": "옵트인한 애플리케이션은 세션이 삭제될 때 사용자에게 연결된 별도로 관리되는 이미지가 없는 얼굴 생체 인식 템플릿 하나를 유지합니다(`DELETE /v3/session/{sessionId}/delete/` 참조). 템플릿은 유한한 `expires_at`이 있는 생체 인식 데이터입니다. 이미지, 세션 데이터 또는 신원 필드를 절대 포함하지 않으며, 사용자 삭제, 개인정보 삭제 처리, 만료 또는 명시적 영구 삭제 시 완전히 삭제됩니다. 이러한 endpoint는 애플리케이션 API 키(`x-api-key`)만 허용하며, Business Console 사용자 token은 `403`으로 거부됩니다.\n\n한 번의 호출로 명시적 ID 목록을 사용하거나 목록 endpoint와 동일한 필터로 선택적으로 범위를 좁힌 `delete_all: true`를 사용하여 여러 템플릿을 영구 삭제합니다. 템플릿은 하나씩 영구 삭제되며 각 결과는 `purged` 또는 `already_purged`로 보고됩니다. 생체 인식 저장소를 사용할 수 없는 경우 호출 시 실패한 첫 번째 템플릿에서 `503`을 반환합니다. 요청에서 이전에 영구 삭제된 템플릿은 영구 삭제된 상태로 유지되고, 실패한 템플릿은 `purge_failed`로 이동하며(이미 대조에서 제외됨), 요청을 반복하면 작업을 완료합니다.\n\n**필터 없이 `delete_all: true`를 사용하면 애플리케이션의 모든 생체 인식 템플릿이 영구 삭제되며 되돌릴 수 없습니다.** 먼저 동일한 필터로 개수 조회 endpoint를 실행하세요.",
        "operationId": "bulk_purge_biometric_templates",
        "x-didit-sdk": {
          "resource": "biometric_templates",
          "method": "batch_delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Biometric Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "template_uuids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1,
                    "description": "영구 삭제할 템플릿입니다. `delete_all`이 `true`가 아닌 경우 필수입니다. 이미 영구 삭제된 ID는 `already_purged`로 보고됩니다."
                  },
                  "delete_all": {
                    "type": "boolean",
                    "default": false,
                    "description": "`true`인 경우 아래 필터와 일치하는 모든 템플릿을 영구 삭제합니다(필터가 제공되지 않으면 애플리케이션의 모든 템플릿). `template_uuids`는 무시됩니다. 되돌릴 수 없습니다."
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "`delete_all`과 함께 사용할 때만 적용: 소유한 사용자의 `vendor_data`에 대한 대소문자 구분 없는 부분 문자열 일치."
                  },
                  "vendor_user_uuid": {
                    "type": "string",
                    "format": "uuid",
                    "description": "`delete_all`과 함께 사용할 때만 적용: 소유 User에 대한 정확한 일치."
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "pending",
                      "active",
                      "expired",
                      "held_out_of_use",
                      "purge_pending",
                      "purge_failed"
                    ],
                    "description": "`delete_all`과 함께 사용할 때만 유효합니다."
                  },
                  "source_type": {
                    "type": "string",
                    "enum": [
                      "session_delete",
                      "automatic_retention",
                      "backfill"
                    ],
                    "description": "`delete_all`과 함께 사용할 때만 유효합니다."
                  },
                  "retained_from": {
                    "type": "string",
                    "format": "date-time",
                    "description": "`delete_all`과 함께 사용할 때만 유효합니다."
                  },
                  "retained_to": {
                    "type": "string",
                    "format": "date-time",
                    "description": "`delete_all`과 함께 사용할 때만 유효합니다. `retained_from`보다 이전일 수 없습니다."
                  }
                }
              },
              "examples": {
                "By id": {
                  "value": {
                    "template_uuids": [
                      "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                      "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
                    ]
                  }
                },
                "Every template of one User": {
                  "value": {
                    "delete_all": true,
                    "vendor_user_uuid": "2f7c1a9e-8b4d-4c6a-9e1f-3d5b7a9c1e2f"
                  }
                },
                "Every template in the application": {
                  "value": {
                    "delete_all": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "템플릿별 삭제 결과입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "outcome": {
                            "type": "string",
                            "enum": [
                              "purged",
                              "already_purged"
                            ]
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Mixed": {
                    "value": {
                      "results": [
                        {
                          "uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                          "outcome": "purged"
                        },
                        {
                          "uuid": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                          "outcome": "already_purged"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 오류 — 아무것도 영구 삭제되지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing selector": {
                    "value": {
                      "template_uuids": [
                        "This field is required unless delete_all is true."
                      ]
                    }
                  },
                  "Bad range": {
                    "value": {
                      "retained_to": [
                        "Must be on or after retained_from."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "콘솔 사용자 token이거나 허용되지 않은 API 키입니다. 이 endpoint들은 애플리케이션 API 키만 허용합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "생체 인식 템플릿을 보존하거나 삭제하는 동안 생체 인식 저장소를 사용할 수 없었습니다. 아무것도 삭제되지 않았으므로 동일한 요청을 반복하십시오. 재시도는 멱등성을 가지며 단일 템플릿으로 수렴됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Retryable": {
                    "value": {
                      "detail": "The biometric-template operation could not finish because an external store is unavailable. The operation is retryable."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/biometric-templates/delete/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"delete_all\": true, \"vendor_user_uuid\": \"2f7c1a9e-8b4d-4c6a-9e1f-3d5b7a9c1e2f\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.biometric_templates.batch_delete(\n    template_uuids=[\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.biometricTemplates.batchDelete({\n  template_uuids: [\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.BiometricTemplates.BatchDelete(ctx, didit.BiometricTemplatesBatchDeleteParams{\n\tTemplateUUIDs: didit.Some([]string{\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.BiometricTemplatesBatchDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.biometricTemplates().batchDelete(BiometricTemplatesBatchDeleteParams.builder()\n        .templateUuids(List.of(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->biometricTemplates->batchDelete([\n    'template_uuids' => ['9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b', '1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.biometric_templates.batch_delete(template_uuids: [\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.BiometricTemplates.BatchDeleteAsync(new BiometricTemplatesBatchDeleteParams\n{\n    TemplateUuids = new string[] { \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/kyb/shareholders/": {
      "post": {
        "summary": "주주 정보가 포함된 KYB 등기부 기업(독립 실행형)",
        "operationId": "post_v3_kyb_shareholders",
        "x-didit-sdk": {
          "resource": "kyb",
          "method": "list_shareholders",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [],
        "description": "`POST /v3/kyb/search/`에서 반환된 후보 중 하나의 Lite 프로필과 **직접 주주**(자연인 및 법인, 지분율 범위 포함)를 조회합니다.\n\n**검색과의 매칭.** 동일한 애플리케이션의 검색에서 반환된 후보의 `kyb_response_id`를 그대로 전달하십시오. 구매하려는 등급(`POST /v3/kyb/search/`의 `tier`)으로 검색해야 합니다. 해당 등급을 제공하는 등기부 체인에서 검색이 실행되며, Lite 검색 결과가 비어 있다고 해서 등기부에 해당 기업이 없다는 증거는 아니기 때문입니다. 해당 국가의 소유 구조 데이터가 다른 등기부에 있는 경우, Didit은 추가 비용 없이 등록번호로 해당 등기부에서 기업을 다시 찾습니다.\n\n**결제.** 해당 국가의 주주(Shareholders) 요금으로 청구됩니다([KYB 등기부 요금](/ko/getting-started/kyb-registry-pricing) 참조). 등기부에 해당 기업의 주주 기록이 없거나(또는 해당 국가에서 소유 구조 데이터를 전혀 제공하지 않는 경우) 대신 Lite 프로필이 제공되고 해당 요금이 청구됩니다. `registry_tier_delivered` 및 `registry_ownership_status`를 확인하십시오. 등기부 호출 전에 주주 요금 기준으로 잔액을 확인합니다(부족 시 `403`).\n\n**지원 여부.** v3 전용입니다. 모든 호출은 기업 세션을 생성합니다(세션 ID는 `request_id`임).\n\n**대기 중인 보고서.** 보고서가 아직 준비 중이거나 소유 구조 섹션이 아직 등기부에서 조회되지 않은 경우, 엔드포인트는 202 Accepted, kyb_registry.fetch_status=pending, kyb_registry.registry_ownership_status=pending, registry_tier_delivered=null을 반환합니다. request_id를 보관하고 registry_checks[0].company.fetch_status가 확정될 때까지 GET /v3/session/{request_id}/decision/을 조회하십시오. Didit은 보고서를 자동으로 완료하고 준비가 완료되면 제공된 등급에 대해 요금을 청구합니다. 대기 중인 동안 구매를 반복하지 마십시오. 새로운 POST 호출마다 별도의 요청이 생성됩니다.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KYBRegistryCandidateRequest"
              },
              "example": {
                "kyb_response_id": "69aeeb95febb0f1704042259",
                "vendor_data": "company-1234"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/kyb/shareholders/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"kyb_response_id\": \"69aeeb95febb0f1704042259\",\n    \"vendor_data\": \"company-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.kyb.list_shareholders(\n    kyb_response_id=\"69aeeb95febb0f1704042259\",\n    vendor_data=\"company-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.kyb.listShareholders({\n  kyb_response_id: \"69aeeb95febb0f1704042259\",\n  vendor_data: \"company-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.KYB.ListShareholders(ctx, didit.KYBRegistryCandidateRequest{\n\tKYBResponseID: \"69aeeb95febb0f1704042259\",\n\tVendorData:    didit.String(\"company-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.KYBRegistryCandidateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.kyb().listShareholders(KYBRegistryCandidateRequest.builder()\n        .kybResponseId(\"69aeeb95febb0f1704042259\")\n        .vendorData(\"company-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->kyb->listShareholders([\n    'kyb_response_id' => '69aeeb95febb0f1704042259',\n    'vendor_data' => 'company-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.kyb.list_shareholders(\n  kyb_response_id: \"69aeeb95febb0f1704042259\",\n  vendor_data: \"company-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Kyb.ListShareholdersAsync(new KYBRegistryCandidateRequest\n{\n    KybResponseId = \"69aeeb95febb0f1704042259\",\n    VendorData = \"company-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "제공된 등급에 따라 반환되고 청구되는 기업 보고서입니다. 아직 준비 중인 소유 구조 보고서는 202를 반환할 수 있습니다. 저장된 결정을 조회하려면 request_id를 보관하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "이 조회에 대해 생성된 기업 세션의 Id입니다. 응답 이후 법인 등기부 조회가 완료되면 저장된 레코드(콘솔에서 확인 가능)가 계속 업데이트됩니다."
                    },
                    "registry_tier_requested": {
                      "type": "string",
                      "enum": [
                        "basic",
                        "shareholders",
                        "ubo"
                      ],
                      "description": "이 endpoint에서 판매하는 등급: select의 경우 `basic` (Lite), `shareholders`, `ubo`입니다."
                    },
                    "registry_tier_delivered": {
                      "type": "string",
                      "enum": [
                        "basic",
                        "shareholders",
                        "ubo",
                        null
                      ],
                      "description": "실제로 제공되어 결제 청구된 등급입니다. 해당 국가의 등기부에 소유 구조 데이터가 없거나, 등기부에 이 기업의 소유 구조 기록이 없는 경우 요청한 등급보다 낮아집니다.",
                      "nullable": true
                    },
                    "kyb_registry": {
                      "type": "object",
                      "description": "전체 등기부 기업 프로필입니다.",
                      "properties": {
                        "uuid": {
                          "type": "string",
                          "format": "uuid",
                          "description": "이 기업 레코드에 대한 Didit의 ID입니다."
                        },
                        "node_id": {
                          "type": "string",
                          "example": "feature_kyb_registry"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "Not Finished",
                            "Approved",
                            "Declined",
                            "In Review"
                          ],
                          "description": "법인 등기부 확인에 대한 Didit의 평가입니다(예: 기업이 등기부에서 활성 상태가 아니거나 소유 구조 데이터를 도출할 수 없는 경우 `In Review`)."
                        },
                        "registry_status": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "active",
                            "dissolved",
                            "deregistered",
                            "see full details",
                            "authorised",
                            "appointed representative",
                            "unauthorised",
                            "inactive",
                            "no longer authorised",
                            "closed",
                            "struck off",
                            null
                          ],
                          "description": "등기소에서 보고된 정규화된 기업 상태입니다."
                        },
                        "data_resolved": {
                          "type": "boolean",
                          "description": "등기소에서 전체 프로필을 반환하면 `true`입니다. 폴링 후에도 등기소에서 여전히 처리 중인 경우 `false`이며, 저장된 레코드는 등기소 처리가 완료되면 자동으로 완료됩니다."
                        },
                        "company_name": {
                          "type": "string",
                          "example": "Tesco PLC"
                        },
                        "registration_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "00445790"
                        },
                        "country_code": {
                          "type": "string",
                          "description": "ISO 3166-1 alpha-2.",
                          "example": "GB"
                        },
                        "region": {
                          "type": "string",
                          "nullable": true,
                          "description": "법인 등기부가 지역 단위인 경우 행정 구역 코드(예: `US-CA`의 경우 `CA`), 그렇지 않은 경우 비어 있습니다."
                        },
                        "company_type": {
                          "type": "string",
                          "nullable": true,
                          "example": "Public Limited Company"
                        },
                        "incorporation_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "1947-11-27"
                        },
                        "registered_address": {
                          "type": "string",
                          "nullable": true,
                          "example": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA"
                        },
                        "tax_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "GB412 8925 93"
                        },
                        "risk_level": {
                          "type": "string",
                          "nullable": true,
                          "description": "제공되는 경우, 법인 등기부에 보고된 위험 수준입니다."
                        },
                        "verification_status": {
                          "type": "string",
                          "enum": [
                            "verified",
                            "failed",
                            "unknown"
                          ],
                          "nullable": true,
                          "description": "관할 구역 간 검증 상태: 등기부 상태가 존속 상태(`active`)를 확정하는 경우 `verified`, 회사가 더 이상 존속하지 않음(예: `dissolved`)을 나타내는 경우 `failed`, 그 외의 경우 `unknown`입니다. 등기부에서 가져오지 않은 회사 및 선택이 아직 `pending` 상태인 동안에는 `null`입니다."
                        },
                        "is_from_registry": {
                          "type": "boolean",
                          "description": "이 endpoint의 경우 항상 `true`입니다. 프로필을 공식 등기부에서 조회했습니다."
                        },
                        "fetch_status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "resolved"
                          ],
                          "description": "법인 등기부 조회 라이프사이클입니다. `data_resolved`에 반영됩니다."
                        },
                        "alternative_names": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우, 텍스트 형태의 대체명, 상호명, 이전 명칭 또는 원어 기업명입니다."
                        },
                        "nature_of_business": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우의 업종 설명 또는 분류 코드입니다."
                        },
                        "registered_capital": {
                          "type": "string",
                          "nullable": true
                        },
                        "registered_capital_amount": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우, 문자열 형태의 십진수 금액입니다."
                        },
                        "registered_capital_currency": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우의 ISO 4217 코드입니다."
                        },
                        "website": {
                          "type": "string",
                          "nullable": true,
                          "example": "https://www.tesco.com/"
                        },
                        "email": {
                          "type": "string",
                          "nullable": true,
                          "example": "customer.service@tesco.co.uk"
                        },
                        "phone": {
                          "type": "string",
                          "nullable": true,
                          "example": "03301231688"
                        },
                        "legal_entity_identifier": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우의 LEI입니다."
                        },
                        "location_of_registration": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우, 기업이 등록된 법인 등기부/관할 구역입니다."
                        },
                        "vat_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "호스팅 법인 등기부 단계에서 수집되었거나 이후 편집된 EU VAT 번호입니다. 선택 시점에는 일반적으로 아직 설정되지 않습니다. VAT 및 납세자 번호 검증은 최종 사용자가 호스팅 흐름에서 법인 등기부 단계를 제출할 때 실행됩니다."
                        },
                        "vat_validation_status": {
                          "type": "string",
                          "enum": [
                            "valid",
                            "invalid",
                            "format_valid",
                            "invalid_format",
                            "could_not_validate",
                            "not_applicable"
                          ],
                          "description": "법인 등기부 제출 시 VAT 번호 또는 없는 경우 `tax_number`를 검증한 결과입니다. `valid` / `invalid`: 해당 국가의 공식 등기소(EU VIES, 노르웨이, 스위스, 브라질, 콜롬비아, 코스타리카, 에콰도르, 파라과이, 폴란드의 경우 국내 VAT 등록부 포함)에서 결정됩니다. `format_valid` / `invalid_format`: 등기소 조회가 불가능한 경우 해당 국가의 서식 및 체크 디지트 규칙에 따라 결정됩니다. `could_not_validate`: 등기소를 사용할 수 없습니다. `not_applicable`: 번호가 없거나, 등기소나 규칙이 없는 국가이거나, 샌드박스 세션인 경우입니다."
                        },
                        "vat_validated_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "출처가 인식하는 확인된 번호입니다(예: 프랑스 SIREN 또는 네덜란드 RSIN에서 파생된 VAT 번호). 확인이 실행되지 않은 경우 `null`입니다."
                        },
                        "vat_validation_source": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "eu_vies",
                            "pl_vat_white_list",
                            "no_brreg",
                            "ch_uid_register",
                            "br_receita_federal",
                            "co_rues",
                            "cr_hacienda",
                            "ec_sri",
                            "py_dnit",
                            "format_rules",
                            null
                          ],
                          "description": "`vat_validation_status`를 결정한 소스(공식 등기소 또는 `format_rules`)입니다. 검사가 실행되지 않은 경우 `null`입니다."
                        },
                        "vat_validated_name": {
                          "type": "string",
                          "nullable": true,
                          "description": "해당 번호를 검증한 소스에 등록된 이름(소스를 통해 공개된 경우). 상태가 `valid`인 경우에만 설정됩니다."
                        },
                        "vat_validated_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "번호를 검증한 출처에 등록된 주소(출처에서 제공하는 경우)입니다. 상태가 `valid`일 때만 설정됩니다."
                        },
                        "vat_checked_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "검사의 타임스탬프입니다. 검사가 실행되지 않은 경우 `null`입니다."
                        },
                        "financial_summary": {
                          "type": "object",
                          "nullable": true,
                          "description": "제공되는 경우, 법인 등기부에 보고된 주식/자본 세부 정보(통화, 총 주식 수, 주식 클래스)입니다."
                        },
                        "officers": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "uuid": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "name": {
                                "type": "string",
                                "example": "MELISSA BETHELL"
                              },
                              "designation": {
                                "type": "string",
                                "nullable": true,
                                "description": "원시 등기 직함(예: `Director`, `Secretary`)입니다."
                              },
                              "role": {
                                "type": "string",
                                "description": "직함에서 파생된 정규화된 역할입니다. 17개 값으로 구성된 전체 모델 세트이며, 이 endpoint의 등기부 파싱은 일반적으로 director, non_executive_director, secretary, chairman 또는 company_officer를 내보냅니다.",
                                "enum": [
                                  "director",
                                  "non_executive_director",
                                  "secretary",
                                  "chairman",
                                  "ubo",
                                  "shareholder",
                                  "representative",
                                  "founder",
                                  "legal_advisor",
                                  "authorized_signatory",
                                  "trustee",
                                  "beneficiary",
                                  "company_officer",
                                  "settlor",
                                  "protector",
                                  "investor",
                                  "other"
                                ]
                              },
                              "nationality": {
                                "type": "string",
                                "nullable": true
                              },
                              "is_active": {
                                "type": "boolean",
                                "description": "등기소에서 해당 임명이 사임한 것으로 표시된 경우 `false`."
                              },
                              "kyc_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "Approved",
                                  "Declined",
                                  "Pending",
                                  null
                                ],
                                "description": "이 임원에 대해 연결된 KYC 세션이 시작된 경우 해당 세션의 상태입니다. 그렇지 않은 경우 `null`입니다."
                              },
                              "kyc_session_url": {
                                "type": "string",
                                "nullable": true,
                                "description": "연결된 KYC 세션이 존재하는 경우 해당 세션의 인증 URL입니다."
                              },
                              "first_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "등기소에서 명시적으로 보고한 경우의 이름입니다. 성명에서 유추되지 않습니다."
                              },
                              "last_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "등기소에서 명시적으로 보고한 경우의 성입니다."
                              },
                              "address": {
                                "type": "string",
                                "nullable": true,
                                "description": "등기부에서 보고된 임원 주소입니다."
                              },
                              "appointment_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "임원이 선임된 날짜입니다.",
                                "format": "date"
                              },
                              "termination_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "보고된 경우 선임 종료일입니다.",
                                "format": "date"
                              },
                              "date_of_birth": {
                                "type": "string",
                                "nullable": true,
                                "description": "법인 등기부에 보고된 전체 생년월일입니다. 출생 연도 또는 월만 알려진 경우 null입니다.",
                                "format": "date"
                              },
                              "date_of_birth_year": {
                                "type": "integer",
                                "nullable": true,
                                "minimum": 1,
                                "maximum": 9999,
                                "description": "전체 날짜를 알 수 없는 경우를 포함하여, 법인 등기부에 보고된 출생 연도입니다."
                              },
                              "date_of_birth_month": {
                                "type": "integer",
                                "nullable": true,
                                "minimum": 1,
                                "maximum": 12,
                                "description": "법인 등기부에 보고된 출생 월입니다. 연도만 알려진 경우 null입니다."
                              }
                            }
                          },
                          "description": "등기부에서 추출된 이사, 비서 및 기타 임원입니다."
                        },
                        "beneficial_owners": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "uuid": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "name": {
                                "type": "string"
                              },
                              "first_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "last_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "entity_type": {
                                "type": "string",
                                "enum": [
                                  "person",
                                  "company"
                                ],
                                "description": "소유자가 자연인인지 법인인지 여부입니다."
                              },
                              "roles": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "정규화된 역할입니다(예: `ubo`, `shareholder`)."
                              },
                              "ownership_min_shares": {
                                "type": "string",
                                "nullable": true,
                                "description": "등기소에서 보고한 소유 지분 구간의 하한값(예: `25%`)."
                              },
                              "ownership_max_shares": {
                                "type": "string",
                                "nullable": true,
                                "description": "법인 등기부에서 보고한 소유 구조 구간의 상한선입니다."
                              },
                              "is_active": {
                                "type": "boolean"
                              },
                              "kyc_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "Approved",
                                  "Declined",
                                  "Pending",
                                  null
                                ]
                              },
                              "kyc_session_url": {
                                "type": "string",
                                "nullable": true
                              },
                              "effective_ownership_percent": {
                                "type": "number",
                                "nullable": true,
                                "description": "파싱된 소유 구조 백분율입니다(최댓값을 사용하고, 최댓값이 없으면 최솟값을 사용합니다)."
                              },
                              "company_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "registration_number": {
                                "type": "string",
                                "nullable": true
                              },
                              "country_of_birth": {
                                "type": "string",
                                "nullable": true
                              },
                              "email": {
                                "type": "string",
                                "nullable": true
                              },
                              "nationality": {
                                "type": "string",
                                "nullable": true
                              },
                              "designation": {
                                "type": "string",
                                "nullable": true
                              },
                              "voting_min_shares": {
                                "type": "string",
                                "nullable": true
                              },
                              "voting_max_shares": {
                                "type": "string",
                                "nullable": true
                              },
                              "date_of_birth": {
                                "type": "string",
                                "nullable": true,
                                "description": "보고된 전체 생년월일입니다.",
                                "format": "date"
                              },
                              "appointment_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "신고된 선임일입니다.",
                                "format": "date"
                              },
                              "shareholding": {
                                "$ref": "#/components/schemas/KYBRegistryShareholding"
                              }
                            }
                          },
                          "description": "등기부에서 추출한 실소유자 / 중대한 지배력을 가진 자입니다. 등기부에서 소유 구조를 공개하지 않는 경우 비어 있을 수 있습니다."
                        },
                        "addresses": {
                          "type": "array",
                          "nullable": true,
                          "description": "등기부에 기재된 모든 주소의 표준 형식입니다. 기재된 내용이 없으면 null입니다.",
                          "items": {
                            "$ref": "#/components/schemas/KYBRegistryAddress"
                          }
                        },
                        "industries": {
                          "type": "array",
                          "nullable": true,
                          "description": "등기부에서 기업을 분류하는 표준 형태의 활동입니다. 명시된 활동이 없는 경우 null입니다.",
                          "items": {
                            "$ref": "#/components/schemas/KYBRegistryIndustry"
                          }
                        },
                        "accounts": {
                          "type": "object",
                          "nullable": true,
                          "additionalProperties": true,
                          "description": "제공되는 경우 법인 등기부 제출 날짜입니다. 연차 보고서 및 주주총회에는 last_annual_return_date 및 last_agm_date를 사용하며, 재무제표와는 구별됩니다."
                        },
                        "registry_data": {
                          "$ref": "#/components/schemas/KYBRegistryData"
                        },
                        "user_provided_data": {
                          "type": "object",
                          "nullable": true,
                          "description": "이 endpoint에서는 항상 `null`입니다(최종 사용자가 등기부 데이터를 편집할 때 호스팅 KYB 워크플로에서 사용됨)."
                        },
                        "confirmed_by_user_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "이 endpoint에서는 항상 `null`입니다."
                        },
                        "last_console_edit_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "콘솔 검토자가 나중에 기록을 수정할 때 설정됩니다."
                        },
                        "is_editable": {
                          "type": "boolean",
                          "description": "법인 등기부에서 가져온 데이터를 호스팅된 플로우/콘솔에서 계속 수정할 수 있는지 여부입니다."
                        },
                        "registry_tier_delivered": {
                          "type": "string",
                          "enum": [
                            "basic",
                            "shareholders",
                            "ubo",
                            null
                          ],
                          "description": "최상위 `registry_tier_delivered`와 동일합니다.",
                          "nullable": true
                        },
                        "registry_ownership_status": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "not_requested",
                            "delivered",
                            "not_held",
                            "unavailable",
                            "pending",
                            null
                          ],
                          "description": "소유 구조 데이터가 반환된 경우 `delivered`, 소유 구조 등기소가 응답했으나 이 기업이 등재되어 있지 않은 경우 `not_held`(`registry_data.ownership_error` 참조), 소유 구조 등급을 요청했으나 등기소에 해당 기업의 데이터가 없거나 조회를 요청할 수 없는 경우 `unavailable`(`registry_data.ownership_error` 참조), 등기소에서 소유 구조 섹션을 아직 가져오지 못해 Didit이 완료 중인 경우 `pending`, Lite 등급인 경우 `not_requested`."
                        },
                        "ownership": {
                          "$ref": "#/components/schemas/KYBRegistryOwnership"
                        },
                        "registry_tier": {
                          "type": "string",
                          "nullable": true,
                          "description": "워크플로가 주문한 등기소 등급(`basic`, `shareholders` 또는 `ubo`)입니다. `ownership.tier_requested`에도 포함됩니다."
                        },
                        "registry_monitoring": {
                          "type": "object",
                          "nullable": true,
                          "description": "기업의 최신 등기부 모니터링 정보 또는 존재하지 않는 경우 `null`입니다.",
                          "properties": {
                            "uuid": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "status": {
                              "type": "string"
                            },
                            "unavailable_reason": {
                              "type": "string",
                              "nullable": true
                            },
                            "enrolled_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "cancelled_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "last_bill_date": {
                              "type": "string",
                              "format": "date",
                              "nullable": true
                            },
                            "next_bill_date": {
                              "type": "string",
                              "format": "date",
                              "nullable": true
                            },
                            "last_event_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "events_count": {
                              "type": "integer"
                            },
                            "watched_fields": {
                              "description": "모니터가 감시하는 기업 필드입니다."
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "전송한 `vendor_data`의 에코 값입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "description": "전송한 `metadata`의 에코 값입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "Resolved company": {
                    "summary": "전체 등기부 프로필(간결성을 위해 임원 목록은 축약됨)",
                    "value": {
                      "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e",
                      "kyb_registry": {
                        "uuid": "f1e2d3c4-b5a6-4789-9c0d-1e2f3a4b5c6d",
                        "node_id": "feature_kyb_registry",
                        "status": "In Review",
                        "registry_status": "active",
                        "data_resolved": true,
                        "company_name": "Tesco PLC",
                        "registration_number": "00445790",
                        "country_code": "GB",
                        "region": "",
                        "company_type": "Public Limited Company",
                        "incorporation_date": "1947-11-27",
                        "registered_address": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA",
                        "tax_number": "GB412 8925 93",
                        "risk_level": "low risk",
                        "verification_status": "verified",
                        "is_from_registry": true,
                        "fetch_status": "resolved",
                        "alternative_names": "TESCO STORES (HOLDINGS) PUBLIC LIMITED COMPANY",
                        "nature_of_business": null,
                        "registered_capital": null,
                        "registered_capital_amount": null,
                        "registered_capital_currency": null,
                        "website": "https://www.tesco.com/",
                        "email": "customer.service@tesco.co.uk",
                        "phone": "03301231688",
                        "legal_entity_identifier": null,
                        "location_of_registration": null,
                        "financial_summary": {
                          "currency": "Pound (£)",
                          "total_number_of_shares": "8174378721",
                          "meta_detail": {
                            "Class_Of_Share": "Ordinary"
                          }
                        },
                        "officers": [
                          {
                            "uuid": "a1b2c3d4-e5f6-4789-9a0b-1c2d3e4f5a6b",
                            "name": "CHRISTOPHER JON TAYLOR",
                            "designation": "Secretary",
                            "role": "secretary",
                            "nationality": null,
                            "is_active": true,
                            "kyc_status": null,
                            "kyc_session_url": null
                          },
                          {
                            "uuid": "b2c3d4e5-f6a7-4890-8b1c-2d3e4f5a6b7c",
                            "name": "MELISSA BETHELL",
                            "designation": "Director",
                            "role": "director",
                            "nationality": "British",
                            "is_active": true,
                            "kyc_status": null,
                            "kyc_session_url": null
                          }
                        ],
                        "beneficial_owners": [],
                        "addresses": [
                          {
                            "address": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA",
                            "type": "legal_entity_registry_address",
                            "description": "registered office address"
                          }
                        ],
                        "industries": null,
                        "accounts": {
                          "last_account": "26 February 2025",
                          "next_account": "26 February 2026",
                          "due_by_date": "26 August 2026"
                        },
                        "registry_data": {},
                        "user_provided_data": null,
                        "confirmed_by_user_at": null,
                        "last_console_edit_at": null,
                        "is_editable": true
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:45:00.000000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 필드 수준 문제는 DRF의 표준 엔벨로프를 사용합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing kyb_response_id": {
                    "summary": "`kyb_response_id`는 필수 항목입니다.",
                    "value": {
                      "kyb_response_id": [
                        "This field is required."
                      ]
                    }
                  },
                  "save_api_request=false rejected": {
                    "summary": "선택 항목은 항상 지속됩니다",
                    "value": {
                      "save_api_request": [
                        "KYB registry select must be saved so billing and retrieval can be tracked."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었거나 호출한 조직의 잔액이 호출 비용을 충당할 수 없을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 키가 누락된 경우 `{\"detail\": ...}`과 함께 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 크레딧이 부족한 경우 어떠한 스크리닝이나 제공업체 호출도 진행되기 전에 `{\"error\": ...}`과 함께 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 호출 비용을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "보고서가 접수되었으며 아직 처리 중입니다. 보고서가 아직 준비 중인 경우 endpoint는 202 Accepted, kyb_registry.fetch_status=pending, registry_tier_delivered=null을 반환합니다. request_id를 유지하고 registry_checks[0].company.fetch_status가 해결될 때까지 GET /v3/session/{request_id}/decision/을 조회하십시오. Didit은 보고서를 자동으로 완료하고 준비가 완료되면 제공된 등급에 대해 요금을 청구합니다. 대기 중인 동안 구매를 반복하지 마십시오. 새로운 POST마다 별도의 요청이 생성됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/paths/~1v3~1kyb~1shareholders~1/post/responses/200/content/application~1json/schema"
                },
                "examples": {
                  "Pending (registry still resolving)": {
                    "summary": "소유 구조 보고서가 아직 처리 중입니다. 저장된 결정을 조회합니다.",
                    "value": {
                      "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e",
                      "kyb_registry": {
                        "uuid": "7c0a4f7e-2b1d-4f6a-9c3e-8d5b2a1f0e9d",
                        "node_id": "feature_kyb_registry",
                        "status": "Not Finished",
                        "registry_status": null,
                        "data_resolved": false,
                        "company_name": "Example Holdings Limited",
                        "registration_number": "12345678",
                        "country_code": "HK",
                        "region": null,
                        "company_type": null,
                        "incorporation_date": null,
                        "registered_address": null,
                        "tax_number": null,
                        "risk_level": null,
                        "verification_status": null,
                        "is_from_registry": true,
                        "fetch_status": "pending",
                        "alternative_names": null,
                        "nature_of_business": null,
                        "registered_capital": null,
                        "registered_capital_amount": null,
                        "registered_capital_currency": null,
                        "website": null,
                        "email": null,
                        "phone": null,
                        "legal_entity_identifier": null,
                        "location_of_registration": null,
                        "financial_summary": {},
                        "officers": [],
                        "beneficial_owners": [],
                        "addresses": null,
                        "industries": null,
                        "accounts": null,
                        "registry_data": {},
                        "user_provided_data": null,
                        "confirmed_by_user_at": null,
                        "last_console_edit_at": null,
                        "is_editable": true,
                        "registry_tier_delivered": null,
                        "registry_ownership_status": "pending"
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:45:00.000000+00:00",
                      "registry_tier_delivered": null,
                      "registry_tier_requested": "shareholders"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/kyb/ubo/": {
      "post": {
        "summary": "실소유자 정보가 포함된 KYB 등기부 기업(독립 실행형)",
        "operationId": "post_v3_kyb_ubo",
        "x-didit-sdk": {
          "resource": "kyb",
          "method": "list_ubos",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [],
        "description": "`POST /v3/kyb/search/`에서 반환된 후보 중 하나의 Lite 프로필, 직접 주주, **그리고 소유 구조 체인을 통해 파악된 최종 실소유자**(`registry_data.ubo_resolution`에 모기업 체인이 포함됨)를 조회합니다.\n\n**검색과의 매칭.** 동일한 애플리케이션의 검색에서 반환된 후보의 `kyb_response_id`를 그대로 전달하십시오. 구매하려는 등급(`POST /v3/kyb/search/`의 `tier`)으로 검색해야 합니다. 해당 등급을 제공하는 등기부 체인에서 검색이 실행되며, Lite 검색 결과가 비어 있다고 해서 등기부에 해당 기업이 없다는 증거는 아니기 때문입니다. 해당 국가의 소유 구조 데이터가 다른 등기부에 있는 경우, Didit은 추가 비용 없이 등록번호로 해당 등기부에서 기업을 다시 찾습니다.\n\n**결제.** 해당 국가의 UBO 요금으로 청구됩니다([KYB 등기부 요금](/ko/getting-started/kyb-registry-pricing) 참조). 제공되는 등급은 해당 국가 및 등기부에서 제공할 수 있는 최고 등급입니다. 분석된 보고서에서 자연인이 실소유자로 지정되지 않은 경우 주주(Shareholders) 등급이, 소유 구조 기록이 전혀 없는 경우 Lite 등급이 제공되며, `registry_tier_delivered`에 청구된 등급이 명시됩니다. 등기부 호출 전에 UBO 요금 기준으로 잔액을 확인합니다(부족 시 `403`).\n\n**지원 여부.** v3 전용입니다. 모든 호출은 기업 세션을 생성합니다(세션 ID는 `request_id`임).\n\n**대기 중인 보고서.** 보고서가 아직 준비 중이거나 소유 구조 섹션이 아직 등기부에서 조회되지 않은 경우, 엔드포인트는 202 Accepted, kyb_registry.fetch_status=pending, kyb_registry.registry_ownership_status=pending, registry_tier_delivered=null을 반환합니다. request_id를 보관하고 registry_checks[0].company.fetch_status가 해결될 때까지 GET /v3/session/{request_id}/decision/을 조회하십시오. Didit은 보고서를 자동으로 완료하고 준비가 완료되면 제공된 등급에 대해 요금을 청구합니다. 대기 중인 동안 구매를 반복하지 마십시오. 새로운 POST 호출마다 별도의 요청이 생성됩니다.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KYBRegistryCandidateRequest"
              },
              "example": {
                "kyb_response_id": "69aeeb95febb0f1704042259",
                "vendor_data": "company-1234"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/kyb/ubo/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"kyb_response_id\": \"69aeeb95febb0f1704042259\",\n    \"vendor_data\": \"company-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.kyb.list_ubos(\n    kyb_response_id=\"69aeeb95febb0f1704042259\",\n    vendor_data=\"company-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.kyb.listUbos({\n  kyb_response_id: \"69aeeb95febb0f1704042259\",\n  vendor_data: \"company-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.KYB.ListUBOs(ctx, didit.KYBRegistryCandidateRequest{\n\tKYBResponseID: \"69aeeb95febb0f1704042259\",\n\tVendorData:    didit.String(\"company-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.KYBRegistryCandidateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.kyb().listUbos(KYBRegistryCandidateRequest.builder()\n        .kybResponseId(\"69aeeb95febb0f1704042259\")\n        .vendorData(\"company-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->kyb->listUbos([\n    'kyb_response_id' => '69aeeb95febb0f1704042259',\n    'vendor_data' => 'company-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.kyb.list_ubos(\n  kyb_response_id: \"69aeeb95febb0f1704042259\",\n  vendor_data: \"company-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Kyb.ListUbosAsync(new KYBRegistryCandidateRequest\n{\n    KybResponseId = \"69aeeb95febb0f1704042259\",\n    VendorData = \"company-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "제공된 등급에 따라 반환되고 청구되는 기업 보고서입니다. 아직 준비 중인 소유 구조 보고서는 202를 반환할 수 있습니다. 저장된 결정을 조회하려면 request_id를 보관하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "이 조회에 대해 생성된 기업 세션의 Id입니다. 응답 이후 법인 등기부 조회가 완료되면 저장된 레코드(콘솔에서 확인 가능)가 계속 업데이트됩니다."
                    },
                    "registry_tier_requested": {
                      "type": "string",
                      "enum": [
                        "basic",
                        "shareholders",
                        "ubo"
                      ],
                      "description": "이 endpoint에서 판매하는 등급: select의 경우 `basic` (Lite), `shareholders`, `ubo`입니다."
                    },
                    "registry_tier_delivered": {
                      "type": "string",
                      "enum": [
                        "basic",
                        "shareholders",
                        "ubo",
                        null
                      ],
                      "description": "실제로 제공되어 결제 청구된 등급입니다. 해당 국가의 등기부에 소유 구조 데이터가 없거나, 등기부에 이 기업의 소유 구조 기록이 없거나, `ubo` 요청의 해결된 보고서에 실소유자로 지정된 자연인이 없는 경우 요청한 등급보다 낮아집니다.",
                      "nullable": true
                    },
                    "kyb_registry": {
                      "type": "object",
                      "description": "전체 등기부 기업 프로필입니다.",
                      "properties": {
                        "uuid": {
                          "type": "string",
                          "format": "uuid",
                          "description": "이 기업 레코드에 대한 Didit의 ID입니다."
                        },
                        "node_id": {
                          "type": "string",
                          "example": "feature_kyb_registry"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "Not Finished",
                            "Approved",
                            "Declined",
                            "In Review"
                          ],
                          "description": "법인 등기부 확인에 대한 Didit의 평가입니다(예: 기업이 등기부에서 활성 상태가 아니거나 소유 구조 데이터를 도출할 수 없는 경우 `In Review`)."
                        },
                        "registry_status": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "active",
                            "dissolved",
                            "deregistered",
                            "see full details",
                            "authorised",
                            "appointed representative",
                            "unauthorised",
                            "inactive",
                            "no longer authorised",
                            "closed",
                            "struck off",
                            null
                          ],
                          "description": "등기소에서 보고된 정규화된 기업 상태입니다."
                        },
                        "data_resolved": {
                          "type": "boolean",
                          "description": "등기소에서 전체 프로필을 반환하면 `true`입니다. 폴링 후에도 등기소에서 여전히 처리 중인 경우 `false`이며, 저장된 레코드는 등기소 처리가 완료되면 자동으로 완료됩니다."
                        },
                        "company_name": {
                          "type": "string",
                          "example": "Tesco PLC"
                        },
                        "registration_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "00445790"
                        },
                        "country_code": {
                          "type": "string",
                          "description": "ISO 3166-1 alpha-2.",
                          "example": "GB"
                        },
                        "region": {
                          "type": "string",
                          "nullable": true,
                          "description": "법인 등기부가 지역 단위인 경우 행정 구역 코드(예: `US-CA`의 경우 `CA`), 그렇지 않은 경우 비어 있습니다."
                        },
                        "company_type": {
                          "type": "string",
                          "nullable": true,
                          "example": "Public Limited Company"
                        },
                        "incorporation_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "1947-11-27"
                        },
                        "registered_address": {
                          "type": "string",
                          "nullable": true,
                          "example": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA"
                        },
                        "tax_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "GB412 8925 93"
                        },
                        "risk_level": {
                          "type": "string",
                          "nullable": true,
                          "description": "제공되는 경우, 법인 등기부에 보고된 위험 수준입니다."
                        },
                        "verification_status": {
                          "type": "string",
                          "enum": [
                            "verified",
                            "failed",
                            "unknown"
                          ],
                          "nullable": true,
                          "description": "관할 구역 간 검증 상태: 등기부 상태가 존속 상태(`active`)를 확정하는 경우 `verified`, 회사가 더 이상 존속하지 않음(예: `dissolved`)을 나타내는 경우 `failed`, 그 외의 경우 `unknown`입니다. 등기부에서 가져오지 않은 회사 및 선택이 아직 `pending` 상태인 동안에는 `null`입니다."
                        },
                        "is_from_registry": {
                          "type": "boolean",
                          "description": "이 endpoint의 경우 항상 `true`입니다. 프로필을 공식 등기부에서 조회했습니다."
                        },
                        "fetch_status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "resolved"
                          ],
                          "description": "법인 등기부 조회 라이프사이클입니다. `data_resolved`에 반영됩니다."
                        },
                        "alternative_names": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우, 텍스트 형태의 대체명, 상호명, 이전 명칭 또는 원어 기업명입니다."
                        },
                        "nature_of_business": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우의 업종 설명 또는 분류 코드입니다."
                        },
                        "registered_capital": {
                          "type": "string",
                          "nullable": true
                        },
                        "registered_capital_amount": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우, 문자열 형태의 십진수 금액입니다."
                        },
                        "registered_capital_currency": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우의 ISO 4217 코드입니다."
                        },
                        "website": {
                          "type": "string",
                          "nullable": true,
                          "example": "https://www.tesco.com/"
                        },
                        "email": {
                          "type": "string",
                          "nullable": true,
                          "example": "customer.service@tesco.co.uk"
                        },
                        "phone": {
                          "type": "string",
                          "nullable": true,
                          "example": "03301231688"
                        },
                        "legal_entity_identifier": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우의 LEI입니다."
                        },
                        "location_of_registration": {
                          "type": "string",
                          "nullable": true,
                          "description": "보고된 경우, 기업이 등록된 법인 등기부/관할 구역입니다."
                        },
                        "vat_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "호스팅 법인 등기부 단계에서 수집되었거나 이후 편집된 EU VAT 번호입니다. 선택 시점에는 일반적으로 아직 설정되지 않습니다. VAT 및 납세자 번호 검증은 최종 사용자가 호스팅 흐름에서 법인 등기부 단계를 제출할 때 실행됩니다."
                        },
                        "vat_validation_status": {
                          "type": "string",
                          "enum": [
                            "valid",
                            "invalid",
                            "format_valid",
                            "invalid_format",
                            "could_not_validate",
                            "not_applicable"
                          ],
                          "description": "법인 등기부 제출 시 VAT 번호 또는 없는 경우 `tax_number`를 검증한 결과입니다. `valid` / `invalid`: 해당 국가의 공식 등기소(EU VIES, 노르웨이, 스위스, 브라질, 콜롬비아, 코스타리카, 에콰도르, 파라과이, 폴란드의 경우 국내 VAT 등록부 포함)에서 결정됩니다. `format_valid` / `invalid_format`: 등기소 조회가 불가능한 경우 해당 국가의 서식 및 체크 디지트 규칙에 따라 결정됩니다. `could_not_validate`: 등기소를 사용할 수 없습니다. `not_applicable`: 번호가 없거나, 등기소나 규칙이 없는 국가이거나, 샌드박스 세션인 경우입니다."
                        },
                        "vat_validated_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "출처가 인식하는 확인된 번호입니다(예: 프랑스 SIREN 또는 네덜란드 RSIN에서 파생된 VAT 번호). 확인이 실행되지 않은 경우 `null`입니다."
                        },
                        "vat_validation_source": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "eu_vies",
                            "pl_vat_white_list",
                            "no_brreg",
                            "ch_uid_register",
                            "br_receita_federal",
                            "co_rues",
                            "cr_hacienda",
                            "ec_sri",
                            "py_dnit",
                            "format_rules",
                            null
                          ],
                          "description": "`vat_validation_status`를 결정한 소스(공식 등기소 또는 `format_rules`)입니다. 검사가 실행되지 않은 경우 `null`입니다."
                        },
                        "vat_validated_name": {
                          "type": "string",
                          "nullable": true,
                          "description": "해당 번호를 검증한 소스에 등록된 이름(소스를 통해 공개된 경우). 상태가 `valid`인 경우에만 설정됩니다."
                        },
                        "vat_validated_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "번호를 검증한 출처에 등록된 주소(출처에서 제공하는 경우)입니다. 상태가 `valid`일 때만 설정됩니다."
                        },
                        "vat_checked_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "검사의 타임스탬프입니다. 검사가 실행되지 않은 경우 `null`입니다."
                        },
                        "financial_summary": {
                          "type": "object",
                          "nullable": true,
                          "description": "제공되는 경우, 법인 등기부에 보고된 주식/자본 세부 정보(통화, 총 주식 수, 주식 클래스)입니다."
                        },
                        "officers": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "uuid": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "name": {
                                "type": "string",
                                "example": "MELISSA BETHELL"
                              },
                              "designation": {
                                "type": "string",
                                "nullable": true,
                                "description": "원시 등기 직함(예: `Director`, `Secretary`)입니다."
                              },
                              "role": {
                                "type": "string",
                                "description": "직함에서 파생된 정규화된 역할입니다. 17개 값으로 구성된 전체 모델 세트이며, 이 endpoint의 등기부 파싱은 일반적으로 director, non_executive_director, secretary, chairman 또는 company_officer를 내보냅니다.",
                                "enum": [
                                  "director",
                                  "non_executive_director",
                                  "secretary",
                                  "chairman",
                                  "ubo",
                                  "shareholder",
                                  "representative",
                                  "founder",
                                  "legal_advisor",
                                  "authorized_signatory",
                                  "trustee",
                                  "beneficiary",
                                  "company_officer",
                                  "settlor",
                                  "protector",
                                  "investor",
                                  "other"
                                ]
                              },
                              "nationality": {
                                "type": "string",
                                "nullable": true
                              },
                              "is_active": {
                                "type": "boolean",
                                "description": "등기소에서 해당 임명이 사임한 것으로 표시된 경우 `false`."
                              },
                              "kyc_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "Approved",
                                  "Declined",
                                  "Pending",
                                  null
                                ],
                                "description": "이 임원에 대해 연결된 KYC 세션이 시작된 경우 해당 세션의 상태입니다. 그렇지 않은 경우 `null`입니다."
                              },
                              "kyc_session_url": {
                                "type": "string",
                                "nullable": true,
                                "description": "연결된 KYC 세션이 존재하는 경우 해당 세션의 인증 URL입니다."
                              },
                              "first_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "등기소에서 명시적으로 보고한 경우의 이름입니다. 성명에서 유추되지 않습니다."
                              },
                              "last_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "등기소에서 명시적으로 보고한 경우의 성입니다."
                              },
                              "address": {
                                "type": "string",
                                "nullable": true,
                                "description": "등기부에서 보고된 임원 주소입니다."
                              },
                              "appointment_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "임원이 선임된 날짜입니다.",
                                "format": "date"
                              },
                              "termination_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "보고된 경우 선임 종료일입니다.",
                                "format": "date"
                              },
                              "date_of_birth": {
                                "type": "string",
                                "nullable": true,
                                "description": "법인 등기부에 보고된 전체 생년월일입니다. 출생 연도 또는 월만 알려진 경우 null입니다.",
                                "format": "date"
                              },
                              "date_of_birth_year": {
                                "type": "integer",
                                "nullable": true,
                                "minimum": 1,
                                "maximum": 9999,
                                "description": "전체 날짜를 알 수 없는 경우를 포함하여, 법인 등기부에 보고된 출생 연도입니다."
                              },
                              "date_of_birth_month": {
                                "type": "integer",
                                "nullable": true,
                                "minimum": 1,
                                "maximum": 12,
                                "description": "법인 등기부에 보고된 출생 월입니다. 연도만 알려진 경우 null입니다."
                              }
                            }
                          },
                          "description": "등기부에서 추출된 이사, 비서 및 기타 임원입니다."
                        },
                        "beneficial_owners": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "uuid": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "name": {
                                "type": "string"
                              },
                              "first_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "last_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "entity_type": {
                                "type": "string",
                                "enum": [
                                  "person",
                                  "company"
                                ],
                                "description": "소유자가 자연인인지 법인인지 여부입니다."
                              },
                              "roles": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "정규화된 역할입니다(예: `ubo`, `shareholder`)."
                              },
                              "ownership_min_shares": {
                                "type": "string",
                                "nullable": true,
                                "description": "등기소에서 보고한 소유 지분 구간의 하한값(예: `25%`)."
                              },
                              "ownership_max_shares": {
                                "type": "string",
                                "nullable": true,
                                "description": "법인 등기부에서 보고한 소유 구조 구간의 상한선입니다."
                              },
                              "is_active": {
                                "type": "boolean"
                              },
                              "kyc_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "Approved",
                                  "Declined",
                                  "Pending",
                                  null
                                ]
                              },
                              "kyc_session_url": {
                                "type": "string",
                                "nullable": true
                              },
                              "effective_ownership_percent": {
                                "type": "number",
                                "nullable": true,
                                "description": "파싱된 소유 구조 백분율입니다(최댓값을 사용하고, 최댓값이 없으면 최솟값을 사용합니다)."
                              },
                              "company_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "registration_number": {
                                "type": "string",
                                "nullable": true
                              },
                              "country_of_birth": {
                                "type": "string",
                                "nullable": true
                              },
                              "email": {
                                "type": "string",
                                "nullable": true
                              },
                              "nationality": {
                                "type": "string",
                                "nullable": true
                              },
                              "designation": {
                                "type": "string",
                                "nullable": true
                              },
                              "voting_min_shares": {
                                "type": "string",
                                "nullable": true
                              },
                              "voting_max_shares": {
                                "type": "string",
                                "nullable": true
                              },
                              "date_of_birth": {
                                "type": "string",
                                "nullable": true,
                                "description": "보고된 전체 생년월일입니다.",
                                "format": "date"
                              },
                              "appointment_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "신고된 선임일입니다.",
                                "format": "date"
                              },
                              "shareholding": {
                                "$ref": "#/components/schemas/KYBRegistryShareholding"
                              }
                            }
                          },
                          "description": "등기부에서 추출한 실소유자 / 중대한 지배력을 가진 자입니다. 등기부에서 소유 구조를 공개하지 않는 경우 비어 있을 수 있습니다."
                        },
                        "addresses": {
                          "type": "array",
                          "nullable": true,
                          "description": "등기부에 기재된 모든 주소의 표준 형식입니다. 기재된 내용이 없으면 null입니다.",
                          "items": {
                            "$ref": "#/components/schemas/KYBRegistryAddress"
                          }
                        },
                        "industries": {
                          "type": "array",
                          "nullable": true,
                          "description": "등기부에서 기업을 분류하는 표준 형태의 활동입니다. 명시된 활동이 없는 경우 null입니다.",
                          "items": {
                            "$ref": "#/components/schemas/KYBRegistryIndustry"
                          }
                        },
                        "accounts": {
                          "type": "object",
                          "nullable": true,
                          "additionalProperties": true,
                          "description": "제공되는 경우 법인 등기부 제출 날짜입니다. 연차 보고서 및 주주총회에는 last_annual_return_date 및 last_agm_date를 사용하며, 재무제표와는 구별됩니다."
                        },
                        "registry_data": {
                          "$ref": "#/components/schemas/KYBRegistryData"
                        },
                        "user_provided_data": {
                          "type": "object",
                          "nullable": true,
                          "description": "이 endpoint에서는 항상 `null`입니다(최종 사용자가 등기부 데이터를 편집할 때 호스팅 KYB 워크플로에서 사용됨)."
                        },
                        "confirmed_by_user_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "이 endpoint에서는 항상 `null`입니다."
                        },
                        "last_console_edit_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "콘솔 검토자가 나중에 기록을 수정할 때 설정됩니다."
                        },
                        "is_editable": {
                          "type": "boolean",
                          "description": "법인 등기부에서 가져온 데이터를 호스팅된 플로우/콘솔에서 계속 수정할 수 있는지 여부입니다."
                        },
                        "registry_tier_delivered": {
                          "type": "string",
                          "enum": [
                            "basic",
                            "shareholders",
                            "ubo",
                            null
                          ],
                          "description": "최상위 `registry_tier_delivered`와 동일합니다.",
                          "nullable": true
                        },
                        "registry_ownership_status": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "not_requested",
                            "delivered",
                            "not_held",
                            "unavailable",
                            "pending",
                            null
                          ],
                          "description": "소유 구조 데이터가 반환된 경우 `delivered`, 소유 구조 등기소가 응답했으나 이 기업이 등재되어 있지 않은 경우 `not_held`(`registry_data.ownership_error` 참조), 소유 구조 등급을 요청했으나 등기소에 해당 기업의 데이터가 없거나 조회를 요청할 수 없는 경우 `unavailable`(`registry_data.ownership_error` 참조), 등기소에서 소유 구조 섹션을 아직 가져오지 못해 Didit이 완료 중인 경우 `pending`, Lite 등급인 경우 `not_requested`."
                        },
                        "ownership": {
                          "$ref": "#/components/schemas/KYBRegistryOwnership"
                        },
                        "registry_tier": {
                          "type": "string",
                          "nullable": true,
                          "description": "워크플로가 주문한 등기소 등급(`basic`, `shareholders` 또는 `ubo`)입니다. `ownership.tier_requested`에도 포함됩니다."
                        },
                        "registry_monitoring": {
                          "type": "object",
                          "nullable": true,
                          "description": "기업의 최신 등기부 모니터링 정보 또는 존재하지 않는 경우 `null`입니다.",
                          "properties": {
                            "uuid": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "status": {
                              "type": "string"
                            },
                            "unavailable_reason": {
                              "type": "string",
                              "nullable": true
                            },
                            "enrolled_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "cancelled_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "last_bill_date": {
                              "type": "string",
                              "format": "date",
                              "nullable": true
                            },
                            "next_bill_date": {
                              "type": "string",
                              "format": "date",
                              "nullable": true
                            },
                            "last_event_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "events_count": {
                              "type": "integer"
                            },
                            "watched_fields": {
                              "description": "모니터가 감시하는 기업 필드입니다."
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "전송한 `vendor_data`의 에코 값입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "description": "전송한 `metadata`의 에코 값입니다."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "Resolved company": {
                    "summary": "전체 등기부 프로필(간결성을 위해 임원 목록은 축약됨)",
                    "value": {
                      "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e",
                      "kyb_registry": {
                        "uuid": "f1e2d3c4-b5a6-4789-9c0d-1e2f3a4b5c6d",
                        "node_id": "feature_kyb_registry",
                        "status": "In Review",
                        "registry_status": "active",
                        "data_resolved": true,
                        "company_name": "Tesco PLC",
                        "registration_number": "00445790",
                        "country_code": "GB",
                        "region": "",
                        "company_type": "Public Limited Company",
                        "incorporation_date": "1947-11-27",
                        "registered_address": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA",
                        "tax_number": "GB412 8925 93",
                        "risk_level": "low risk",
                        "verification_status": "verified",
                        "is_from_registry": true,
                        "fetch_status": "resolved",
                        "alternative_names": "TESCO STORES (HOLDINGS) PUBLIC LIMITED COMPANY",
                        "nature_of_business": null,
                        "registered_capital": null,
                        "registered_capital_amount": null,
                        "registered_capital_currency": null,
                        "website": "https://www.tesco.com/",
                        "email": "customer.service@tesco.co.uk",
                        "phone": "03301231688",
                        "legal_entity_identifier": null,
                        "location_of_registration": null,
                        "financial_summary": {
                          "currency": "Pound (£)",
                          "total_number_of_shares": "8174378721",
                          "meta_detail": {
                            "Class_Of_Share": "Ordinary"
                          }
                        },
                        "officers": [
                          {
                            "uuid": "a1b2c3d4-e5f6-4789-9a0b-1c2d3e4f5a6b",
                            "name": "CHRISTOPHER JON TAYLOR",
                            "designation": "Secretary",
                            "role": "secretary",
                            "nationality": null,
                            "is_active": true,
                            "kyc_status": null,
                            "kyc_session_url": null
                          },
                          {
                            "uuid": "b2c3d4e5-f6a7-4890-8b1c-2d3e4f5a6b7c",
                            "name": "MELISSA BETHELL",
                            "designation": "Director",
                            "role": "director",
                            "nationality": "British",
                            "is_active": true,
                            "kyc_status": null,
                            "kyc_session_url": null
                          }
                        ],
                        "beneficial_owners": [],
                        "addresses": [
                          {
                            "address": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA",
                            "type": "legal_entity_registry_address",
                            "description": "registered office address"
                          }
                        ],
                        "industries": null,
                        "accounts": {
                          "last_account": "26 February 2025",
                          "next_account": "26 February 2026",
                          "due_by_date": "26 August 2026"
                        },
                        "registry_data": {
                          "ubo_resolution": {
                            "parent_chain": [],
                            "subsidiaries": [],
                            "unresolved": []
                          }
                        },
                        "user_provided_data": null,
                        "confirmed_by_user_at": null,
                        "last_console_edit_at": null,
                        "is_editable": true
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:45:00.000000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 필드 수준 문제는 DRF의 표준 엔벨로프를 사용합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing kyb_response_id": {
                    "summary": "`kyb_response_id`는 필수 항목입니다.",
                    "value": {
                      "kyb_response_id": [
                        "This field is required."
                      ]
                    }
                  },
                  "save_api_request=false rejected": {
                    "summary": "선택 항목은 항상 지속됩니다",
                    "value": {
                      "save_api_request": [
                        "KYB registry select must be saved so billing and retrieval can be tracked."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "권한이 거부되었습니다. `x-api-key` 헤더가 누락되었거나 호출한 조직의 잔액이 호출 비용을 충당할 수 없을 때 반환됩니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 키가 누락된 경우 `{\"detail\": ...}`과 함께 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 크레딧이 부족한 경우 어떠한 스크리닝이나 제공업체 호출도 진행되기 전에 `{\"error\": ...}`과 함께 `403`을 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "조직 잔액이 호출 비용을 충당할 수 없습니다",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를 공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 응답에는 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가 포함됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "현재 분 동안 300건을 초과하는 쓰기 요청 발생",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "보고서가 접수되었으며 아직 처리 중입니다. 보고서가 아직 준비 중인 경우 endpoint는 202 Accepted, kyb_registry.fetch_status=pending, registry_tier_delivered=null을 반환합니다. request_id를 유지하고 registry_checks[0].company.fetch_status가 해결될 때까지 GET /v3/session/{request_id}/decision/을 조회하십시오. Didit은 보고서를 자동으로 완료하고 준비가 완료되면 제공된 등급에 대해 요금을 청구합니다. 대기 중인 동안 구매를 반복하지 마십시오. 새로운 POST마다 별도의 요청이 생성됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/paths/~1v3~1kyb~1ubo~1/post/responses/200/content/application~1json/schema"
                },
                "examples": {
                  "Pending (registry still resolving)": {
                    "summary": "소유 구조 보고서가 아직 처리 중입니다. 저장된 결정을 조회합니다.",
                    "value": {
                      "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e",
                      "kyb_registry": {
                        "uuid": "7c0a4f7e-2b1d-4f6a-9c3e-8d5b2a1f0e9d",
                        "node_id": "feature_kyb_registry",
                        "status": "Not Finished",
                        "registry_status": null,
                        "data_resolved": false,
                        "company_name": "Example Holdings Limited",
                        "registration_number": "12345678",
                        "country_code": "HK",
                        "region": null,
                        "company_type": null,
                        "incorporation_date": null,
                        "registered_address": null,
                        "tax_number": null,
                        "risk_level": null,
                        "verification_status": null,
                        "is_from_registry": true,
                        "fetch_status": "pending",
                        "alternative_names": null,
                        "nature_of_business": null,
                        "registered_capital": null,
                        "registered_capital_amount": null,
                        "registered_capital_currency": null,
                        "website": null,
                        "email": null,
                        "phone": null,
                        "legal_entity_identifier": null,
                        "location_of_registration": null,
                        "financial_summary": {},
                        "officers": [],
                        "beneficial_owners": [],
                        "addresses": null,
                        "industries": null,
                        "accounts": null,
                        "registry_data": {},
                        "user_provided_data": null,
                        "confirmed_by_user_at": null,
                        "last_console_edit_at": null,
                        "is_editable": true,
                        "registry_tier_delivered": null,
                        "registry_ownership_status": "pending"
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:45:00.000000+00:00",
                      "registry_tier_delivered": null,
                      "registry_tier_requested": "ubo"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/id-verification/wallets/": {
      "get": {
        "operationId": "list_wallets",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "description": "각 디지털 ID 지갑의 시작 endpoint, 국가, 필수 필드 및 현재 이 환경에서 애플리케이션이 시작할 수 있는지 여부입니다. 목록에 표시되어 있다고 해서 활성 상태임을 의미하지는 않습니다.",
        "summary": "디지털 신분증 지갑 목록 조회",
        "tags": [
          "Digital ID wallets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletCatalogResponse"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": "자격 증명(x-api-key 또는 Authorization: Bearer)이 누락되었습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request GET \\\n  --url https://verification.didit.me/v3/id-verification/wallets/ \\\n  --header 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.list()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.list();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.List(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().list();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->list();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.list\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.ListAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/id-verification/wallets/verifications/{request_id}/": {
      "get": {
        "operationId": "get_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "retrieve_verification",
          "auth": "api_key",
          "server": true
        },
        "description": "지갑 인증의 상태 및 결과: 인증된 경우 표준화된 신원 및 지갑 자체의 속성, 거부된 경우 오류 코드, 대기 중인 경우 다음 작업입니다. expires_at이 지난 인증은 시간 초과로 결정됩니다.",
        "summary": "지갑 인증 조회",
        "parameters": [
          {
            "in": "path",
            "name": "request_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "start endpoint가 반환한 request_id입니다.",
            "required": true
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "ftn",
                      "name": "Finnish Trust Network",
                      "issuing_authority": "Finnish banks and mobile operators (FTN)"
                    },
                    "country": "FIN",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": "자격 증명(x-api-key 또는 Authorization: Bearer)이 누락되었습니다."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 not_found: 이 애플리케이션의 어떤 지갑 인증에도 이 request_id가 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request GET \\\n  --url https://verification.didit.me/v3/id-verification/wallets/verifications/REQUEST_ID/ \\\n  --header 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.retrieve_verification(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.retrieveVerification(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.RetrieveVerification(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().retrieveVerification(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->retrieveVerification('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.retrieve_verification(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.RetrieveVerificationAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/id-verification/wallets/verifications/{request_id}/poll/": {
      "post": {
        "operationId": "poll_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "poll_verification",
          "auth": "api_key",
          "server": true
        },
        "description": "Smart-ID 및 Mobile-ID: 사용자가 확인했는지, 거부했는지, 아니면 프롬프트가 만료되도록 두었는지 제공자에게 묻고, 확인한 경우 서명된 신원을 검증합니다. 리디렉션 지갑은 사용자의 브라우저를 통해 완료되므로 이 작업에서는 검증 결과를 다시 읽기만 합니다. 완료된 후의 인증 상태를 응답합니다.",
        "summary": "지갑 인증 폴링",
        "parameters": [
          {
            "in": "path",
            "name": "request_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "start endpoint가 반환한 request_id입니다.",
            "required": true
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "smart_id",
                      "name": "Smart-ID",
                      "issuing_authority": "SK ID Solutions"
                    },
                    "country": "EST",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "in_app",
                    "simulated": true,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "confirm_in_app",
                      "verification_code": "1234",
                      "poll_interval_seconds": 2
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": "자격 증명(x-api-key 또는 Authorization: Bearer)이 누락되었습니다."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 not_found: 이 애플리케이션의 어떤 지갑 인증에도 이 request_id가 없습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/verifications/REQUEST_ID/poll/ \\\n  --header 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.poll_verification(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.pollVerification(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.PollVerification(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().pollVerification(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->pollVerification('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.poll_verification(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.PollVerificationAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/id-verification/wallets/verifications/{request_id}/cancel/": {
      "post": {
        "operationId": "cancel_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "cancel_verification",
          "auth": "api_key",
          "server": true
        },
        "description": "대기 중인 인증을 철회합니다: 취소됨으로 거부되며 결제되지 않습니다. 이미 결정된 인증은 변경 없이 반환됩니다. Smart-ID 및 Mobile-ID: 로그인을 폴링으로 확인하는 중에 취소 요청이 도착하면 해당 폴링을 몇 초 동안 기다린 후 거부하거나, 사용자가 이미 확인한 경우에는 인증됨으로 반환합니다. 사용자가 지금 완료 중인 인증은 취소할 수 없습니다(Retry-After가 포함된 409 verification_in_progress). 해당 시간(초)이 지난 후 재시도하여 결과를 확인하세요.",
        "summary": "지갑 인증 취소",
        "parameters": [
          {
            "in": "path",
            "name": "request_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "start endpoint가 반환한 request_id입니다.",
            "required": true
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "ftn",
                      "name": "Finnish Trust Network",
                      "issuing_authority": "Finnish banks and mobile operators (FTN)"
                    },
                    "country": "FIN",
                    "status": "Declined",
                    "outcome": "cancelled",
                    "error": "cancelled_by_customer",
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": null,
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": "자격 증명(x-api-key 또는 Authorization: Bearer)이 누락되었습니다."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 not_found: 이 애플리케이션의 어떤 지갑 인증에도 이 request_id가 없습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 verification_in_progress: 사용자가 현재 이 로그인을 완료하고 있습니다. Retry-After 헤더는 재시도 시점을 나타냅니다. 재시도 시 결정된 인증이 반환됩니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/verifications/REQUEST_ID/cancel/ \\\n  --header 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.cancel_verification(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.cancelVerification(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.CancelVerification(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().cancelVerification(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->cancelVerification('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.cancel_verification(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.CancelVerificationAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/id-verification/wallets/mitid/": {
      "post": {
        "operationId": "start_mitid_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_mitid",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 MitID 로그인(덴마크 디지털정부청; DNK)을 시작합니다. 신원이 인증된 경우에만 1회 결제됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL과 함께 next_action.type=redirect가 포함됩니다. 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 공급자에게 연결되지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "MitID 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMitidWalletVerificationStartRequest"
              },
              "example": {
                "country": "DNK",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMitidWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMitidWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "mitid",
                      "name": "MitID",
                      "issuing_authority": "Danish Agency for Digital Government"
                    },
                    "country": "DNK",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/mitid/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"DNK\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_mitid(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"DNK\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startMitid({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"DNK\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartMitid(ctx, didit.IDWalletsStartMitidParams{\n\tBody: didit.DigitalIDWalletAPIMitidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIMitidWalletVerificationStartCountryEnum(\"DNK\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiMitidWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiMitidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startMitid(DigitalIdWalletApiMitidWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiMitidWalletVerificationStartCountryEnum.of(\"DNK\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startMitid([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'DNK',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_mitid(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"DNK\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartMitidAsync(new DigitalIdWalletApiMitidWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiMitidWalletVerificationStartCountryEnum(\"DNK\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "mitid"
      }
    },
    "/v3/id-verification/wallets/bankid-se/": {
      "post": {
        "operationId": "start_bankid_se_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_bankid_se",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 BankID(SWE) 로그인(Finansiell ID-Teknik / bank consortium; SWE)을 시작합니다. 신원이 인증된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL과 함께 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 절대 URL에서 확인하지 말고 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인하십시오. 샌드박스 애플리케이션은 공급자에게 연결하지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "BankID (SWE) 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidSeWalletVerificationStartRequest"
              },
              "example": {
                "country": "SWE",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidSeWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidSeWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "bankid_se",
                      "name": "BankID",
                      "issuing_authority": "Finansiell ID-Teknik / bank consortium"
                    },
                    "country": "SWE",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/bankid-se/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"SWE\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_bankid_se(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"SWE\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startBankidSe({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"SWE\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartBankidSe(ctx, didit.IDWalletsStartBankidSeParams{\n\tBody: didit.DigitalIDWalletAPIBankidSeWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryEe9enum(\"SWE\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiBankidSeWalletVerificationStartRequest;\nimport me.didit.types.DigitalIdWalletApiCountryEe9Enum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startBankidSe(DigitalIdWalletApiBankidSeWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryEe9Enum.of(\"SWE\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startBankidSe([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'SWE',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_bankid_se(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"SWE\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartBankidSeAsync(new DigitalIdWalletApiBankidSeWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryEe9Enum(\"SWE\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "bankid_se"
      }
    },
    "/v3/id-verification/wallets/bankid-no/": {
      "post": {
        "operationId": "start_bankid_no_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_bankid_no",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 BankID(NOR) 로그인(BankID BankAxept AS; NOR)을 시작합니다. 신원이 인증된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL과 함께 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 절대 URL에서 확인하지 말고 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인하십시오. 샌드박스 애플리케이션은 공급자에게 연결하지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "BankID (NOR) 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidNoWalletVerificationStartRequest"
              },
              "example": {
                "country": "NOR",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidNoWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidNoWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "bankid_no",
                      "name": "BankID",
                      "issuing_authority": "BankID BankAxept AS"
                    },
                    "country": "NOR",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/bankid-no/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"NOR\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_bankid_no(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"NOR\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startBankidNo({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NOR\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartBankidNo(ctx, didit.IDWalletsStartBankidNoParams{\n\tBody: didit.DigitalIDWalletAPIBankidNoWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryAfcEnum(\"NOR\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiBankidNoWalletVerificationStartRequest;\nimport me.didit.types.DigitalIdWalletApiCountryAfcEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startBankidNo(DigitalIdWalletApiBankidNoWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryAfcEnum.of(\"NOR\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startBankidNo([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'NOR',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_bankid_no(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NOR\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartBankidNoAsync(new DigitalIdWalletApiBankidNoWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryAfcEnum(\"NOR\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "bankid_no"
      }
    },
    "/v3/id-verification/wallets/vipps/": {
      "post": {
        "operationId": "start_vipps_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_vipps",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 Vipps 로그인(Vipps MobilePay / BankID NO; NOR)을 시작합니다. 신원이 확인된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL이 포함된 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 제공업체에 접속하지 않는 결정론적 시뮬레이션(simulated: true)을 수신합니다.",
        "summary": "Vipps 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiVippsWalletVerificationStartRequest"
              },
              "example": {
                "country": "NOR",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiVippsWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiVippsWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "vipps",
                      "name": "Vipps",
                      "issuing_authority": "Vipps MobilePay / BankID NO"
                    },
                    "country": "NOR",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/vipps/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"NOR\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_vipps(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"NOR\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startVipps({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NOR\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartVipps(ctx, didit.IDWalletsStartVippsParams{\n\tBody: didit.DigitalIDWalletAPIVippsWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryAfcEnum(\"NOR\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountryAfcEnum;\nimport me.didit.types.DigitalIdWalletApiVippsWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startVipps(DigitalIdWalletApiVippsWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryAfcEnum.of(\"NOR\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startVipps([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'NOR',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_vipps(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NOR\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartVippsAsync(new DigitalIdWalletApiVippsWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryAfcEnum(\"NOR\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "vipps"
      }
    },
    "/v3/id-verification/wallets/buypass/": {
      "post": {
        "operationId": "start_buypass_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_buypass",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 Buypass ID 로그인(Buypass AS; NOR)을 시작합니다. 신원이 인증된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL과 함께 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 절대 URL에서 확인하지 말고 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인하십시오. 샌드박스 애플리케이션은 공급자에게 연결하지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "Buypass ID 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBuypassWalletVerificationStartRequest"
              },
              "example": {
                "country": "NOR",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBuypassWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBuypassWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "buypass",
                      "name": "Buypass ID",
                      "issuing_authority": "Buypass AS"
                    },
                    "country": "NOR",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/buypass/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"NOR\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_buypass(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"NOR\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startBuypass({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NOR\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartBuypass(ctx, didit.IDWalletsStartBuypassParams{\n\tBody: didit.DigitalIDWalletAPIBuypassWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryAfcEnum(\"NOR\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiBuypassWalletVerificationStartRequest;\nimport me.didit.types.DigitalIdWalletApiCountryAfcEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startBuypass(DigitalIdWalletApiBuypassWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryAfcEnum.of(\"NOR\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startBuypass([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'NOR',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_buypass(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NOR\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartBuypassAsync(new DigitalIdWalletApiBuypassWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryAfcEnum(\"NOR\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "buypass"
      }
    },
    "/v3/id-verification/wallets/itsme/": {
      "post": {
        "operationId": "start_itsme_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_itsme",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 itsme 로그인(벨기에 모바일 ID; BEL, LUX, NLD)을 시작합니다. 신원이 확인된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL이 포함된 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 제공업체에 연결하지 않는 결정론적 시뮬레이션(simulated: true)을 수신합니다.",
        "summary": "itsme 인증을 시작합니다.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiItsmeWalletVerificationStartRequest"
              },
              "example": {
                "country": "BEL",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiItsmeWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiItsmeWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "itsme",
                      "name": "itsme",
                      "issuing_authority": "Belgian Mobile ID"
                    },
                    "country": "BEL",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/itsme/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"BEL\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_itsme(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"BEL\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startItsme({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"BEL\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartItsme(ctx, didit.IDWalletsStartItsmeParams{\n\tBody: didit.DigitalIDWalletAPIItsmeWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.DigitalIDWalletAPIItsmeWalletVerificationStartCountryEnum(\"BEL\"),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiItsmeWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiItsmeWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startItsme(DigitalIdWalletApiItsmeWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiItsmeWalletVerificationStartCountryEnum.of(\"BEL\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startItsme([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'BEL',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_itsme(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"BEL\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartItsmeAsync(new DigitalIdWalletApiItsmeWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = \"BEL\",\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "itsme"
      }
    },
    "/v3/id-verification/wallets/idin/": {
      "post": {
        "operationId": "start_idin_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_idin",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 iDIN 로그인(네덜란드 은행(Currence iDIN); NLD)을 시작합니다. 신원이 확인된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL이 포함된 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 제공업체에 연결하지 않는 결정론적 시뮬레이션(simulated: true)을 수신합니다.",
        "summary": "iDIN 인증을 시작합니다.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdinWalletVerificationStartRequest"
              },
              "example": {
                "country": "NLD",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdinWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdinWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "idin",
                      "name": "iDIN",
                      "issuing_authority": "Dutch banks (Currence iDIN)"
                    },
                    "country": "NLD",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/idin/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"NLD\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_idin(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"NLD\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startIdin({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NLD\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartIdin(ctx, didit.IDWalletsStartIdinParams{\n\tBody: didit.DigitalIDWalletAPIIdinWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIIdinWalletVerificationStartCountryEnum(\"NLD\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiIdinWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiIdinWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startIdin(DigitalIdWalletApiIdinWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiIdinWalletVerificationStartCountryEnum.of(\"NLD\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startIdin([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'NLD',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_idin(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NLD\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartIdinAsync(new DigitalIdWalletApiIdinWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiIdinWalletVerificationStartCountryEnum(\"NLD\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "idin"
      }
    },
    "/v3/id-verification/wallets/ftn/": {
      "post": {
        "operationId": "start_ftn_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_ftn",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 Finnish Trust Network 로그인(핀란드 은행 및 이동통신사(FTN); FIN)을 시작합니다. 신원이 인증된 경우에만 1회 결제됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL과 함께 next_action.type=redirect가 포함됩니다. 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 공급자에게 연결되지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "Finnish Trust Network 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFtnWalletVerificationStartRequest"
              },
              "example": {
                "country": "FIN",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFtnWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFtnWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "ftn",
                      "name": "Finnish Trust Network",
                      "issuing_authority": "Finnish banks and mobile operators (FTN)"
                    },
                    "country": "FIN",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/ftn/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"FIN\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_ftn(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"FIN\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startFtn({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"FIN\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartFtn(ctx, didit.IDWalletsStartFtnParams{\n\tBody: didit.DigitalIDWalletAPIFtnWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIFtnWalletVerificationStartCountryEnum(\"FIN\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiFtnWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiFtnWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startFtn(DigitalIdWalletApiFtnWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiFtnWalletVerificationStartCountryEnum.of(\"FIN\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startFtn([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'FIN',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_ftn(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"FIN\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartFtnAsync(new DigitalIdWalletApiFtnWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiFtnWalletVerificationStartCountryEnum(\"FIN\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "ftn"
      }
    },
    "/v3/id-verification/wallets/personalausweis/": {
      "post": {
        "operationId": "start_personalausweis_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_personalausweis",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 Personalausweis 로그인(Bundesministerium des Innern (eID); DEU)을 시작합니다. 신원이 확인된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL이 포함된 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 제공업체에 접속하지 않는 결정론적 시뮬레이션(simulated: true)을 수신합니다.",
        "summary": "Personalausweis 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest"
              },
              "example": {
                "country": "DEU",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "personalausweis",
                      "name": "Personalausweis",
                      "issuing_authority": "Bundesministerium des Innern (eID)"
                    },
                    "country": "DEU",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/personalausweis/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"DEU\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_personalausweis(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"DEU\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startPersonalausweis({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"DEU\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartPersonalausweis(ctx, didit.IDWalletsStartPersonalausweisParams{\n\tBody: didit.DigitalIDWalletAPIPersonalausweisWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIPersonalausweisWalletVerificationStartCountryEnum(\"DEU\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiPersonalausweisWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startPersonalausweis(DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiPersonalausweisWalletVerificationStartCountryEnum.of(\"DEU\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startPersonalausweis([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'DEU',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_personalausweis(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"DEU\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartPersonalausweisAsync(new DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiPersonalausweisWalletVerificationStartCountryEnum(\"DEU\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "personalausweis"
      }
    },
    "/v3/id-verification/wallets/frejaid/": {
      "post": {
        "operationId": "start_frejaid_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_frejaid",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 Freja eID 로그인(Freja eID Group; SWE)을 시작합니다. 신원이 인증된 경우에만 1회 결제됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL과 함께 next_action.type=redirect가 포함됩니다. 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 공급자에게 연결되지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "Freja eID 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFrejaidWalletVerificationStartRequest"
              },
              "example": {
                "country": "SWE",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFrejaidWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFrejaidWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "frejaid",
                      "name": "Freja eID",
                      "issuing_authority": "Freja eID Group"
                    },
                    "country": "SWE",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/frejaid/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"SWE\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_frejaid(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"SWE\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startFrejaid({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"SWE\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartFrejaid(ctx, didit.IDWalletsStartFrejaidParams{\n\tBody: didit.DigitalIDWalletAPIFrejaidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryEe9enum(\"SWE\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountryEe9Enum;\nimport me.didit.types.DigitalIdWalletApiFrejaidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startFrejaid(DigitalIdWalletApiFrejaidWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryEe9Enum.of(\"SWE\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startFrejaid([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'SWE',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_frejaid(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"SWE\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartFrejaidAsync(new DigitalIdWalletApiFrejaidWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryEe9Enum(\"SWE\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "frejaid"
      }
    },
    "/v3/id-verification/wallets/uae-pass/": {
      "post": {
        "operationId": "start_uae_pass_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_uae_pass",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 UAE PASS 로그인(UAE Digital Government Authority; ARE)을 시작합니다. 신원이 확인된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL이 포함된 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 제공업체에 접속하지 않는 결정론적 시뮬레이션(simulated: true)을 수신합니다.",
        "summary": "UAE PASS 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiUaePassWalletVerificationStartRequest"
              },
              "example": {
                "country": "ARE",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiUaePassWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiUaePassWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "uae_pass",
                      "name": "UAE PASS",
                      "issuing_authority": "UAE Digital Government Authority"
                    },
                    "country": "ARE",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/uae-pass/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"ARE\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_uae_pass(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"ARE\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startUaePass({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"ARE\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartUaePass(ctx, didit.IDWalletsStartUaePassParams{\n\tBody: didit.DigitalIDWalletAPIUaePassWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIUaePassWalletVerificationStartCountryEnum(\"ARE\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiUaePassWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiUaePassWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startUaePass(DigitalIdWalletApiUaePassWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiUaePassWalletVerificationStartCountryEnum.of(\"ARE\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startUaePass([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'ARE',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_uae_pass(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"ARE\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartUaePassAsync(new DigitalIdWalletApiUaePassWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiUaePassWalletVerificationStartCountryEnum(\"ARE\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "uae_pass"
      }
    },
    "/v3/id-verification/wallets/govbr/": {
      "post": {
        "operationId": "start_govbr_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_govbr",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 gov.br 로그인(Governo Federal do Brasil; BRA)을 시작합니다. 신원이 확인된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL이 포함된 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 제공업체에 접속하지 않는 결정론적 시뮬레이션(simulated: true)을 수신합니다.",
        "summary": "gov.br 인증을 시작합니다.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovbrWalletVerificationStartRequest"
              },
              "example": {
                "country": "BRA",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovbrWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovbrWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "govbr",
                      "name": "gov.br",
                      "issuing_authority": "Governo Federal do Brasil"
                    },
                    "country": "BRA",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/govbr/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"BRA\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_govbr(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"BRA\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startGovbr({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"BRA\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartGovbr(ctx, didit.IDWalletsStartGovbrParams{\n\tBody: didit.DigitalIDWalletAPIGovbrWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIGovbrWalletVerificationStartCountryEnum(\"BRA\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiGovbrWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startGovbr(DigitalIdWalletApiGovbrWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum.of(\"BRA\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startGovbr([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'BRA',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_govbr(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"BRA\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartGovbrAsync(new DigitalIdWalletApiGovbrWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum(\"BRA\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "govbr"
      }
    },
    "/v3/id-verification/wallets/oneid/": {
      "post": {
        "operationId": "start_oneid_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_oneid",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 OneID 로그인(OneID(영국 은행 인증 신원); GBR)을 시작합니다. 신원이 확인된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL이 포함된 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 제공업체에 접속하지 않는 결정론적 시뮬레이션(simulated: true)을 수신합니다.",
        "summary": "OneID 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiOneidWalletVerificationStartRequest"
              },
              "example": {
                "country": "GBR",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiOneidWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiOneidWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "oneid",
                      "name": "OneID",
                      "issuing_authority": "OneID (UK bank-verified identity)"
                    },
                    "country": "GBR",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/oneid/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"GBR\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_oneid(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"GBR\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startOneid({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"GBR\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartOneid(ctx, didit.IDWalletsStartOneidParams{\n\tBody: didit.DigitalIDWalletAPIOneidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountry520enum(\"GBR\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountry520Enum;\nimport me.didit.types.DigitalIdWalletApiOneidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startOneid(DigitalIdWalletApiOneidWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountry520Enum.of(\"GBR\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startOneid([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'GBR',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_oneid(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"GBR\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartOneidAsync(new DigitalIdWalletApiOneidWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountry520Enum(\"GBR\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "oneid"
      }
    },
    "/v3/id-verification/wallets/govuk-wallet/": {
      "post": {
        "operationId": "start_govuk_wallet_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_govuk_wallet",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 GOV.UK Wallet 로그인(영국 정부 디지털 서비스; GBR)을 시작합니다. 신원이 인증된 경우에만 1회 결제됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL과 함께 next_action.type=redirect가 포함됩니다. 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 공급자에게 연결되지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "GOV.UK Wallet 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovukWalletWalletVerificationStartRequest"
              },
              "example": {
                "country": "GBR",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovukWalletWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovukWalletWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "govuk_wallet",
                      "name": "GOV.UK Wallet",
                      "issuing_authority": "UK Government Digital Service"
                    },
                    "country": "GBR",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/govuk-wallet/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"GBR\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_govuk_wallet(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"GBR\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startGovukWallet({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"GBR\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartGovukWallet(ctx, didit.IDWalletsStartGovukWalletParams{\n\tBody: didit.DigitalIDWalletAPIGovukWalletWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountry520enum(\"GBR\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountry520Enum;\nimport me.didit.types.DigitalIdWalletApiGovukWalletWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startGovukWallet(DigitalIdWalletApiGovukWalletWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountry520Enum.of(\"GBR\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startGovukWallet([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'GBR',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_govuk_wallet(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"GBR\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartGovukWalletAsync(new DigitalIdWalletApiGovukWalletWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountry520Enum(\"GBR\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "govuk_wallet"
      }
    },
    "/v3/id-verification/wallets/smart-id/": {
      "post": {
        "operationId": "start_smart_id_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_smart_id",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 Smart-ID 로그인(SK ID Solutions; EST, LVA, LTU, BEL)을 시작합니다. 신원이 확인된 경우에만 1회 청구됩니다. 응답에는 사용자에게 표시할 비교 코드가 포함된 next_action.type=confirm_in_app이 전달되며, 사용자는 앱에서 이를 확인하고 PIN을 입력합니다(절대로 PIN을 수집하지 마십시오). poll_interval_seconds 간격으로 POST /v3/id-verification/wallets/verifications/{request_id}/poll/을 폴링하거나 webhook을 활용하십시오. Didit 역시 백그라운드에서 폴링을 수행합니다. 샌드박스 애플리케이션은 제공업체에 접속하지 않는 결정론적 시뮬레이션(simulated: true)을 수신합니다.",
        "summary": "Smart-ID 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiSmartIdWalletVerificationStartRequest"
              },
              "example": {
                "country": "EST",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "personal_code": "00000000000"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiSmartIdWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiSmartIdWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "smart_id",
                      "name": "Smart-ID",
                      "issuing_authority": "SK ID Solutions"
                    },
                    "country": "EST",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "in_app",
                    "simulated": true,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "confirm_in_app",
                      "verification_code": "1234",
                      "poll_interval_seconds": 2
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/smart-id/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"EST\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"personal_code\": \"00000000000\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_smart_id(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"EST\",\n    personal_code=\"00000000000\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startSmartId({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"EST\",\n  personal_code: \"00000000000\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartSmartID(ctx, didit.IDWalletsStartSmartIDParams{\n\tBody: didit.DigitalIDWalletAPISmartIDWalletVerificationStartRequest{\n\t\tVendorData:   didit.String(\"your-customer-reference\"),\n\t\tMetadata:     didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:      didit.DigitalIDWalletAPISmartIDWalletVerificationStartCountryEnum(\"EST\"),\n\t\tPersonalCode: \"00000000000\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiSmartIdWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiSmartIdWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startSmartId(DigitalIdWalletApiSmartIdWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiSmartIdWalletVerificationStartCountryEnum.of(\"EST\"))\n        .personalCode(\"00000000000\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startSmartId([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'EST',\n    'personal_code' => '00000000000',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_smart_id(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"EST\",\n  personal_code: \"00000000000\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartSmartIdAsync(new DigitalIdWalletApiSmartIdWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = \"EST\",\n    PersonalCode = \"00000000000\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "smart_id"
      }
    },
    "/v3/id-verification/wallets/mobile-id/": {
      "post": {
        "operationId": "start_mobile_id_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_mobile_id",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 Mobile-ID 로그인(SK ID Solutions 및 국가 이동통신사; EST, LTU)을 시작합니다. 신원이 인증된 경우에만 1회 결제됩니다. 응답에는 사용자에게 표시할 비교 코드와 함께 next_action.type=confirm_in_app이 포함됩니다. 사용자는 앱에서 이를 확인하고 PIN을 입력합니다(PIN을 직접 수집해서는 안 됩니다). poll_interval_seconds 간격마다 POST /v3/id-verification/wallets/verifications/{request_id}/poll/을 폴링하거나 webhook을 활용할 수 있습니다. Didit도 백그라운드에서 폴링을 수행합니다. 샌드박스 애플리케이션은 공급자에게 연결되지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "Mobile-ID 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMobileIdWalletVerificationStartRequest"
              },
              "example": {
                "country": "EST",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "personal_code": "00000000000",
                "phone_number": "+37200000000"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMobileIdWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMobileIdWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "mobile_id",
                      "name": "Mobile-ID",
                      "issuing_authority": "SK ID Solutions with the national mobile operators"
                    },
                    "country": "EST",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "in_app",
                    "simulated": true,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "confirm_in_app",
                      "verification_code": "1234",
                      "poll_interval_seconds": 2
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/mobile-id/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"EST\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"personal_code\": \"00000000000\",\n  \"phone_number\": \"+37200000000\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_mobile_id(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"EST\",\n    personal_code=\"00000000000\",\n    phone_number=\"+37200000000\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startMobileId({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"EST\",\n  personal_code: \"00000000000\",\n  phone_number: \"+37200000000\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartMobileID(ctx, didit.IDWalletsStartMobileIDParams{\n\tBody: didit.DigitalIDWalletAPIMobileIDWalletVerificationStartRequest{\n\t\tVendorData:   didit.String(\"your-customer-reference\"),\n\t\tMetadata:     didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:      didit.DigitalIDWalletAPIMobileIDWalletVerificationStartCountryEnum(\"EST\"),\n\t\tPersonalCode: \"00000000000\",\n\t\tPhoneNumber:  \"+37200000000\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiMobileIdWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiMobileIdWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startMobileId(DigitalIdWalletApiMobileIdWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiMobileIdWalletVerificationStartCountryEnum.of(\"EST\"))\n        .personalCode(\"00000000000\")\n        .phoneNumber(\"+37200000000\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startMobileId([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'EST',\n    'personal_code' => '00000000000',\n    'phone_number' => '+37200000000',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_mobile_id(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"EST\",\n  personal_code: \"00000000000\",\n  phone_number: \"+37200000000\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartMobileIdAsync(new DigitalIdWalletApiMobileIdWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = \"EST\",\n    PersonalCode = \"00000000000\",\n    PhoneNumber = \"+37200000000\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "mobile_id"
      }
    },
    "/v3/id-verification/wallets/idcard-ee/": {
      "post": {
        "operationId": "start_idcard_ee_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_idcard_ee",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 에스토니아 ID 카드 로그인(Police and Border Guard Board (Estonia); EST)을 시작합니다. 신원이 인증된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL과 함께 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 절대 URL에서 확인하지 말고 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인하십시오. 샌드박스 애플리케이션은 공급자에게 연결하지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "Estonian ID-card 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdcardEeWalletVerificationStartRequest"
              },
              "example": {
                "country": "EST",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdcardEeWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdcardEeWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "idcard_ee",
                      "name": "Estonian ID-card",
                      "issuing_authority": "Police and Border Guard Board (Estonia)"
                    },
                    "country": "EST",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/idcard-ee/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"EST\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_idcard_ee(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"EST\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startIdcardEe({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"EST\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartIdcardEe(ctx, didit.IDWalletsStartIdcardEeParams{\n\tBody: didit.DigitalIDWalletAPIIdcardEeWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIIdcardEeWalletVerificationStartCountryEnum(\"EST\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiIdcardEeWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startIdcardEe(DigitalIdWalletApiIdcardEeWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum.of(\"EST\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startIdcardEe([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'EST',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_idcard_ee(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"EST\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartIdcardEeAsync(new DigitalIdWalletApiIdcardEeWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum(\"EST\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "idcard_ee"
      }
    },
    "/v3/id-verification/wallets/eparaksts-mobile/": {
      "post": {
        "operationId": "start_eparaksts_mobile_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_eparaksts_mobile",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 eParaksts mobile 로그인(LVRTC(Latvian State Radio and Television Centre); LVA)을 시작합니다. 신원이 확인된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL이 포함된 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 제공업체에 접속하지 않는 결정론적 시뮬레이션(simulated: true)을 수신합니다.",
        "summary": "eParaksts 모바일 인증을 시작합니다.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest"
              },
              "example": {
                "country": "LVA",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "eparaksts_mobile",
                      "name": "eParaksts mobile",
                      "issuing_authority": "LVRTC (Latvian State Radio and Television Centre)"
                    },
                    "country": "LVA",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/eparaksts-mobile/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"LVA\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_eparaksts_mobile(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"LVA\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startEparakstsMobile({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"LVA\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartEparakstsMobile(ctx, didit.IDWalletsStartEparakstsMobileParams{\n\tBody: didit.DigitalIDWalletAPIEparakstsMobileWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIEparakstsMobileWalletVerificationStartCountryEnum(\"LVA\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiEparakstsMobileWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startEparakstsMobile(DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiEparakstsMobileWalletVerificationStartCountryEnum.of(\"LVA\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startEparakstsMobile([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'LVA',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_eparaksts_mobile(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"LVA\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartEparakstsMobileAsync(new DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiEparakstsMobileWalletVerificationStartCountryEnum(\"LVA\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "eparaksts_mobile"
      }
    },
    "/v3/id-verification/wallets/bankid-cz/": {
      "post": {
        "operationId": "start_bankid_cz_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_bankid_cz",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 Bank iD 로그인(Bankovní identita, a.s.; CZE)을 시작합니다. 신원이 인증된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저가 이동할 URL과 함께 next_action.type=redirect가 포함됩니다. 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook에서 확인하십시오. 샌드박스 애플리케이션은 공급자에게 전혀 연결하지 않는 결정론적 시뮬레이션(simulated: true)을 수신합니다.",
        "summary": "Bank iD 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidCzWalletVerificationStartRequest"
              },
              "example": {
                "country": "CZE",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidCzWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidCzWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "bankid_cz",
                      "name": "Bank iD",
                      "issuing_authority": "Bankovní identita, a.s."
                    },
                    "country": "CZE",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/bankid-cz/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"CZE\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_bankid_cz(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"CZE\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startBankidCz({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"CZE\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartBankidCz(ctx, didit.IDWalletsStartBankidCzParams{\n\tBody: didit.DigitalIDWalletAPIBankidCzWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryE2dEnum(\"CZE\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiBankidCzWalletVerificationStartRequest;\nimport me.didit.types.DigitalIdWalletApiCountryE2dEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startBankidCz(DigitalIdWalletApiBankidCzWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryE2dEnum.of(\"CZE\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startBankidCz([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'CZE',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_bankid_cz(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"CZE\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartBankidCzAsync(new DigitalIdWalletApiBankidCzWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryE2dEnum(\"CZE\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "bankid_cz"
      }
    },
    "/v3/id-verification/wallets/mojeid/": {
      "post": {
        "operationId": "start_mojeid_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_mojeid",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 MojeID 로그인(CZ.NIC; CZE)을 시작합니다. 신원이 확인된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL이 포함된 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 제공업체에 접속하지 않는 결정론적 시뮬레이션(simulated: true)을 수신합니다.",
        "summary": "MojeID 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMojeidWalletVerificationStartRequest"
              },
              "example": {
                "country": "CZE",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMojeidWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMojeidWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "mojeid",
                      "name": "MojeID",
                      "issuing_authority": "CZ.NIC"
                    },
                    "country": "CZE",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/mojeid/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"CZE\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_mojeid(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"CZE\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startMojeid({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"CZE\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartMojeid(ctx, didit.IDWalletsStartMojeidParams{\n\tBody: didit.DigitalIDWalletAPIMojeidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryE2dEnum(\"CZE\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountryE2dEnum;\nimport me.didit.types.DigitalIdWalletApiMojeidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startMojeid(DigitalIdWalletApiMojeidWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryE2dEnum.of(\"CZE\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startMojeid([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'CZE',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_mojeid(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"CZE\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartMojeidAsync(new DigitalIdWalletApiMojeidWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryE2dEnum(\"CZE\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "mojeid"
      }
    },
    "/v3/id-verification/wallets/diia/": {
      "post": {
        "operationId": "start_diia_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_diia",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 Diia 로그인(Ministry of Digital Transformation of Ukraine; UKR)을 시작합니다. 신원이 인증된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL과 함께 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 절대 URL에서 확인하지 말고 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인하십시오. 샌드박스 애플리케이션은 공급자에게 연결하지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "Diia 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiDiiaWalletVerificationStartRequest"
              },
              "example": {
                "country": "UKR",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiDiiaWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiDiiaWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "diia",
                      "name": "Diia",
                      "issuing_authority": "Ministry of Digital Transformation of Ukraine"
                    },
                    "country": "UKR",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/diia/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"UKR\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_diia(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"UKR\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startDiia({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"UKR\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartDiia(ctx, didit.IDWalletsStartDiiaParams{\n\tBody: didit.DigitalIDWalletAPIDiiaWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIDiiaWalletVerificationStartCountryEnum(\"UKR\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiDiiaWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiDiiaWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startDiia(DigitalIdWalletApiDiiaWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiDiiaWalletVerificationStartCountryEnum.of(\"UKR\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startDiia([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'UKR',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_diia(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"UKR\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartDiiaAsync(new DigitalIdWalletApiDiiaWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiDiiaWalletVerificationStartCountryEnum(\"UKR\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "diia"
      }
    },
    "/v3/id-verification/wallets/franceconnect/": {
      "post": {
        "operationId": "start_franceconnect_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_franceconnect",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 FranceConnect 로그인(DINUM(프랑스 정부); FRA)을 시작합니다. 신원이 인증된 경우에만 1회 결제됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL과 함께 next_action.type=redirect가 포함됩니다. 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인해야 합니다. 샌드박스 애플리케이션은 공급자에게 연결되지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "FranceConnect 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFranceconnectWalletVerificationStartRequest"
              },
              "example": {
                "country": "FRA",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFranceconnectWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFranceconnectWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "franceconnect",
                      "name": "FranceConnect",
                      "issuing_authority": "DINUM (French state)"
                    },
                    "country": "FRA",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/franceconnect/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"FRA\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_franceconnect(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"FRA\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startFranceconnect({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"FRA\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartFranceconnect(ctx, didit.IDWalletsStartFranceconnectParams{\n\tBody: didit.DigitalIDWalletAPIFranceconnectWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIFranceconnectWalletVerificationStartCountryEnum(\"FRA\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiFranceconnectWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startFranceconnect(DigitalIdWalletApiFranceconnectWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum.of(\"FRA\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startFranceconnect([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'FRA',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_franceconnect(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"FRA\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartFranceconnectAsync(new DigitalIdWalletApiFranceconnectWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum(\"FRA\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "franceconnect"
      }
    },
    "/v3/id-verification/wallets/audkenni/": {
      "post": {
        "operationId": "start_audkenni_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_audkenni",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 Auðkenni 로그인(Auðkenni(아이슬란드 전자 신분증); ISL)을 시작합니다. 신원이 인증된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저가 이동할 URL과 함께 next_action.type=redirect가 포함됩니다. 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 URL이 아닌 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook에서 확인하십시오. 샌드박스 애플리케이션은 공급자에게 전혀 연결하지 않는 결정론적 시뮬레이션(simulated: true)을 수신합니다.",
        "summary": "Auðkenni 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiAudkenniWalletVerificationStartRequest"
              },
              "example": {
                "country": "ISL",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiAudkenniWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiAudkenniWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "audkenni",
                      "name": "Auðkenni",
                      "issuing_authority": "Auðkenni (Icelandic electronic ID)"
                    },
                    "country": "ISL",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/audkenni/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"ISL\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_audkenni(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"ISL\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startAudkenni({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"ISL\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartAudkenni(ctx, didit.IDWalletsStartAudkenniParams{\n\tBody: didit.DigitalIDWalletAPIAudkenniWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIAudkenniWalletVerificationStartCountryEnum(\"ISL\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiAudkenniWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiAudkenniWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startAudkenni(DigitalIdWalletApiAudkenniWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiAudkenniWalletVerificationStartCountryEnum.of(\"ISL\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startAudkenni([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'ISL',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_audkenni(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"ISL\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartAudkenniAsync(new DigitalIdWalletApiAudkenniWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiAudkenniWalletVerificationStartCountryEnum(\"ISL\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "audkenni"
      }
    },
    "/v3/id-verification/wallets/connectid/": {
      "post": {
        "operationId": "start_connectid_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_connectid",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 ConnectID 로그인(Australian Payments Plus; AUS)을 시작합니다. 신원이 인증된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL과 함께 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 절대 URL에서 확인하지 말고 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인하십시오. 샌드박스 애플리케이션은 공급자에게 연결하지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "ConnectID 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiConnectidWalletVerificationStartRequest"
              },
              "example": {
                "country": "AUS",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiConnectidWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiConnectidWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "connectid",
                      "name": "ConnectID",
                      "issuing_authority": "Australian Payments Plus"
                    },
                    "country": "AUS",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/connectid/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"AUS\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_connectid(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"AUS\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startConnectid({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"AUS\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartConnectid(ctx, didit.IDWalletsStartConnectidParams{\n\tBody: didit.DigitalIDWalletAPIConnectidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIConnectidWalletVerificationStartCountryEnum(\"AUS\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiConnectidWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiConnectidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startConnectid(DigitalIdWalletApiConnectidWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiConnectidWalletVerificationStartCountryEnum.of(\"AUS\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startConnectid([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'AUS',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_connectid(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"AUS\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartConnectidAsync(new DigitalIdWalletApiConnectidWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiConnectidWalletVerificationStartCountryEnum(\"AUS\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "connectid"
      }
    },
    "/v3/id-verification/wallets/eudi/": {
      "post": {
        "operationId": "start_eudi_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_eudi",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 EUDI Wallet 로그인(사용자의 소속 회원국, 발급 기관은 국가마다 다름; AUT, BEL, BGR, HRV, CYP, CZE, DNK, EST, FIN, FRA, DEU, GRC, HUN, IRL, ITA, LVA, LTU, LUX, MLT, NLD, POL, PRT, ROU, SVK, SVN, ESP, SWE, ISL, LIE, NOR)을 시작합니다. 신원이 인증된 경우에만 1회 청구됩니다. 응답에는 사용자의 브라우저를 이동시킬 URL과 함께 next_action.type=redirect가 전달되며, 사용자는 request_id 및 result가 추가된 return_url로 돌아옵니다. 결과는 절대 URL에서 확인하지 말고 GET /v3/id-verification/wallets/verifications/{request_id}/ 또는 webhook을 통해 확인하십시오. 샌드박스 애플리케이션은 공급자에게 연결하지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "EUDI Wallet 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiEudiWalletVerificationStartRequest"
              },
              "example": {
                "country": "AUT",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiEudiWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiEudiWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "eudi",
                      "name": "EUDI Wallet",
                      "issuing_authority": "The user's own member state; the issuer differs per country"
                    },
                    "country": "AUT",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/eudi/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"AUT\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_eudi(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"AUT\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startEudi({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"AUT\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartEudi(ctx, didit.IDWalletsStartEudiParams{\n\tBody: didit.DigitalIDWalletAPIEudiWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.DigitalIDWalletAPIEudiWalletVerificationStartCountryEnum(\"AUT\"),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiEudiWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiEudiWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startEudi(DigitalIdWalletApiEudiWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiEudiWalletVerificationStartCountryEnum.of(\"AUT\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startEudi([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'AUT',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_eudi(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"AUT\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartEudiAsync(new DigitalIdWalletApiEudiWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = \"AUT\",\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "eudi"
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/teams/": {
      "get": {
        "summary": "검토 팀 목록 조회",
        "description": "요청된 애플리케이션에 대한 `list:cases` 권한이 필요합니다.",
        "operationId": "list_case_teams",
        "x-didit-sdk": {
          "resource": "cases.teams",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 1000000,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaseReviewTeam"
                      }
                    },
                    "count": {
                      "type": "integer",
                      "description": "일치하는 개수이며 최대 100개로 제한됩니다. 제한을 넘어 계속하려면 next를 따르십시오."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 입력입니다."
          },
          "403": {
            "description": "권한이 부족합니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.teams.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.teams.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Teams.ListAutoPaging(ctx, didit.CasesTeamsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().teams().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->teams->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.teams.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Teams.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "summary": "검토 팀 생성",
        "description": "요청된 애플리케이션에 대한 `write:cases` 권한이 필요합니다.",
        "operationId": "create_case_teams",
        "x-didit-sdk": {
          "resource": "cases.teams",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "responses": {
          "201": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseReviewTeam"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 입력입니다."
          },
          "403": {
            "description": "권한이 부족합니다."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseReviewTeamCreate"
              },
              "example": {
                "name": "AML analysts",
                "members": [
                  {
                    "user_id": "9a000000-0000-4000-8000-0000000000aa",
                    "capacity": 10
                  }
                ]
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.teams.create(\n    name=\"AML analysts\",\n    members=[{\n        \"user_id\": \"9a000000-0000-4000-8000-0000000000aa\",\n        \"capacity\": 10,\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.teams.create({\n  name: \"AML analysts\",\n  members: [{\n    user_id: \"9a000000-0000-4000-8000-0000000000aa\",\n    capacity: 10,\n  }],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Teams.Create(ctx, didit.CaseReviewTeamCreate{\n\tName: \"AML analysts\",\n\tMembers: []didit.CaseReviewTeamMemberParam{{\n\t\tUserID:   \"9a000000-0000-4000-8000-0000000000aa\",\n\t\tCapacity: didit.Int(10),\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CaseReviewTeamCreate;\nimport me.didit.types.CaseReviewTeamMember;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().teams().create(CaseReviewTeamCreate.builder()\n        .name(\"AML analysts\")\n        .members(List.of(CaseReviewTeamMember.builder()\n                .userId(\"9a000000-0000-4000-8000-0000000000aa\")\n                .capacity(10L)\n                .build()))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->teams->create([\n    'name' => 'AML analysts',\n    'members' => [[\n        'user_id' => '9a000000-0000-4000-8000-0000000000aa',\n        'capacity' => 10,\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.teams.create(\n  name: \"AML analysts\",\n  members: [{\n    user_id: \"9a000000-0000-4000-8000-0000000000aa\",\n    capacity: 10,\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Teams.CreateAsync(new CaseReviewTeamCreate\n{\n    Name = \"AML analysts\",\n    Members = new CaseReviewTeamMember[]\n    {\n        new()\n        {\n            UserId = \"9a000000-0000-4000-8000-0000000000aa\",\n            Capacity = 10,\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/fraud/checks/{check_id}/": {
      "get": {
        "operationId": "root_retrieve",
        "x-didit-sdk": {
          "resource": "fraud_checks",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "description": "`check_id`로 이전에 생성된 확인을 가져옵니다.",
        "summary": "사기 확인 조회",
        "parameters": [
          {
            "in": "path",
            "name": "check_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudCheckResponse"
                }
              }
            },
            "description": ""
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudClientCredentialsErrorMessage"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "Fraud Check"
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.fraud_checks.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.fraudChecks.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FraudChecks.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.fraudChecks().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->fraudChecks->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.fraud_checks.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FraudChecks.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/requests/": {
      "get": {
        "operationId": "organization_application_cases_requests_list",
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "결과를 정렬할 때 사용할 필드입니다.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "페이지당 반환할 결과 수입니다.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "description": "결과 반환을 시작할 초기 인덱스입니다.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingPaginatedCaseRequestList"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "이 호출자에게는 요청 또는 케이스를 사용할 수 없습니다."
          },
          "403": {
            "description": "호출자에게 필요한 케이스 권한이 없습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.requests.list(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.requests.list(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Requests.ListAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesRequestsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().requests().list(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->requests->list('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.requests.list(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Requests.ListAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "operationId": "organization_application_cases_requests_create",
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseRequestConfirmRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseRequestConfirmRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseRequestConfirmRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "404": {
            "description": "이 호출자에게는 요청 또는 케이스를 사용할 수 없습니다."
          },
          "403": {
            "description": "호출자에게 필요한 케이스 권한이 없습니다."
          },
          "400": {
            "description": "유효하지 않은 입력, 지원되지 않는 목적, 사용할 수 없는 인증된 연락처, 또는 기존의 변경 불가능한 응답입니다."
          },
          "409": {
            "description": "미리보기가 변경되었거나 만료되었습니다. 확인하기 전에 다시 미리보기를 진행하십시오."
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingCaseRequest"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "15분 이내에 서명된 미리보기를 정확히 확인하세요. 고정 템플릿과 케이스 대상자 소유의 OTP 인증된 연락처만 허용됩니다. 요청 ID는 재시도를 멱등하게 만듭니다. 전송은 대기열에 추가되며, SENT, SIMULATED, UNKNOWN은 서로 다른 결과입니다. 조치 가능한 요청은 케이스를 사용자 대기 중 상태로 설정합니다. 검토 업데이트는 상태를 변경하지 않은 채로 둡니다.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.create(\n    \"11111111-2222-3333-4444-555555555555\",\n    contact_id=\"11111111-2222-3333-4444-555555555555\",\n    purpose=\"identity_document\",\n    request_id=\"11111111-2222-3333-4444-555555555555\",\n    expires_at=\"2026-01-15T10:00:00Z\",\n    preview_token=\"your-preview-token\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.create(\"11111111-2222-3333-4444-555555555555\", {\n  contact_id: \"11111111-2222-3333-4444-555555555555\",\n  purpose: \"identity_document\",\n  request_id: \"11111111-2222-3333-4444-555555555555\",\n  expires_at: \"2026-01-15T10:00:00Z\",\n  preview_token: \"your-preview-token\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.Create(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CustomerMessagingCaseRequestConfirmRequest{\n\tContactID:    \"11111111-2222-3333-4444-555555555555\",\n\tPurpose:      didit.CustomerMessagingPurposeEnum(\"identity_document\"),\n\tRequestID:    \"11111111-2222-3333-4444-555555555555\",\n\tExpiresAt:    time.Date(2026, 1, 15, 10, 0, 0, 0, time.UTC),\n\tPreviewToken: \"your-preview-token\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.OffsetDateTime;\nimport me.didit.Didit;\nimport me.didit.types.CustomerMessagingCaseRequestConfirmRequest;\nimport me.didit.types.CustomerMessagingPurposeEnum;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().create(\"11111111-2222-3333-4444-555555555555\", CustomerMessagingCaseRequestConfirmRequest.builder()\n        .contactId(\"11111111-2222-3333-4444-555555555555\")\n        .purpose(CustomerMessagingPurposeEnum.of(\"identity_document\"))\n        .requestId(\"11111111-2222-3333-4444-555555555555\")\n        .expiresAt(OffsetDateTime.parse(\"2026-01-15T10:00:00Z\"))\n        .previewToken(\"your-preview-token\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->requests->create('11111111-2222-3333-4444-555555555555', [\n    'contact_id' => '11111111-2222-3333-4444-555555555555',\n    'purpose' => 'identity_document',\n    'request_id' => '11111111-2222-3333-4444-555555555555',\n    'expires_at' => '2026-01-15T10:00:00Z',\n    'preview_token' => 'your-preview-token',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.create(\n  \"11111111-2222-3333-4444-555555555555\",\n  contact_id: \"11111111-2222-3333-4444-555555555555\",\n  purpose: \"identity_document\",\n  request_id: \"11111111-2222-3333-4444-555555555555\",\n  expires_at: \"2026-01-15T10:00:00Z\",\n  preview_token: \"your-preview-token\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.CreateAsync(\"11111111-2222-3333-4444-555555555555\", new CustomerMessagingCaseRequestConfirmRequest\n{\n    ContactId = \"11111111-2222-3333-4444-555555555555\",\n    Purpose = \"identity_document\",\n    RequestId = \"11111111-2222-3333-4444-555555555555\",\n    ExpiresAt = DateTimeOffset.Parse(\"2026-01-15T10:00:00Z\"),\n    PreviewToken = \"your-preview-token\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/fraud/checks/": {
      "post": {
        "operationId": "create_fraud_check",
        "x-didit-sdk": {
          "resource": "fraud_checks",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "description": "하나 이상의 유형화된 식별자를 제출하고, 단일 응답으로 정규화, 최신 데이터 보강, 지원되는 국가 및 식별자 유형에 대한 신뢰할 수 있는 검증, 독립적인 위험 차원 분석 및 권장 사항을 수신합니다.\n\n이 프로필들은 식별자 검사를 지원합니다. 셀피 기반 신원 바인딩(`biometric_identity`)에는 프로필 버전 `2026-09-14.2`와 브라질 CPF가 필요합니다. 이는 사용자의 동의가 있고 조직에 해당 권한이 부여된 경우에만 실행됩니다. 이전 버전에서는 `not_available_in_profile_version`으로 보고됩니다. 실행할 수 없는 모듈은 확정적인 이유와 함께 건너뜀으로 보고되며, 응답할 수 없는 소스는 결코 신원 불일치로 보고되지 않습니다.",
        "summary": "사기 검사 실행",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/FraudCheckRequestRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FraudCheckRequestRequest"
              },
              "example": {
                "client_reference": "review-attempt-001",
                "subject": {
                  "identifiers": [
                    {
                      "type": "email",
                      "value": "applicant@example.com"
                    }
                  ],
                  "attributes": {
                    "first_name": "Alex",
                    "last_name": "Example"
                  }
                },
                "checks": {
                  "include": [
                    "networks_same_org",
                    "networks_cross_org",
                    "email_risk"
                  ]
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/FraudCheckRequestRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudCheckResponse"
                }
              }
            },
            "description": ""
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudClientCredentialsErrorMessage"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": ""
          },
          "409": {
            "description": "충돌(비용 청구 없이 반환됨): `client_reference`가 이미 다른 요청 본문에서 사용되었거나, 동일한 `client_reference`를 가진 검사가 아직 실행 중이거나(`Retry-After` 초 후에 동일한 참조로 재시도), 이 검사가 기록되는 인증이 검사 완료 전에 삭제되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "different_body": {
                    "summary": "다른 본문과 함께 재사용된 레퍼런스",
                    "value": {
                      "error": "client_reference has already been used with a different request body."
                    }
                  },
                  "still_running": {
                    "summary": "이 참조를 가진 확인이 아직 실행 중입니다",
                    "value": {
                      "error": "A check with this client_reference is already running. Retry with the same reference later."
                    }
                  },
                  "verification_deleted": {
                    "summary": "확인이 완료되기 전에 인증이 삭제되었습니다",
                    "value": {
                      "error": "This verification was deleted before the check completed."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "동일한 `client_reference`를 가진 검사가 아직 실행 중일 때 전송되는, 재시도 전 대기 시간(초)입니다.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "Fraud Check"
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.fraud_checks.create(\n    client_reference=\"review-attempt-001\",\n    subject={\n        \"identifiers\": [{\n            \"type\": \"email\",\n            \"value\": \"applicant@example.com\",\n        }],\n        \"attributes\": {\n            \"first_name\": \"Alex\",\n            \"last_name\": \"Example\",\n        },\n    },\n    checks={\n        \"include\": [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.fraudChecks.create({\n  client_reference: \"review-attempt-001\",\n  subject: {\n    identifiers: [{\n      type: \"email\",\n      value: \"applicant@example.com\",\n    }],\n    attributes: {\n      first_name: \"Alex\",\n      last_name: \"Example\",\n    },\n  },\n  checks: {\n    include: [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FraudChecks.Create(ctx, didit.FraudCheckRequestRequest{\n\tClientReference: didit.String(\"review-attempt-001\"),\n\tSubject: didit.FraudCheckSubjectRequest{\n\t\tIdentifiers: []didit.FraudCheckIdentifierRequest{{\n\t\t\tType:  didit.FraudTypeEnum(\"email\"),\n\t\t\tValue: \"applicant@example.com\",\n\t\t}},\n\t\tAttributes: didit.Some(didit.FraudCheckAttributesRequest{\n\t\t\tFirstName: didit.String(\"Alex\"),\n\t\t\tLastName:  didit.String(\"Example\"),\n\t\t}),\n\t},\n\tChecks: didit.Some(didit.FraudCheckModuleSelectionRequest{\n\t\tInclude: didit.Some([]didit.FraudExcludeEnum{didit.FraudExcludeEnum(\"networks_same_org\"), didit.FraudExcludeEnum(\"networks_cross_org\"), didit.FraudExcludeEnum(\"email_risk\")}),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.FraudCheckAttributesRequest;\nimport me.didit.types.FraudCheckIdentifierRequest;\nimport me.didit.types.FraudCheckModuleSelectionRequest;\nimport me.didit.types.FraudCheckRequestRequest;\nimport me.didit.types.FraudCheckSubjectRequest;\nimport me.didit.types.FraudExcludeEnum;\nimport me.didit.types.FraudTypeEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.fraudChecks().create(FraudCheckRequestRequest.builder()\n        .clientReference(\"review-attempt-001\")\n        .subject(FraudCheckSubjectRequest.builder()\n                .identifiers(List.of(FraudCheckIdentifierRequest.builder()\n                        .type(FraudTypeEnum.of(\"email\"))\n                        .value(\"applicant@example.com\")\n                        .build()))\n                .attributes(FraudCheckAttributesRequest.builder()\n                        .firstName(\"Alex\")\n                        .lastName(\"Example\")\n                        .build())\n                .build())\n        .checks(FraudCheckModuleSelectionRequest.builder()\n                .include(List.of(FraudExcludeEnum.of(\"networks_same_org\"), FraudExcludeEnum.of(\"networks_cross_org\"), FraudExcludeEnum.of(\"email_risk\")))\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->fraudChecks->create([\n    'client_reference' => 'review-attempt-001',\n    'subject' => [\n        'identifiers' => [[\n            'type' => 'email',\n            'value' => 'applicant@example.com',\n        ]],\n        'attributes' => [\n            'first_name' => 'Alex',\n            'last_name' => 'Example',\n        ],\n    ],\n    'checks' => [\n        'include' => ['networks_same_org', 'networks_cross_org', 'email_risk'],\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.fraud_checks.create(\n  client_reference: \"review-attempt-001\",\n  subject: {\n    identifiers: [{\n      type: \"email\",\n      value: \"applicant@example.com\",\n    }],\n    attributes: {\n      first_name: \"Alex\",\n      last_name: \"Example\",\n    },\n  },\n  checks: {\n    include: [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FraudChecks.CreateAsync(new FraudCheckRequestRequest\n{\n    ClientReference = \"review-attempt-001\",\n    Subject = new()\n    {\n        Identifiers = new FraudCheckIdentifierRequest[]\n        {\n            new()\n            {\n                Type = \"email\",\n                Value = \"applicant@example.com\",\n            },\n        },\n        Attributes = new FraudCheckAttributesRequest\n        {\n            FirstName = \"Alex\",\n            LastName = \"Example\",\n        },\n    },\n    Checks = new FraudCheckModuleSelectionRequest\n    {\n        Include = new FraudExcludeEnum[] { \"networks_same_org\", \"networks_cross_org\", \"email_risk\" },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/requests/{request_uuid}/cancel/": {
      "post": {
        "operationId": "organization_application_cases_requests_cancel_create",
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "cancel",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "request_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingCaseRequest"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "이 호출자에게는 요청 또는 케이스를 사용할 수 없습니다."
          },
          "403": {
            "description": "호출자에게 필요한 케이스 권한이 없습니다."
          },
          "400": {
            "description": "유효하지 않은 입력, 지원되지 않는 목적, 사용할 수 없는 인증된 연락처, 또는 기존의 변경 불가능한 응답입니다."
          },
          "409": {
            "description": "미리보기가 변경되었거나 만료되었습니다. 확인하기 전에 다시 미리보기를 진행하십시오."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.cancel(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.cancel(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.Cancel(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().cancel(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->requests->cancel('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.cancel(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.CancelAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/requests/options/": {
      "get": {
        "operationId": "organization_application_cases_requests_options_retrieve",
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "retrieve_options",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingCaseRequestOptions"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "이 호출자에게는 요청 또는 케이스를 사용할 수 없습니다."
          },
          "403": {
            "description": "호출자에게 필요한 케이스 권한이 없습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.retrieve_options(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.retrieveOptions(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.RetrieveOptions(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().retrieveOptions(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->requests->retrieveOptions('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.retrieve_options(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.RetrieveOptionsAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/requests/{request_uuid}/attachment/": {
      "get": {
        "operationId": "organization_application_cases_requests_attachment_retrieve",
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "retrieve_attachment",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "request_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "이 호출자에게는 요청 또는 케이스를 사용할 수 없습니다."
          },
          "403": {
            "description": "호출자에게 필요한 케이스 권한이 없습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\ncontent = client.cases.requests.retrieve_attachment(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.png\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst content = await didit.cases.requests.retrieveAttachment(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nawait writeFile(\"download.png\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresp, err := client.Cases.Requests.RetrieveAttachment(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.png\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().requests().retrieveAttachment(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\n        .writeTo(Path.of(\"download.png\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$content = $didit->cases->requests->retrieveAttachment('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.png');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ncontent = didit.cases.requests.retrieve_attachment(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nFile.binwrite(\"download.png\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar content = await client.Cases.Requests.RetrieveAttachmentAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.png\");"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/{record_uuid}/history/": {
      "get": {
        "operationId": "list_case_routing_rule_history",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "list_history",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "record_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "결과를 정렬할 때 사용할 필드입니다.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "페이지당 반환할 결과 수입니다.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "description": "결과 반환을 시작할 초기 인덱스입니다.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "tags": [
          "Case Assignment"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoutingPublicationPaginatedPolicyRevisionList"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "케이스 접근 권한이 필요합니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.routing_rules.list_history(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.routingRules.listHistory(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.RoutingRules.ListHistoryAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesRoutingRulesListHistoryParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().routingRules().listHistory(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->routingRules->listHistory('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.routing_rules.list_history(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.RoutingRules.ListHistoryAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/resubmission-preview/": {
      "post": {
        "summary": "재제출 이메일 미리보기",
        "description": "세션을 변경하거나 검사를 재설정하거나 만료 기간을 연장하거나 검사를 실행하거나 메일을 발송하지 않고, KYC 또는 KYB 재제출 시 함께 발송될 이메일을 렌더링합니다. `write:sessions` 권한(범위가 지정된 API 키에는 결정에 대한 쓰기 권한 필요)과 `Approved`, `Declined`, `In Review`, `Kyc Expired` 또는 `Abandoned` 상태의 세션이 필요합니다. 서버는 선택된 워크플로 단계를 검증하고 적용 가능한 인증된 화이트 라벨 발신자 및 브랜딩이 적용된 고정 번역 템플릿을 렌더링합니다. 요청에서 제목, 메시지 본문 또는 작업 URL을 설정할 수 없습니다.\n\n`email_address`는 선택 사항입니다. 이를 지정하지 않으면 이메일은 해당 사용자의 주소(워크플로의 이메일 인증 단계에서 검증한 주소이며, 해당 주소가 없으면 세션 생성 시 `contact_details`에 입력된 주소)로 발송됩니다. 직접 전달한 주소가 우선 적용됩니다(`recipient_source: request`). 알려진 주소가 없고 전달한 주소도 없는 경우, `recipient` 및 `preview_token`은 빈 문자열이 되며 이메일을 발송할 수 없습니다.\n\n응답에는 수신자 및 해당 출처, 발신자, 제목, HTML, 언어, 확정된 단계, 확정 시 이메일 발송 여부(`will_be_sent`, `not_sent_reason`), 서명된 `preview_token`이 포함됩니다. 선택된 모든 단계가 사용자 없이 실행되는 경우 `requires_user_action`은 `false`가 되며, 이 경우 재제출은 자체적으로 완료되고 이메일은 발송되지 않습니다(`not_sent_reason: no_user_action`).\n\n이 미리보기는 세션 상태를 예약하거나 전송을 승인하지 않습니다. 검토 후 [Update Session Status](/ko/sessions-api/update-status)를 호출할 때 `new_status: Resubmitted`, 미리 본 것과 동일한 `nodes_to_resubmit` 및 `email_language`, `send_email: true`, `email_address`를 `recipient`로, `email_preview_token`을 `preview_token`으로 설정하여 호출하십시오. 영수증은 15분 후 만료됩니다. 영수증이 제공되면 입력값, 메시지 내용, 발신자 또는 세션 상태 중 변경된 항목이 있을 때 어떤 변경이나 발송도 하기 전에 `409`가 반환됩니다. 기존 연동에서는 영수증을 생략할 수 있습니다. 충돌 발생 후에는 미리보기를 다시 생성하십시오. 응답을 민감한 인증 콘텐츠로 취급하십시오. 응답은 `Cache-Control: no-store`를 사용합니다. HTML은 애플리케이션 DOM에 직접 렌더링하지 말고 반드시 샌드박스 처리된 프레임에서 렌더링하십시오.",
        "operationId": "post_v3_session_resubmission_preview",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "preview_resubmission",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "업데이트할 인증 세션의 UUID입니다. 사용자(KYC) 및 기업(KYB) 세션 ID를 모두 지원하며, 서비스는 두 세션 유형 전체에서 ID를 확인합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "nodes_to_resubmit": {
                    "type": "array",
                    "description": "재제출과 동일한 검증, 선택 및 워크플로 순서를 사용하여 미리 볼 단계입니다. 재제출이 필요한 기록된 시도를 자동 선택하려면 생략하십시오.",
                    "items": {
                      "type": "object",
                      "required": [
                        "node_id",
                        "feature"
                      ],
                      "properties": {
                        "node_id": {
                          "type": "string",
                          "description": "세션의 워크플로 정의에 표시되는 노드 식별자(예: `feature_ocr`, `feature_liveness`).",
                          "example": "feature_ocr"
                        },
                        "feature": {
                          "type": "string",
                          "description": "노드의 기능 유형입니다. `ID_VERIFICATION`, `POA`, `PHONE`, `EMAIL` 별칭은 서버 측에서 `OCR`, `PROOF_OF_ADDRESS`, `PHONE_VERIFICATION`, `EMAIL_VERIFICATION`으로 정규화됩니다. `KYB_REGISTRY`, `KYB_KEY_PEOPLE`, `KYB`는 스키마 유효성 검사를 통과하지만 예시에 표시된 비즈니스 규칙 `400` 오류로 항상 거부됩니다.",
                          "enum": [
                            "OCR",
                            "OCR_BACK",
                            "NFC",
                            "AML",
                            "FACE",
                            "LIVENESS",
                            "FACE_MATCH",
                            "IP_ANALYSIS",
                            "AGE_ESTIMATION",
                            "PROOF_OF_ADDRESS",
                            "PHONE_VERIFICATION",
                            "EMAIL_VERIFICATION",
                            "FACE_SEARCH",
                            "DATABASE_VALIDATION",
                            "QUESTIONNAIRE",
                            "DOCUMENT_AI",
                            "KYB_DOCUMENTS",
                            "ID_VERIFICATION",
                            "POA",
                            "PHONE",
                            "EMAIL",
                            "KYB_REGISTRY",
                            "KYB_KEY_PEOPLE",
                            "KYB",
                            "GEOLOCATION"
                          ],
                          "example": "OCR"
                        }
                      }
                    }
                  },
                  "email_address": {
                    "type": "string",
                    "format": "email",
                    "description": "선택 사항입니다. 개인 본인의 주소 대신 이 주소로 이메일을 전송합니다. 지정하지 않으면 워크플로에서 개인이 인증한 주소가 수신자가 되며, 그렇지 않으면 `contact_details`에 입력된 주소가 사용됩니다. 이 호출로는 이메일이 전송되지 않습니다.",
                    "example": "user@example.com"
                  },
                  "email_language": {
                    "type": "string",
                    "description": "알림 이메일 언어입니다. 스키마 수준에서 모든 문자열을 허용하며, 지원되지 않는 코드는 영어(`en`)로 자동 대체됩니다.",
                    "default": "en",
                    "example": "en"
                  }
                }
              },
              "examples": {
                "Person's Own Address": {
                  "summary": "해당 인물 본인 주소에 대한 주소 증명 재제출 미리보기",
                  "value": {
                    "nodes_to_resubmit": [
                      {
                        "node_id": "feature_poa_1",
                        "feature": "POA"
                      }
                    ],
                    "email_language": "en"
                  }
                },
                "Named Recipient": {
                  "summary": "지정한 주소에 대한 이메일 미리보기",
                  "value": {
                    "nodes_to_resubmit": [
                      {
                        "node_id": "feature_ocr",
                        "feature": "OCR"
                      }
                    ],
                    "email_address": "person@example.com",
                    "email_language": "en"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "미리보기 전용입니다. 세션은 변경되지 않으며 이메일도 전송되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "recipient",
                    "recipient_source",
                    "sender",
                    "sender_name",
                    "sender_email",
                    "sender_kind",
                    "subject",
                    "html",
                    "text",
                    "language",
                    "will_be_sent",
                    "not_sent_reason",
                    "preview_token",
                    "nodes_to_resubmit",
                    "requires_user_action"
                  ],
                  "properties": {
                    "recipient": {
                      "type": "string",
                      "description": "이메일이 전송되는 주소입니다. 사용자의 주소를 알 수 없는 경우 빈 문자열입니다: 이 경우 이메일을 전송할 수 없으며 `preview_token`도 비어 있습니다. 확인할 때 `email_address`로 전달하십시오.",
                      "example": "person@example.com"
                    },
                    "recipient_source": {
                      "type": "string",
                      "enum": [
                        "email_verification",
                        "contact_details",
                        "request",
                        ""
                      ],
                      "description": "`recipient`의 출처입니다. `request`: 전달한 `email_address`입니다. `email_verification`: 플로우의 이메일 인증 단계에서 사용자가 인증한 주소입니다. `contact_details`: 세션 생성 시 `contact_details`에 제공된 주소입니다. 주소가 없는 경우 빈 문자열입니다.",
                      "example": "email_verification"
                    },
                    "sender": {
                      "type": "string",
                      "description": "이메일 발송에 사용되는 `From` 헤더입니다.",
                      "example": "Example App <no-reply@mail.example.com>"
                    },
                    "sender_name": {
                      "type": "string",
                      "description": "`sender`의 표시 이름 부분입니다.",
                      "example": "Example App"
                    },
                    "sender_email": {
                      "type": "string",
                      "format": "email",
                      "description": "`sender`의 주소 부분입니다.",
                      "example": "no-reply@mail.example.com"
                    },
                    "sender_kind": {
                      "type": "string",
                      "enum": [
                        "customer",
                        "didit"
                      ],
                      "description": "`customer`: 이메일이 애플리케이션의 인증된 발신자 도메인(화이트 라벨)에서 발송됩니다. `didit`: Didit의 자체 발신자에서 발송됩니다.",
                      "example": "customer"
                    },
                    "subject": {
                      "type": "string",
                      "description": "전송된 그대로의 제목 라인입니다.",
                      "example": "Action Required: Complete your verification in Example App"
                    },
                    "html": {
                      "type": "string",
                      "description": "전송된 그대로의 이메일 HTML이며, 로고는 data URL로 임베드되어 있습니다. 애플리케이션 DOM에 직접 렌더링하지 말고 반드시 샌드박스 처리된 프레임에서 렌더링하세요.",
                      "example": "<!DOCTYPE html><html><body>...</body></html>"
                    },
                    "text": {
                      "type": "string",
                      "description": "간결한 미리보기를 제공하기 위해 수신자의 메시지 스레드에 보관되는 일반 텍스트 형태의 이메일 내용입니다(HTML은 수신자가 받는 이메일 그대로 유지됨).",
                      "example": "Almost there\n\nSome steps need to be completed again.\nHere’s what to fix:\n\nhttps://verify.didit.me/session/abc123"
                    },
                    "language": {
                      "type": "string",
                      "description": "이메일이 작성된 언어입니다. 요청한 `email_language`가 제공되지 않는 경우 영어(`en`)로 설정됩니다.",
                      "example": "en"
                    },
                    "will_be_sent": {
                      "type": "boolean",
                      "description": "`send_email: true`로 변경 사항을 확인할 때 이 이메일을 발송할지 여부입니다. `not_sent_reason`이 설정된 경우 `false`입니다.",
                      "example": true
                    },
                    "not_sent_reason": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "no_user_action",
                        "no_recipient",
                        "sandbox",
                        null
                      ],
                      "description": "확인 시 이메일이 전송되지 않는 이유 또는 전송될 예정인 경우 `null`입니다. `no_user_action`: 선택한 모든 단계가 사용자 없이 실행되므로 재제출이 자동으로 완료되고 이메일이 발송되지 않습니다. `no_recipient`: 사용자의 알려진 주소가 없으며 전달된 주소도 없습니다. `sandbox`: 수신자가 샌드박스 이메일 전송에 동의하지 않은 샌드박스 세션이므로 전송이 시뮬레이션만 됩니다.",
                      "example": null
                    },
                    "nodes_to_resubmit": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "node_id",
                          "feature"
                        ],
                        "properties": {
                          "node_id": {
                            "type": "string",
                            "description": "세션의 워크플로 정의에 표시되는 노드 식별자(예: `feature_ocr`, `feature_liveness`).",
                            "example": "feature_ocr"
                          },
                          "feature": {
                            "type": "string",
                            "description": "노드의 기능 유형입니다. `ID_VERIFICATION`, `POA`, `PHONE`, `EMAIL` 별칭은 서버 측에서 `OCR`, `PROOF_OF_ADDRESS`, `PHONE_VERIFICATION`, `EMAIL_VERIFICATION`으로 정규화됩니다. `KYB_REGISTRY`, `KYB_KEY_PEOPLE`, `KYB`는 스키마 유효성 검사를 통과하지만 예시에 표시된 비즈니스 규칙 `400` 오류로 항상 거부됩니다.",
                            "enum": [
                              "OCR",
                              "OCR_BACK",
                              "NFC",
                              "AML",
                              "FACE",
                              "LIVENESS",
                              "FACE_MATCH",
                              "IP_ANALYSIS",
                              "AGE_ESTIMATION",
                              "PROOF_OF_ADDRESS",
                              "PHONE_VERIFICATION",
                              "EMAIL_VERIFICATION",
                              "FACE_SEARCH",
                              "DATABASE_VALIDATION",
                              "QUESTIONNAIRE",
                              "DOCUMENT_AI",
                              "KYB_DOCUMENTS",
                              "ID_VERIFICATION",
                              "POA",
                              "PHONE",
                              "EMAIL",
                              "KYB_REGISTRY",
                              "KYB_KEY_PEOPLE",
                              "KYB",
                              "GEOLOCATION"
                            ],
                            "example": "OCR"
                          }
                        }
                      }
                    },
                    "requires_user_action": {
                      "type": "boolean",
                      "description": "선택한 검사 중 하나 이상에 사용자 상호작용이 필요한지 여부입니다. 이는 최종 워크플로 결과를 예측하지 않습니다."
                    },
                    "preview_token": {
                      "type": "string",
                      "description": "해당 이메일에 대한 서명된 영수증으로, 15분 동안 유효합니다. [세션 상태 업데이트](/ko/sessions-api/update-status)에 `email_preview_token`으로 전달하십시오. 수신자가 없는 경우 빈 문자열입니다.",
                      "example": "eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000"
                    }
                  }
                },
                "examples": {
                  "Will Be Sent": {
                    "summary": "기본 수취인: 플로우에서 검증된 주소",
                    "value": {
                      "recipient": "person@example.com",
                      "recipient_source": "email_verification",
                      "sender": "Example App <no-reply@mail.example.com>",
                      "sender_name": "Example App",
                      "sender_email": "no-reply@mail.example.com",
                      "sender_kind": "customer",
                      "subject": "Action Required: Complete your verification in Example App",
                      "html": "<!DOCTYPE html><html><body>...</body></html>",
                      "language": "en",
                      "will_be_sent": true,
                      "not_sent_reason": null,
                      "nodes_to_resubmit": [
                        {
                          "node_id": "feature_poa_1",
                          "feature": "PROOF_OF_ADDRESS"
                        }
                      ],
                      "requires_user_action": true,
                      "preview_token": "eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000"
                    }
                  },
                  "No User Action": {
                    "summary": "백엔드 단계만 선택되었으므로 이메일이 발송되지 않습니다",
                    "value": {
                      "recipient": "person@example.com",
                      "recipient_source": "contact_details",
                      "sender": "Example App <no-reply@mail.example.com>",
                      "sender_name": "Example App",
                      "sender_email": "no-reply@mail.example.com",
                      "sender_kind": "customer",
                      "subject": "Action Required: Complete your verification in Example App",
                      "html": "<!DOCTYPE html><html><body>...</body></html>",
                      "language": "en",
                      "will_be_sent": false,
                      "not_sent_reason": "no_user_action",
                      "nodes_to_resubmit": [
                        {
                          "node_id": "feature_aml",
                          "feature": "AML"
                        }
                      ],
                      "requires_user_action": false,
                      "preview_token": "eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000"
                    }
                  }
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "항상 `no-store`입니다. 미리보기에는 인증 콘텐츠가 포함되어 있으므로 캐시해서는 안 됩니다.",
                "schema": {
                  "type": "string",
                  "example": "no-store"
                }
              }
            }
          },
          "400": {
            "description": "세션이 이 endpoint에서 허용하는 상태가 아니거나, 이미 `Resubmitted` 상태이거나, 선택한 단계를 다시 제출할 수 없거나, 필드가 올바르지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Wrong Current Status": {
                    "summary": "세션이 이 endpoint에서 허용하는 상태가 아닙니다",
                    "value": {
                      "detail": "Only sessions with status Approved, Declined, In Review, Kyc Expired, Abandoned, Resubmitted can be updated. Current status: In Progress"
                    }
                  },
                  "Already Resubmitted": {
                    "summary": "세션이 이미 Resubmitted 상태입니다",
                    "value": [
                      "The new status is the same as the current status."
                    ]
                  },
                  "Nothing To Resubmit": {
                    "summary": "자동 선택 결과 다시 제출해야 하는 단계를 찾지 못했습니다",
                    "value": {
                      "nodes_to_resubmit": "No features found that need resubmission. All features are already approved."
                    }
                  },
                  "Invalid Email": {
                    "summary": "email_address가 이메일 주소가 아닙니다",
                    "value": {
                      "email_address": [
                        "Enter a valid email address."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "만료일이 지난 스코프 지정 API 키",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나, 호출자에게 `write:sessions` 권한이 없거나, 범위 지정 API 키에 이 endpoint가 필요로 하는 접근 권한이 없거나, `session_id`가 다른 애플리케이션에 속해 있습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "호출자에게 write:sessions 권한이 없습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped Key Without Access": {
                    "summary": "이 접근 권한이 없는 스코프 지정 API 키",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 `session_id`를 가진 KYC 또는 KYB 세션이 존재하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "알 수 없는 session_id",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "재제출할 단계가 모두 백엔드 전용(AML, DATABASE_VALIDATION, IP_ANALYSIS)이며, 최근 30초 이내에 해당 세션에 대해 백엔드 전용 단계의 재제출이 이미 수행되었으므로 Update Session Status에서 재제출을 거부합니다. `Retry-After`에 지정된 간격이 지난 후 다시 시도하십시오.",
            "content": {
              "application/json": {
                "examples": {
                  "Backend-only resubmit throttled": {
                    "value": {
                      "detail": "This session was already resubmitted for backend-only features within the last 30 seconds; repeating it cannot change the outcome. Wait before resubmitting again."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.preview_resubmission(\n    \"11111111-2222-3333-4444-555555555555\",\n    nodes_to_resubmit=[{\n        \"node_id\": \"feature_poa_1\",\n        \"feature\": \"POA\",\n    }],\n    email_language=\"en\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.previewResubmission(\"11111111-2222-3333-4444-555555555555\", {\n  nodes_to_resubmit: [{\n    node_id: \"feature_poa_1\",\n    feature: \"POA\",\n  }],\n  email_language: \"en\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.PreviewResubmission(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsPreviewResubmissionParams{\n\tNodesToResubmit: didit.Some([]didit.SessionsPreviewResubmissionParamsNodesToResubmit{{\n\t\tNodeID:  \"feature_poa_1\",\n\t\tFeature: \"POA\",\n\t}}),\n\tEmailLanguage: didit.String(\"en\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsPreviewResubmissionParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().previewResubmission(\"11111111-2222-3333-4444-555555555555\", SessionsPreviewResubmissionParams.builder()\n        .nodesToResubmit(List.of(SessionsPreviewResubmissionParams.NodesToResubmit.builder()\n                .nodeId(\"feature_poa_1\")\n                .feature(SessionsPreviewResubmissionParams.NodesToResubmit.Feature.of(\"POA\"))\n                .build()))\n        .emailLanguage(\"en\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->previewResubmission('11111111-2222-3333-4444-555555555555', [\n    'nodes_to_resubmit' => [[\n        'node_id' => 'feature_poa_1',\n        'feature' => 'POA',\n    ]],\n    'email_language' => 'en',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.preview_resubmission(\n  \"11111111-2222-3333-4444-555555555555\",\n  nodes_to_resubmit: [{\n    node_id: \"feature_poa_1\",\n    feature: \"POA\",\n  }],\n  email_language: \"en\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.PreviewResubmissionAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsPreviewResubmissionParams\n{\n    NodesToResubmit = new SessionsPreviewResubmissionParamsNodesToResubmit[]\n    {\n        new()\n        {\n            NodeId = \"feature_poa_1\",\n            Feature = \"POA\",\n        },\n    },\n    EmailLanguage = \"en\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/{record_uuid}/": {
      "get": {
        "summary": "라우팅 규칙 조회",
        "description": "요청된 애플리케이션에 대한 `read:cases` 권한이 필요합니다.",
        "operationId": "retrieve_case_routing_rules",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "record_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseRoutingRule"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 입력입니다."
          },
          "403": {
            "description": "권한이 부족합니다."
          },
          "404": {
            "description": "이 애플리케이션에서 레코드를 찾을 수 없습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "patch": {
        "summary": "라우팅 규칙 업데이트",
        "description": "요청된 애플리케이션에 대한 `write:cases` 권한이 필요합니다.",
        "operationId": "update_case_routing_rules",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "record_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseRoutingRule"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 입력입니다."
          },
          "403": {
            "description": "권한이 부족합니다."
          },
          "404": {
            "description": "이 애플리케이션에서 레코드를 찾을 수 없습니다."
          },
          "409": {
            "description": "라우팅 규칙이 expected_version 이후 변경되었습니다. 재시도하기 전에 최신 규칙을 검토하세요."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseRoutingRuleUpdate"
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    name=\"your-name\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.update(\"11111111-2222-3333-4444-555555555555\", {\n  name: \"your-name\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CaseRoutingRuleUpdate{\n\tName: didit.String(\"your-name\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CaseRoutingRuleUpdate;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().update(\"11111111-2222-3333-4444-555555555555\", CaseRoutingRuleUpdate.builder()\n        .name(\"your-name\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->update('11111111-2222-3333-4444-555555555555', [\n    'name' => 'your-name',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  name: \"your-name\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new CaseRoutingRuleUpdate\n{\n    Name = \"your-name\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/case-requests/{request_uuid}/": {
      "get": {
        "operationId": "case_requests_retrieve",
        "x-didit-sdk": {
          "resource": "case_requests",
          "method": "retrieve",
          "auth": "device_token",
          "server": false
        },
        "parameters": [
          {
            "in": "path",
            "name": "request_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingCaseRequestPublic"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "이 호출자에게는 요청 또는 케이스를 사용할 수 없습니다."
          }
        },
        "security": [
          {
            "CaseRequestToken": []
          }
        ],
        "description": "요청별 token을 사용하여 고객 요청 하나에 접근합니다. 비공개 케이스 조사 결과, 원본 신원 데이터 또는 수취인 주소는 반환되지 않습니다. 조치 가능한 요청은 7일 후에 만료됩니다. 취소 또는 케이스 해결 시 링크가 무효화됩니다. 응답은 변경할 수 없으며 검토자 평가를 위한 증거로 유지됩니다. 응답이 원본 인증을 승인하거나 업데이트하지는 않습니다."
      },
      "post": {
        "operationId": "case_requests_create",
        "x-didit-sdk": {
          "resource": "case_requests",
          "method": "respond",
          "auth": "device_token",
          "server": false
        },
        "parameters": [
          {
            "in": "path",
            "name": "request_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseCustomerResponseRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseCustomerResponseRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingCaseCustomerResponseResult"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "이 호출자에게는 요청 또는 케이스를 사용할 수 없습니다."
          },
          "400": {
            "description": "유효하지 않은 입력, 지원되지 않는 목적, 사용할 수 없는 인증된 연락처, 또는 기존의 변경 불가능한 응답입니다."
          },
          "409": {
            "description": "미리보기가 변경되었거나 만료되었습니다. 확인하기 전에 다시 미리보기를 진행하십시오."
          }
        },
        "security": [
          {
            "CaseRequestToken": []
          }
        ],
        "description": "요청별 token을 사용하여 고객 요청 하나에 접근합니다. 비공개 케이스 조사 결과, 원본 신원 데이터 또는 수취인 주소는 반환되지 않습니다. 조치 가능한 요청은 7일 후에 만료됩니다. 취소 또는 케이스 해결 시 링크가 무효화됩니다. 응답은 변경할 수 없으며 검토자 평가를 위한 증거로 유지됩니다. 응답이 원본 인증을 승인하거나 업데이트하지는 않습니다."
      }
    },
    "/v3/fraud/checks/plan/": {
      "post": {
        "operationId": "plan_create",
        "x-didit-sdk": {
          "resource": "fraud_checks",
          "method": "plan",
          "auth": "api_key",
          "server": true
        },
        "description": "실행하거나 세션을 생성하거나 결제하지 않고 선택한 검사를 검증하고 가격을 견적합니다.",
        "summary": "사기 검사 계획",
        "tags": [
          "Fraud Check"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/FraudCheckRequestRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FraudCheckRequestRequest"
              },
              "example": {
                "client_reference": "review-attempt-001",
                "subject": {
                  "identifiers": [
                    {
                      "type": "email",
                      "value": "applicant@example.com"
                    }
                  ],
                  "attributes": {
                    "first_name": "Alex",
                    "last_name": "Example"
                  }
                },
                "checks": {
                  "include": [
                    "networks_same_org",
                    "networks_cross_org",
                    "email_risk"
                  ]
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/FraudCheckRequestRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudCheckPlan"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudBadRequestErrorMessage"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.fraud_checks.plan(\n    client_reference=\"review-attempt-001\",\n    subject={\n        \"identifiers\": [{\n            \"type\": \"email\",\n            \"value\": \"applicant@example.com\",\n        }],\n        \"attributes\": {\n            \"first_name\": \"Alex\",\n            \"last_name\": \"Example\",\n        },\n    },\n    checks={\n        \"include\": [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.fraudChecks.plan({\n  client_reference: \"review-attempt-001\",\n  subject: {\n    identifiers: [{\n      type: \"email\",\n      value: \"applicant@example.com\",\n    }],\n    attributes: {\n      first_name: \"Alex\",\n      last_name: \"Example\",\n    },\n  },\n  checks: {\n    include: [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FraudChecks.Plan(ctx, didit.FraudCheckRequestRequest{\n\tClientReference: didit.String(\"review-attempt-001\"),\n\tSubject: didit.FraudCheckSubjectRequest{\n\t\tIdentifiers: []didit.FraudCheckIdentifierRequest{{\n\t\t\tType:  didit.FraudTypeEnum(\"email\"),\n\t\t\tValue: \"applicant@example.com\",\n\t\t}},\n\t\tAttributes: didit.Some(didit.FraudCheckAttributesRequest{\n\t\t\tFirstName: didit.String(\"Alex\"),\n\t\t\tLastName:  didit.String(\"Example\"),\n\t\t}),\n\t},\n\tChecks: didit.Some(didit.FraudCheckModuleSelectionRequest{\n\t\tInclude: didit.Some([]didit.FraudExcludeEnum{didit.FraudExcludeEnum(\"networks_same_org\"), didit.FraudExcludeEnum(\"networks_cross_org\"), didit.FraudExcludeEnum(\"email_risk\")}),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.FraudCheckAttributesRequest;\nimport me.didit.types.FraudCheckIdentifierRequest;\nimport me.didit.types.FraudCheckModuleSelectionRequest;\nimport me.didit.types.FraudCheckRequestRequest;\nimport me.didit.types.FraudCheckSubjectRequest;\nimport me.didit.types.FraudExcludeEnum;\nimport me.didit.types.FraudTypeEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.fraudChecks().plan(FraudCheckRequestRequest.builder()\n        .clientReference(\"review-attempt-001\")\n        .subject(FraudCheckSubjectRequest.builder()\n                .identifiers(List.of(FraudCheckIdentifierRequest.builder()\n                        .type(FraudTypeEnum.of(\"email\"))\n                        .value(\"applicant@example.com\")\n                        .build()))\n                .attributes(FraudCheckAttributesRequest.builder()\n                        .firstName(\"Alex\")\n                        .lastName(\"Example\")\n                        .build())\n                .build())\n        .checks(FraudCheckModuleSelectionRequest.builder()\n                .include(List.of(FraudExcludeEnum.of(\"networks_same_org\"), FraudExcludeEnum.of(\"networks_cross_org\"), FraudExcludeEnum.of(\"email_risk\")))\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->fraudChecks->plan([\n    'client_reference' => 'review-attempt-001',\n    'subject' => [\n        'identifiers' => [[\n            'type' => 'email',\n            'value' => 'applicant@example.com',\n        ]],\n        'attributes' => [\n            'first_name' => 'Alex',\n            'last_name' => 'Example',\n        ],\n    ],\n    'checks' => [\n        'include' => ['networks_same_org', 'networks_cross_org', 'email_risk'],\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.fraud_checks.plan(\n  client_reference: \"review-attempt-001\",\n  subject: {\n    identifiers: [{\n      type: \"email\",\n      value: \"applicant@example.com\",\n    }],\n    attributes: {\n      first_name: \"Alex\",\n      last_name: \"Example\",\n    },\n  },\n  checks: {\n    include: [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FraudChecks.PlanAsync(new FraudCheckRequestRequest\n{\n    ClientReference = \"review-attempt-001\",\n    Subject = new()\n    {\n        Identifiers = new FraudCheckIdentifierRequest[]\n        {\n            new()\n            {\n                Type = \"email\",\n                Value = \"applicant@example.com\",\n            },\n        },\n        Attributes = new FraudCheckAttributesRequest\n        {\n            FirstName = \"Alex\",\n            LastName = \"Example\",\n        },\n    },\n    Checks = new FraudCheckModuleSelectionRequest\n    {\n        Include = new FraudExcludeEnum[] { \"networks_same_org\", \"networks_cross_org\", \"email_risk\" },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/": {
      "get": {
        "summary": "라우팅 규칙 목록 조회",
        "description": "요청된 애플리케이션에 대한 `list:cases` 권한이 필요합니다.",
        "operationId": "list_case_routing_rules",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 1000000,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaseRoutingRule"
                      }
                    },
                    "count": {
                      "type": "integer",
                      "description": "일치하는 개수이며 최대 100개로 제한됩니다. 제한을 넘어 계속하려면 next를 따르십시오."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 입력입니다."
          },
          "403": {
            "description": "권한이 부족합니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.routing_rules.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.routingRules.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.RoutingRules.ListAutoPaging(ctx, didit.CasesRoutingRulesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().routingRules().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->routingRules->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.routing_rules.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.RoutingRules.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "summary": "라우팅 규칙 생성",
        "description": "요청된 애플리케이션에 대한 `write:cases` 권한이 필요합니다. 게시되지 않은 초안을 생성하려면 publish=false로 설정하세요. 게시하면 첫 번째 라이브 버전이 생성됩니다. 한 번도 게시되지 않은 초안을 폐기하면 삭제됩니다.",
        "operationId": "create_case_routing_rules",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "responses": {
          "201": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseRoutingRule"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 입력입니다."
          },
          "403": {
            "description": "권한이 부족합니다."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseRoutingRuleCreate"
              },
              "example": {
                "name": "AML screening alerts",
                "conditions": [
                  {
                    "field": "source",
                    "operator": "equals",
                    "value": "AML_SCREENING"
                  }
                ],
                "blueprint": "b1de0000-0000-4000-8000-000000000002"
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.create(\n    name=\"AML screening alerts\",\n    conditions=[{\n        \"field\": \"source\",\n        \"operator\": \"equals\",\n        \"value\": \"AML_SCREENING\",\n    }],\n    blueprint=\"b1de0000-0000-4000-8000-000000000002\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.create({\n  name: \"AML screening alerts\",\n  conditions: [{\n    field: \"source\",\n    operator: \"equals\",\n    value: \"AML_SCREENING\",\n  }],\n  blueprint: \"b1de0000-0000-4000-8000-000000000002\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Create(ctx, didit.CaseRoutingRuleCreate{\n\tName: \"AML screening alerts\",\n\tConditions: []didit.CaseRoutingConditionParam{{\n\t\tField:    \"source\",\n\t\tOperator: \"equals\",\n\t\tValue:    \"AML_SCREENING\",\n\t}},\n\tBlueprint: \"b1de0000-0000-4000-8000-000000000002\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CaseRoutingCondition;\nimport me.didit.types.CaseRoutingRuleCreate;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().create(CaseRoutingRuleCreate.builder()\n        .name(\"AML screening alerts\")\n        .conditions(List.of(CaseRoutingCondition.builder()\n                .field(CaseRoutingCondition.Field.of(\"source\"))\n                .operator(CaseRoutingCondition.Operator.of(\"equals\"))\n                .value(CaseRoutingCondition.Value.ofString(\"AML_SCREENING\"))\n                .build()))\n        .blueprint(\"b1de0000-0000-4000-8000-000000000002\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->create([\n    'name' => 'AML screening alerts',\n    'conditions' => [[\n        'field' => 'source',\n        'operator' => 'equals',\n        'value' => 'AML_SCREENING',\n    ]],\n    'blueprint' => 'b1de0000-0000-4000-8000-000000000002',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.create(\n  name: \"AML screening alerts\",\n  conditions: [{\n    field: \"source\",\n    operator: \"equals\",\n    value: \"AML_SCREENING\",\n  }],\n  blueprint: \"b1de0000-0000-4000-8000-000000000002\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.CreateAsync(new CaseRoutingRuleCreate\n{\n    Name = \"AML screening alerts\",\n    Conditions = new CaseRoutingCondition[]\n    {\n        new()\n        {\n            Field = \"source\",\n            Operator = \"equals\",\n            Value = \"AML_SCREENING\",\n        },\n    },\n    Blueprint = \"b1de0000-0000-4000-8000-000000000002\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/{record_uuid}/publish/": {
      "post": {
        "operationId": "publish_case_routing_rule",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "publish",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "record_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Assignment"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftPreconditionRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftPreconditionRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftPreconditionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoutingPublicationCaseRoutingRule"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "케이스 접근 권한이 필요합니다."
          },
          "409": {
            "description": "게시된 버전 또는 초안 리비전이 변경되었습니다. 다시 시도하기 전에 다시 로드하십시오."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.publish(\n    \"11111111-2222-3333-4444-555555555555\",\n    expected_version=0,\n    expected_revision=\"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.publish(\"11111111-2222-3333-4444-555555555555\", {\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Publish(ctx, \"11111111-2222-3333-4444-555555555555\", didit.RoutingPublicationPolicyDraftPreconditionRequest{\n\tExpectedVersion:  0,\n\tExpectedRevision: didit.String(\"11111111-2222-3333-4444-555555555555\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.RoutingPublicationPolicyDraftPreconditionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().publish(\"11111111-2222-3333-4444-555555555555\", RoutingPublicationPolicyDraftPreconditionRequest.builder()\n        .expectedVersion(0L)\n        .expectedRevision(\"11111111-2222-3333-4444-555555555555\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->publish('11111111-2222-3333-4444-555555555555', [\n    'expected_version' => 0,\n    'expected_revision' => '11111111-2222-3333-4444-555555555555',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.publish(\n  \"11111111-2222-3333-4444-555555555555\",\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.PublishAsync(\"11111111-2222-3333-4444-555555555555\", new RoutingPublicationPolicyDraftPreconditionRequest\n{\n    ExpectedVersion = 0,\n    ExpectedRevision = \"11111111-2222-3333-4444-555555555555\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/{blueprint_uuid}/publish/": {
      "post": {
        "operationId": "publish_case_blueprint",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "publish",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "blueprint_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftPreconditionRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftPreconditionRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftPreconditionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CasePublicationCaseBlueprint"
                }
              }
            },
            "description": ""
          },
          "409": {
            "description": "게시된 버전 또는 저장된 임시 리비전이 변경되었습니다. 다시 시도하기 전에 다시 로드하십시오."
          },
          "403": {
            "description": "필수 케이스 권한이 누락되었습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.publish(\n    \"11111111-2222-3333-4444-555555555555\",\n    expected_version=0,\n    expected_revision=\"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.publish(\"11111111-2222-3333-4444-555555555555\", {\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.Publish(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasePublicationPolicyDraftPreconditionRequest{\n\tExpectedVersion:  0,\n\tExpectedRevision: didit.String(\"11111111-2222-3333-4444-555555555555\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasePublicationPolicyDraftPreconditionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().publish(\"11111111-2222-3333-4444-555555555555\", CasePublicationPolicyDraftPreconditionRequest.builder()\n        .expectedVersion(0L)\n        .expectedRevision(\"11111111-2222-3333-4444-555555555555\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->publish('11111111-2222-3333-4444-555555555555', [\n    'expected_version' => 0,\n    'expected_revision' => '11111111-2222-3333-4444-555555555555',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.publish(\n  \"11111111-2222-3333-4444-555555555555\",\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.PublishAsync(\"11111111-2222-3333-4444-555555555555\", new CasePublicationPolicyDraftPreconditionRequest\n{\n    ExpectedVersion = 0,\n    ExpectedRevision = \"11111111-2222-3333-4444-555555555555\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/requests/preview/": {
      "post": {
        "operationId": "organization_application_cases_requests_preview_create",
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "preview",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseRequestPreviewRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseRequestPreviewRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseRequestPreviewRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingCaseRequestPreviewResponse"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "이 호출자에게는 요청 또는 케이스를 사용할 수 없습니다."
          },
          "403": {
            "description": "호출자에게 필요한 케이스 권한이 없습니다."
          },
          "400": {
            "description": "유효하지 않은 입력, 지원되지 않는 목적, 사용할 수 없는 인증된 연락처, 또는 기존의 변경 불가능한 응답입니다."
          },
          "409": {
            "description": "미리보기가 변경되었거나 만료되었습니다. 확인하기 전에 다시 미리보기를 진행하십시오."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "케이스를 변경하거나 전송하지 않고 프로덕션 이메일을 렌더링합니다. 정확한 수신자, 발신자, 제목, 본문 및 서명된 preview_token을 반환합니다. 15분 이내에 확인하려면 동일한 contact_id, purpose, language, request_id, expires_at 및 preview_token을 전송하십시오.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.preview(\n    \"11111111-2222-3333-4444-555555555555\",\n    contact_id=\"11111111-2222-3333-4444-555555555555\",\n    purpose=\"identity_document\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.preview(\"11111111-2222-3333-4444-555555555555\", {\n  contact_id: \"11111111-2222-3333-4444-555555555555\",\n  purpose: \"identity_document\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.Preview(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CustomerMessagingCaseRequestPreviewRequest{\n\tContactID: \"11111111-2222-3333-4444-555555555555\",\n\tPurpose:   didit.CustomerMessagingPurposeEnum(\"identity_document\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CustomerMessagingCaseRequestPreviewRequest;\nimport me.didit.types.CustomerMessagingPurposeEnum;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().preview(\"11111111-2222-3333-4444-555555555555\", CustomerMessagingCaseRequestPreviewRequest.builder()\n        .contactId(\"11111111-2222-3333-4444-555555555555\")\n        .purpose(CustomerMessagingPurposeEnum.of(\"identity_document\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->requests->preview('11111111-2222-3333-4444-555555555555', [\n    'contact_id' => '11111111-2222-3333-4444-555555555555',\n    'purpose' => 'identity_document',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.preview(\n  \"11111111-2222-3333-4444-555555555555\",\n  contact_id: \"11111111-2222-3333-4444-555555555555\",\n  purpose: \"identity_document\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.PreviewAsync(\"11111111-2222-3333-4444-555555555555\", new CustomerMessagingCaseRequestPreviewRequest\n{\n    ContactId = \"11111111-2222-3333-4444-555555555555\",\n    Purpose = \"identity_document\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/action-receipts/": {
      "get": {
        "operationId": "action_receipts_retrieve",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "list_action_receipts",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "query",
            "name": "offset",
            "schema": {
              "type": "integer",
              "maximum": 1000000,
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseActionCaseActionReceiptPage"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "주체-작업 영수증을 최신순으로 페이지당 최대 20개 결과로 나열합니다. 다음 페이지에는 next_offset을 사용하십시오. 입력 메모 텍스트는 기록에 노출되지 않습니다.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.list_action_receipts(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.listActionReceipts(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ListActionReceipts(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesListActionReceiptsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().listActionReceipts(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->listActionReceipts('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.list_action_receipts(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ListActionReceiptsAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/notes/{note_uuid}/": {
      "delete": {
        "operationId": "delete_network_note",
        "x-didit-sdk": {
          "resource": "networks.notes",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "summary": "내 네트워크 메모 삭제",
        "description": "write:networks 권한 및 메모의 인증된 작성자가 필요합니다. 삭제하면 되돌릴 수 없습니다. 연결된 계정 및 인증 데이터에는 영향을 주지 않습니다.",
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "네트워크 UUID입니다."
          },
          {
            "name": "note_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Bearer <token> 형식의 콘솔 사용자 액세스 token입니다."
          }
        ],
        "responses": {
          "204": {
            "description": "메모가 삭제되었습니다."
          },
          "401": {
            "description": "인증이 필요합니다."
          },
          "403": {
            "description": "권한 또는 Networks 접근 권한이 누락되었습니다."
          },
          "404": {
            "description": "네트워크 또는 메모가 이 애플리케이션에 표시되지 않습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\nclient = Didit()\n\nclient.networks.notes.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n    extra_headers={\"Authorization\": \"Bearer YOUR_CONSOLE_USER_TOKEN\"},\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nconst didit = new Didit({\n  fetch: (url, init) => {\n    const headers = new Headers(init?.headers);\n    headers.set(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\");\n    return fetch(url, { ...init, headers });\n  },\n});\n\nawait didit.networks.notes.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nclient := didit.NewClient()\n\nif err := client.Networks.Notes.Delete(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", didit.NetworksNotesDeleteParams{\n\tAuthorization: \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n}); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.core.RequestOptions;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nDidit client = new Didit();\n\nclient.networks().notes().delete(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", RequestOptions.builder()\n        .header(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\")\n        .build());"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\n$didit = new DiditClient();\n\n$didit->networks->notes->delete('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555', [\n    'authorization' => 'Bearer YOUR_CONSOLE_USER_TOKEN',\n]);"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\ndidit = Didit::Client.new\n\ndidit.networks.notes.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n  request_options: { extra_headers: { \"Authorization\" => \"Bearer YOUR_CONSOLE_USER_TOKEN\" } }\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nusing var client = new DiditClient();\n\nawait client.Networks.Notes.DeleteAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", requestOptions: new RequestOptions\n{\n    Headers = new Dictionary<string, string>\n    {\n        [\"Authorization\"] = \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n    },\n});"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/action-receipts/{receipt_uuid}/retry/": {
      "post": {
        "operationId": "action_receipts_retry_create",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "retry_action_receipt",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "receipt_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseActionCaseActionReceipt"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "저장된 입력을 사용하여 실패한 이 주체 작업만 재시도합니다. 현재 쓰기 권한을 확인합니다. 적용된 작업은 다시 실행되지 않고 영수증을 반환합니다. 케이스 마감은 독립적입니다.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.retry_action_receipt(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.retryActionReceipt(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RetryActionReceipt(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().retryActionReceipt(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->retryActionReceipt('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.retry_action_receipt(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RetryActionReceiptAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/{blueprint_uuid}/draft/": {
      "get": {
        "operationId": "get_case_blueprint_draft",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "retrieve_draft",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "blueprint_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CasePublicationPolicyDraftResponse"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "필수 케이스 권한이 누락되었습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.retrieve_draft(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.retrieveDraft(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.RetrieveDraft(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().retrieveDraft(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->retrieveDraft('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.retrieve_draft(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.RetrieveDraftAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "put": {
        "operationId": "save_case_blueprint_draft",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "save_draft",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "blueprint_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftWriteRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftWriteRequest"
              },
              "example": {
                "expected_version": 1,
                "expected_revision": "4e5f0000-0000-4000-8000-000000000003",
                "changes": {
                  "max_active_cases": 20
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftWriteRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CasePublicationPolicyDraft"
                }
              }
            },
            "description": ""
          },
          "409": {
            "description": "게시된 버전 또는 저장된 임시 리비전이 변경되었습니다. 다시 시도하기 전에 다시 로드하십시오."
          },
          "403": {
            "description": "필수 케이스 권한이 누락되었습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.save_draft(\n    \"11111111-2222-3333-4444-555555555555\",\n    expected_version=1,\n    expected_revision=\"4e5f0000-0000-4000-8000-000000000003\",\n    changes={\"max_active_cases\": 20},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.saveDraft(\"11111111-2222-3333-4444-555555555555\", {\n  expected_version: 1,\n  expected_revision: \"4e5f0000-0000-4000-8000-000000000003\",\n  changes: { max_active_cases: 20 },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.SaveDraft(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasePublicationPolicyDraftWriteRequest{\n\tExpectedVersion:  1,\n\tExpectedRevision: didit.String(\"4e5f0000-0000-4000-8000-000000000003\"),\n\tChanges:          map[string]any{\"max_active_cases\": 20},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.CasePublicationPolicyDraftWriteRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().saveDraft(\"11111111-2222-3333-4444-555555555555\", CasePublicationPolicyDraftWriteRequest.builder()\n        .expectedVersion(1L)\n        .expectedRevision(\"4e5f0000-0000-4000-8000-000000000003\")\n        .changes(Map.of(\"max_active_cases\", 20))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->saveDraft('11111111-2222-3333-4444-555555555555', [\n    'expected_version' => 1,\n    'expected_revision' => '4e5f0000-0000-4000-8000-000000000003',\n    'changes' => ['max_active_cases' => 20],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.save_draft(\n  \"11111111-2222-3333-4444-555555555555\",\n  expected_version: 1,\n  expected_revision: \"4e5f0000-0000-4000-8000-000000000003\",\n  changes: { max_active_cases: 20 }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.SaveDraftAsync(\"11111111-2222-3333-4444-555555555555\", new CasePublicationPolicyDraftWriteRequest\n{\n    ExpectedVersion = 1,\n    ExpectedRevision = \"4e5f0000-0000-4000-8000-000000000003\",\n    Changes = new Dictionary<string, object> { [\"max_active_cases\"] = 20 },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "operationId": "discard_case_blueprint_draft",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "discard_draft",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "blueprint_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "204": {
            "description": "응답 본문 없음"
          },
          "409": {
            "description": "게시된 버전 또는 저장된 임시 리비전이 변경되었습니다. 다시 시도하기 전에 다시 로드하십시오."
          },
          "403": {
            "description": "필수 케이스 권한이 누락되었습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftPreconditionRequest"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.blueprints.discard_draft(\n    \"11111111-2222-3333-4444-555555555555\",\n    expected_version=0,\n    expected_revision=\"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.blueprints.discardDraft(\"11111111-2222-3333-4444-555555555555\", {\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\",\n});"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Blueprints.DiscardDraft(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasePublicationPolicyDraftPreconditionRequest{\n\tExpectedVersion:  0,\n\tExpectedRevision: didit.String(\"11111111-2222-3333-4444-555555555555\"),\n}); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasePublicationPolicyDraftPreconditionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().blueprints().discardDraft(\"11111111-2222-3333-4444-555555555555\", CasePublicationPolicyDraftPreconditionRequest.builder()\n        .expectedVersion(0L)\n        .expectedRevision(\"11111111-2222-3333-4444-555555555555\")\n        .build());"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->cases->blueprints->discardDraft('11111111-2222-3333-4444-555555555555', [\n    'expected_version' => 0,\n    'expected_revision' => '11111111-2222-3333-4444-555555555555',\n]);"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.blueprints.discard_draft(\n  \"11111111-2222-3333-4444-555555555555\",\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\"\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.Blueprints.DiscardDraftAsync(\"11111111-2222-3333-4444-555555555555\", new CasePublicationPolicyDraftPreconditionRequest\n{\n    ExpectedVersion = 0,\n    ExpectedRevision = \"11111111-2222-3333-4444-555555555555\",\n});"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/teams/{record_uuid}/": {
      "get": {
        "summary": "검토 팀 조회",
        "description": "요청된 애플리케이션에 대한 `read:cases` 권한이 필요합니다.",
        "operationId": "retrieve_case_teams",
        "x-didit-sdk": {
          "resource": "cases.teams",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "record_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseReviewTeam"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 입력입니다."
          },
          "403": {
            "description": "권한이 부족합니다."
          },
          "404": {
            "description": "이 애플리케이션에서 레코드를 찾을 수 없습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.teams.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.teams.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Teams.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().teams().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->teams->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.teams.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Teams.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "patch": {
        "summary": "검토 팀 업데이트",
        "description": "요청된 애플리케이션에 대한 `write:cases` 권한이 필요합니다.",
        "operationId": "update_case_teams",
        "x-didit-sdk": {
          "resource": "cases.teams",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "record_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseReviewTeam"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 입력입니다."
          },
          "403": {
            "description": "권한이 부족합니다."
          },
          "404": {
            "description": "이 애플리케이션에서 레코드를 찾을 수 없습니다."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseReviewTeamUpdate"
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.teams.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    name=\"your-name\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.teams.update(\"11111111-2222-3333-4444-555555555555\", {\n  name: \"your-name\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Teams.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CaseReviewTeamUpdate{\n\tName: didit.String(\"your-name\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CaseReviewTeamUpdate;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().teams().update(\"11111111-2222-3333-4444-555555555555\", CaseReviewTeamUpdate.builder()\n        .name(\"your-name\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->teams->update('11111111-2222-3333-4444-555555555555', [\n    'name' => 'your-name',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.teams.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  name: \"your-name\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Teams.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new CaseReviewTeamUpdate\n{\n    Name = \"your-name\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/report/": {
      "get": {
        "operationId": "download_network_report",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "download_report",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "summary": "네트워크 증거 보고서 다운로드",
        "description": "현재 조직 네트워크, 관찰된 계정 연결, 시그널 참조 및 검토 상태에 대한 PDF를 다운로드합니다. read:networks 권한이 필요합니다. 글로벌 인텔리전스 및 비공개 분석가 메모는 포함되지 않습니다. 각 계정 및 시그널 목록은 최대 500개 항목으로 제한되며 보고서에 불완전 여부가 명시됩니다. 요청으로 인해 네트워크 상태가 변경되지 않습니다. 오류는 JSON으로 반환됩니다.",
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "네트워크 UUID입니다."
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Bearer <token> 형식의 콘솔 사용자 액세스 token입니다."
          }
        ],
        "responses": {
          "200": {
            "description": "네트워크 증거 보고서입니다. Cache-Control: no-store.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "인증이 필요합니다."
          },
          "403": {
            "description": "권한 또는 Networks 접근 권한이 누락되었습니다."
          },
          "404": {
            "description": "네트워크 또는 메모가 이 애플리케이션에 표시되지 않습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\nclient = Didit()\n\ncontent = client.networks.download_report(\n    \"11111111-2222-3333-4444-555555555555\",\n    extra_headers={\"Authorization\": \"Bearer YOUR_CONSOLE_USER_TOKEN\"},\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nconst didit = new Didit({\n  fetch: (url, init) => {\n    const headers = new Headers(init?.headers);\n    headers.set(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\");\n    return fetch(url, { ...init, headers });\n  },\n});\n\nconst content = await didit.networks.downloadReport(\"11111111-2222-3333-4444-555555555555\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nclient := didit.NewClient()\n\nresp, err := client.Networks.DownloadReport(ctx, \"11111111-2222-3333-4444-555555555555\", didit.NetworksDownloadReportParams{\n\tAuthorization: \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.core.RequestOptions;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nDidit client = new Didit();\n\nclient.networks().downloadReport(\"11111111-2222-3333-4444-555555555555\", RequestOptions.builder()\n        .header(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\")\n        .build())\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\n$didit = new DiditClient();\n\n$content = $didit->networks->downloadReport('11111111-2222-3333-4444-555555555555', [\n    'authorization' => 'Bearer YOUR_CONSOLE_USER_TOKEN',\n]);\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\ndidit = Didit::Client.new\n\ncontent = didit.networks.download_report(\n  \"11111111-2222-3333-4444-555555555555\",\n  request_options: { extra_headers: { \"Authorization\" => \"Bearer YOUR_CONSOLE_USER_TOKEN\" } }\n)\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nusing var client = new DiditClient();\n\nvar content = await client.Networks.DownloadReportAsync(\"11111111-2222-3333-4444-555555555555\", requestOptions: new RequestOptions\n{\n    Headers = new Dictionary<string, string>\n    {\n        [\"Authorization\"] = \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n    },\n});\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/notes/": {
      "get": {
        "operationId": "list_network_notes",
        "x-didit-sdk": {
          "resource": "networks.notes",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "summary": "비공개 네트워크 메모 목록 조회",
        "description": "read:networks 권한이 있는 콘솔 사용자는 애플리케이션에 표시되는 네트워크에 대한 메모를 읽을 수 있습니다. 메모는 조직 내에 유지되며 공유 인텔리전스에 기여되지 않습니다. 최신 메모가 먼저 표시됩니다.",
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "네트워크 UUID입니다."
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Bearer <token> 형식의 콘솔 사용자 액세스 token입니다."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 1000000,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "메모 페이지입니다. 개수는 최대 100개로 제한되며, 계속하려면 next를 사용하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NetworkNote"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "인증이 필요합니다."
          },
          "403": {
            "description": "권한 또는 Networks 접근 권한이 누락되었습니다."
          },
          "404": {
            "description": "네트워크 또는 메모가 이 애플리케이션에 표시되지 않습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\nclient = Didit()\n\nfor item in client.networks.notes.list(\n    \"11111111-2222-3333-4444-555555555555\",\n    extra_headers={\"Authorization\": \"Bearer YOUR_CONSOLE_USER_TOKEN\"},\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nconst didit = new Didit({\n  fetch: (url, init) => {\n    const headers = new Headers(init?.headers);\n    headers.set(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\");\n    return fetch(url, { ...init, headers });\n  },\n});\n\nfor await (const item of didit.networks.notes.list(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nclient := didit.NewClient()\n\niter := client.Networks.Notes.ListAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.NetworksNotesListParams{\n\tAuthorization: \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.core.RequestOptions;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nDidit client = new Didit();\n\nfor (var item : client.networks().notes().list(\"11111111-2222-3333-4444-555555555555\", RequestOptions.builder()\n        .header(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\")\n        .build())) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\n$didit = new DiditClient();\n\nforeach ($didit->networks->notes->list('11111111-2222-3333-4444-555555555555', [\n    'authorization' => 'Bearer YOUR_CONSOLE_USER_TOKEN',\n]) as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\ndidit = Didit::Client.new\n\ndidit.networks.notes.list(\n  \"11111111-2222-3333-4444-555555555555\",\n  request_options: { extra_headers: { \"Authorization\" => \"Bearer YOUR_CONSOLE_USER_TOKEN\" } }\n).auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Networks.Notes.ListAsync(\"11111111-2222-3333-4444-555555555555\", requestOptions: new RequestOptions\n{\n    Headers = new Dictionary<string, string>\n    {\n        [\"Authorization\"] = \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n    },\n}))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "operationId": "create_network_note",
        "x-didit-sdk": {
          "resource": "networks.notes",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "summary": "비공개 네트워크 메모 추가",
        "description": "write:networks 권한을 가진 콘솔 사용자가 필요합니다. 작성자는 인증된 사용자로 할당됩니다. 각 메모마다 새로운 무작위 UUID client_reference를 제공하세요. 중복 생성을 방지하려면 응답이 불확실한 경우 동일한 본문과 참조값으로 재시도하세요. 다른 본문, 작성자 또는 네트워크에 참조값을 재사용하면 409가 반환됩니다. 네트워크가 병합되면 메모는 존속되는 조사 건으로 이전됩니다.",
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "네트워크 UUID입니다."
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Bearer <token> 형식의 콘솔 사용자 액세스 token입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "comment",
                  "client_reference"
                ],
                "properties": {
                  "comment": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 10000
                  },
                  "client_reference": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "저장된 비공개 메모입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkNote"
                }
              }
            }
          },
          "200": {
            "description": "저장된 비공개 메모입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkNote"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않거나 비어 있는 메모입니다."
          },
          "409": {
            "description": "해당 참조는 이미 다른 메모에 사용되었습니다."
          },
          "401": {
            "description": "인증이 필요합니다."
          },
          "403": {
            "description": "권한 또는 Networks 접근 권한이 누락되었습니다."
          },
          "404": {
            "description": "네트워크 또는 메모가 이 애플리케이션에 표시되지 않습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\nclient = Didit()\n\nresult = client.networks.notes.create(\n    \"11111111-2222-3333-4444-555555555555\",\n    comment=\"your-comment\",\n    client_reference=\"11111111-2222-3333-4444-555555555555\",\n    extra_headers={\"Authorization\": \"Bearer YOUR_CONSOLE_USER_TOKEN\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nconst didit = new Didit({\n  fetch: (url, init) => {\n    const headers = new Headers(init?.headers);\n    headers.set(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\");\n    return fetch(url, { ...init, headers });\n  },\n});\n\nconst result = await didit.networks.notes.create(\"11111111-2222-3333-4444-555555555555\", {\n  comment: \"your-comment\",\n  client_reference: \"11111111-2222-3333-4444-555555555555\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nclient := didit.NewClient()\n\nresult, err := client.Networks.Notes.Create(ctx, \"11111111-2222-3333-4444-555555555555\", didit.NetworksNotesCreateParams{\n\tComment:         \"your-comment\",\n\tClientReference: \"11111111-2222-3333-4444-555555555555\",\n\tAuthorization:   \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.core.RequestOptions;\nimport me.didit.types.NetworksNotesCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nDidit client = new Didit();\n\nvar result = client.networks().notes().create(\"11111111-2222-3333-4444-555555555555\", NetworksNotesCreateParams.builder()\n        .comment(\"your-comment\")\n        .clientReference(\"11111111-2222-3333-4444-555555555555\")\n        .build(), RequestOptions.builder()\n        .header(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\n$didit = new DiditClient();\n\n$result = $didit->networks->notes->create('11111111-2222-3333-4444-555555555555', [\n    'comment' => 'your-comment',\n    'client_reference' => '11111111-2222-3333-4444-555555555555',\n    'authorization' => 'Bearer YOUR_CONSOLE_USER_TOKEN',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\ndidit = Didit::Client.new\n\nresult = didit.networks.notes.create(\n  \"11111111-2222-3333-4444-555555555555\",\n  comment: \"your-comment\",\n  client_reference: \"11111111-2222-3333-4444-555555555555\",\n  request_options: { extra_headers: { \"Authorization\" => \"Bearer YOUR_CONSOLE_USER_TOKEN\" } }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.Notes.CreateAsync(\"11111111-2222-3333-4444-555555555555\", new NetworksNotesCreateParams\n{\n    Comment = \"your-comment\",\n    ClientReference = \"11111111-2222-3333-4444-555555555555\",\n}, requestOptions: new RequestOptions\n{\n    Headers = new Dictionary<string, string>\n    {\n        [\"Authorization\"] = \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/{record_uuid}/draft/": {
      "get": {
        "operationId": "get_case_routing_rule_draft",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "retrieve_draft",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "record_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Assignment"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoutingPublicationPolicyDraftResponse"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "케이스 접근 권한이 필요합니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.retrieve_draft(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.retrieveDraft(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.RetrieveDraft(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().retrieveDraft(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->retrieveDraft('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.retrieve_draft(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.RetrieveDraftAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "put": {
        "operationId": "save_case_routing_rule_draft",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "save_draft",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "record_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Assignment"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftWriteRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftWriteRequest"
              },
              "example": {
                "expected_version": 1,
                "expected_revision": "4e5f0000-0000-4000-8000-000000000003",
                "changes": {
                  "priority": 10
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftWriteRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoutingPublicationPolicyDraft"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "케이스 접근 권한이 필요합니다."
          },
          "409": {
            "description": "게시된 버전 또는 초안 리비전이 변경되었습니다. 다시 시도하기 전에 다시 로드하십시오."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.save_draft(\n    \"11111111-2222-3333-4444-555555555555\",\n    expected_version=1,\n    expected_revision=\"4e5f0000-0000-4000-8000-000000000003\",\n    changes={\"priority\": 10},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.saveDraft(\"11111111-2222-3333-4444-555555555555\", {\n  expected_version: 1,\n  expected_revision: \"4e5f0000-0000-4000-8000-000000000003\",\n  changes: { priority: 10 },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.SaveDraft(ctx, \"11111111-2222-3333-4444-555555555555\", didit.RoutingPublicationPolicyDraftWriteRequest{\n\tExpectedVersion:  1,\n\tExpectedRevision: didit.String(\"4e5f0000-0000-4000-8000-000000000003\"),\n\tChanges:          map[string]any{\"priority\": 10},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.RoutingPublicationPolicyDraftWriteRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().saveDraft(\"11111111-2222-3333-4444-555555555555\", RoutingPublicationPolicyDraftWriteRequest.builder()\n        .expectedVersion(1L)\n        .expectedRevision(\"4e5f0000-0000-4000-8000-000000000003\")\n        .changes(Map.of(\"priority\", 10))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->saveDraft('11111111-2222-3333-4444-555555555555', [\n    'expected_version' => 1,\n    'expected_revision' => '4e5f0000-0000-4000-8000-000000000003',\n    'changes' => ['priority' => 10],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.save_draft(\n  \"11111111-2222-3333-4444-555555555555\",\n  expected_version: 1,\n  expected_revision: \"4e5f0000-0000-4000-8000-000000000003\",\n  changes: { priority: 10 }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.SaveDraftAsync(\"11111111-2222-3333-4444-555555555555\", new RoutingPublicationPolicyDraftWriteRequest\n{\n    ExpectedVersion = 1,\n    ExpectedRevision = \"4e5f0000-0000-4000-8000-000000000003\",\n    Changes = new Dictionary<string, object> { [\"priority\"] = 10 },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "operationId": "discard_case_routing_rule_draft",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "discard_draft",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "record_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Assignment"
        ],
        "responses": {
          "204": {
            "description": "응답 본문 없음"
          },
          "403": {
            "description": "케이스 접근 권한이 필요합니다."
          },
          "409": {
            "description": "게시된 버전 또는 초안 리비전이 변경되었습니다. 다시 시도하기 전에 다시 로드하십시오."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftPreconditionRequest"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.routing_rules.discard_draft(\n    \"11111111-2222-3333-4444-555555555555\",\n    expected_version=0,\n    expected_revision=\"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.routingRules.discardDraft(\"11111111-2222-3333-4444-555555555555\", {\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\",\n});"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.RoutingRules.DiscardDraft(ctx, \"11111111-2222-3333-4444-555555555555\", didit.RoutingPublicationPolicyDraftPreconditionRequest{\n\tExpectedVersion:  0,\n\tExpectedRevision: didit.String(\"11111111-2222-3333-4444-555555555555\"),\n}); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.RoutingPublicationPolicyDraftPreconditionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().routingRules().discardDraft(\"11111111-2222-3333-4444-555555555555\", RoutingPublicationPolicyDraftPreconditionRequest.builder()\n        .expectedVersion(0L)\n        .expectedRevision(\"11111111-2222-3333-4444-555555555555\")\n        .build());"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->cases->routingRules->discardDraft('11111111-2222-3333-4444-555555555555', [\n    'expected_version' => 0,\n    'expected_revision' => '11111111-2222-3333-4444-555555555555',\n]);"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.routing_rules.discard_draft(\n  \"11111111-2222-3333-4444-555555555555\",\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\"\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.RoutingRules.DiscardDraftAsync(\"11111111-2222-3333-4444-555555555555\", new RoutingPublicationPolicyDraftPreconditionRequest\n{\n    ExpectedVersion = 0,\n    ExpectedRevision = \"11111111-2222-3333-4444-555555555555\",\n});"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/duplicates/": {
      "post": {
        "operationId": "duplicates_create",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "find_duplicates",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CaseDuplicateCaseDuplicateQueryRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseDuplicateCaseDuplicateQueryRequest"
              },
              "example": {
                "subject": {
                  "type": "user",
                  "uuid": "5b9a0000-0000-4000-8000-00000000f00d"
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CaseDuplicateCaseDuplicateQueryRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDuplicateCaseDuplicatePage"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "수동으로 케이스를 생성하기 전에 대상자 또는 소유한 소스 레코드에 대한 기존 케이스를 검토합니다. 미해결 및 해결된 조사가 모두 반환됩니다. 각 페이지에는 최대 20개의 케이스가 포함되며, 다른 페이지를 요청하려면 next_offset을 사용하십시오.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.find_duplicates(\n    subject={\n        \"type\": \"user\",\n        \"uuid\": \"5b9a0000-0000-4000-8000-00000000f00d\",\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.findDuplicates({\n  subject: {\n    type: \"user\",\n    uuid: \"5b9a0000-0000-4000-8000-00000000f00d\",\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.FindDuplicates(ctx, didit.CaseDuplicateCaseDuplicateQueryRequest{\n\tSubject: didit.Some(didit.CaseDuplicateCaseSubjectInputRequest{\n\t\tType: didit.CaseDuplicateTypeEnum(\"user\"),\n\t\tUUID: \"5b9a0000-0000-4000-8000-00000000f00d\",\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CaseDuplicateCaseDuplicateQueryRequest;\nimport me.didit.types.CaseDuplicateCaseSubjectInputRequest;\nimport me.didit.types.CaseDuplicateTypeEnum;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().findDuplicates(CaseDuplicateCaseDuplicateQueryRequest.builder()\n        .subject(CaseDuplicateCaseSubjectInputRequest.builder()\n                .type(CaseDuplicateTypeEnum.of(\"user\"))\n                .uuid(\"5b9a0000-0000-4000-8000-00000000f00d\")\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->findDuplicates([\n    'subject' => [\n        'type' => 'user',\n        'uuid' => '5b9a0000-0000-4000-8000-00000000f00d',\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.find_duplicates(\n  subject: {\n    type: \"user\",\n    uuid: \"5b9a0000-0000-4000-8000-00000000f00d\",\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.FindDuplicatesAsync(new CaseDuplicateCaseDuplicateQueryRequest\n{\n    Subject = new CaseDuplicateCaseSubjectInputRequest\n    {\n        Type = \"user\",\n        Uuid = \"5b9a0000-0000-4000-8000-00000000f00d\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/preview/": {
      "post": {
        "summary": "테스트 케이스 라우팅",
        "description": "요청된 애플리케이션에 대한 `read:cases` 권한이 필요합니다. 현재 검토자의 접근 권한, 가용성, 기술 및 처리 용량을 기준으로 현재 규칙 또는 제공된 초안을 평가합니다. 초안을 저장하거나 검토자 용량을 예약하지는 않습니다.",
        "operationId": "preview_case_routing",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "preview",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseRoutingPreview"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 입력입니다."
          },
          "403": {
            "description": "권한이 부족합니다."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseRoutingPreviewRequest"
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.preview(\n    source=\"MANUAL\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.preview({\n  source: \"MANUAL\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Preview(ctx, didit.CaseRoutingPreviewRequest{\n\tSource: \"MANUAL\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CaseRoutingPreviewRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().preview(CaseRoutingPreviewRequest.builder()\n        .source(CaseRoutingPreviewRequest.Source.of(\"MANUAL\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->preview([\n    'source' => 'MANUAL',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.preview(source: \"MANUAL\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.PreviewAsync(new CaseRoutingPreviewRequest\n{\n    Source = \"MANUAL\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/reviewers/": {
      "get": {
        "summary": "자격을 갖춘 케이스 검토자 목록 조회",
        "description": "요청된 애플리케이션에 대한 `list:cases` 권한이 필요합니다.",
        "operationId": "list_case_reviewers",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "list_reviewers",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "user_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "email": {
                            "type": "string",
                            "format": "email"
                          },
                          "name": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 입력입니다."
          },
          "403": {
            "description": "권한이 부족합니다."
          },
          "503": {
            "description": "검토자 권한을 확인할 수 없습니다. 나중에 다시 시도하십시오."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.list_reviewers()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.listReviewers();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ListReviewers(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().listReviewers();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->listReviewers();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.list_reviewers\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ListReviewersAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/{blueprint_uuid}/history/": {
      "get": {
        "operationId": "list_case_blueprint_history",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "list_history",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "blueprint_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "결과를 정렬할 때 사용할 필드입니다.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "페이지당 반환할 결과 수입니다.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "description": "결과 반환을 시작할 초기 인덱스입니다.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CasePublicationPaginatedPolicyRevisionList"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "필수 케이스 권한이 누락되었습니다."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.blueprints.list_history(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.blueprints.listHistory(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Blueprints.ListHistoryAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesBlueprintsListHistoryParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().blueprints().listHistory(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->blueprints->listHistory('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.blueprints.list_history(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Blueprints.ListHistoryAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/signatures/{nodeId}/documents/{documentId}/file/": {
      "get": {
        "summary": "서명된 문서 다운로드",
        "description": "전자 서명 단계 문서 하나의 서명된 PDF를 다운로드합니다. 결정 내 `signatures[].documents[]`의 `signed_file` 경로를 사용하세요. PDF에는 서명자에게 표시된 문서에 필드 값이 각인된 내용과 증거 페이지가 포함됩니다(`signature_evidence_page`가 꺼져 있지 않은 경우). 고급(AES) PDF에는 타임스탬프가 포함된 PAdES 서명도 포함되지만, 단순 PDF에는 디지털 서명, 직인 또는 타임스탬프가 없습니다. Didit은 파일을 반환하기 전에 `sha256_signed`와 대조하여 확인합니다.\n\n사용자 인증(KYC) 및 기업 확인(KYB) 세션에서 작동합니다. `read:sessions` 권한이 필요하며, 기존 API 키를 사용할 수 있습니다. [전자 서명 보고서](/ko/core-technology/electronic-signature/report-electronic-signature#서명된-문서-다운로드)를 참조하세요.",
        "operationId": "get_v3_session_signature_document_file",
        "x-didit-sdk": {
          "resource": "sessions.signatures",
          "method": "download_document",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "사용자 인증(KYC) 또는 기업 확인(KYB) 세션입니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "required": true,
            "description": "전자 서명 단계: `signatures[]` 항목의 `node_id`입니다.",
            "schema": {
              "type": "string",
              "example": "feature_signature"
            }
          },
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "description": "`signatures[].documents[]` 내 문서의 `id`입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "서명된 PDF입니다.",
            "headers": {
              "Content-Disposition": {
                "description": "파일 이름이 포함된 첨부 파일입니다.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=\"agreement-signed.pdf\""
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나, 이 세션을 읽을 수 없는 자격 증명입니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "You do not have permission to perform this action."
                }
              }
            }
          },
          "404": {
            "description": "일치하는 서명 문서가 없습니다. 세션, 단계 또는 문서가 존재하지 않거나, 삭제되었거나, 아직 서명되지 않았습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not signed yet": {
                    "summary": "서명자가 서명하지 않았습니다",
                    "value": {
                      "code": "signature_not_signed",
                      "detail": "signature_not_signed"
                    }
                  },
                  "Unknown document": {
                    "summary": "이 단계에 해당 문서가 없습니다",
                    "value": {
                      "code": "signature_not_found",
                      "detail": "signature_not_found"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "저장된 파일이 기록된 SHA-256과 더 이상 일치하지 않습니다. 아무것도 반환되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Changed file": {
                    "summary": "저장된 파일이 해시와 일치하지 않습니다",
                    "value": {
                      "code": "signature_document_changed",
                      "detail": "signature_document_changed"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.signatures.download_document(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"feature_signature\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.signatures.downloadDocument(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.Signatures.DownloadDocument(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().signatures().downloadDocument(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\")\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->sessions->signatures->downloadDocument('11111111-2222-3333-4444-555555555555', 'feature_signature', '11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.signatures.download_document(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.Signatures.DownloadDocumentAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/signatures/{nodeId}/evidence/": {
      "get": {
        "summary": "서명 증거 다운로드",
        "description": "서명자의 증거 PDF를 다운로드합니다: 서명 수준 및 형식, 서명자, IP 주소, 각 문서와 해당 원본 SHA-256 및 필드 값, 모든 서명된 파일의 SHA-256과 함께, 고급(AES) 서명의 경우 확인된 신원 세션, 코드 확인, 인증서 및 타임스탬프가 포함됩니다. `signatures[]`에 있는 서명자 항목의 `evidence_file` 경로를 사용하세요.\n\n기업 확인(KYB) 단계에 여러 서명자가 있는 경우 항상 `signature_id`를 전달하세요. 전달하지 않으면 라우트가 해당 단계의 서명자 중 하나를 선택합니다. `read:sessions` 권한이 필요하며, API 키를 사용할 수 있습니다.",
        "operationId": "get_v3_session_signature_evidence",
        "x-didit-sdk": {
          "resource": "sessions.signatures",
          "method": "download_evidence",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "사용자 인증(KYC) 또는 기업 확인(KYB) 세션입니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "required": true,
            "description": "전자 서명 단계: `signatures[]` 항목의 `node_id`입니다.",
            "schema": {
              "type": "string",
              "example": "feature_signature"
            }
          },
          {
            "name": "signature_id",
            "in": "query",
            "required": false,
            "description": "`signatures[]` 내 서명자 항목의 `id`입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "증거 PDF입니다.",
            "headers": {
              "Content-Disposition": {
                "description": "파일 이름이 포함된 첨부 파일입니다.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=\"signature-evidence.pdf\""
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나, 이 세션을 읽을 수 없는 자격 증명입니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "You do not have permission to perform this action."
                }
              }
            }
          },
          "404": {
            "description": "일치하는 증거가 없습니다. 세션, 단계 또는 서명자가 존재하지 않거나, 삭제되었거나, 서명하지 않았습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not signed yet": {
                    "summary": "서명자가 서명하지 않았습니다",
                    "value": {
                      "code": "signature_not_signed",
                      "detail": "signature_not_signed"
                    }
                  },
                  "Unknown signer": {
                    "summary": "이 단계에 해당 서명이 없습니다",
                    "value": {
                      "code": "signature_not_found",
                      "detail": "signature_not_found"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "저장된 파일이 기록된 SHA-256과 더 이상 일치하지 않습니다. 아무것도 반환되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Changed file": {
                    "summary": "저장된 파일이 해시와 일치하지 않습니다",
                    "value": {
                      "code": "signature_document_changed",
                      "detail": "signature_document_changed"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.signatures.download_evidence(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"feature_signature\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.signatures.downloadEvidence(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n);\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.Signatures.DownloadEvidence(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_signature\", didit.SessionsSignaturesDownloadEvidenceParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().signatures().downloadEvidence(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\")\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->sessions->signatures->downloadEvidence('11111111-2222-3333-4444-555555555555', 'feature_signature');\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.signatures.download_evidence(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\"\n)\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.Signatures.DownloadEvidenceAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\");\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/signatures/{nodeId}/fields/{fieldId}/image/": {
      "get": {
        "summary": "서명 이미지 다운로드",
        "description": "서명자가 필드에 적용한 서명 또는 이니셜을 PNG로 다운로드합니다. `signatures[].documents[].fields[]`에 있는 필드의 `image_url`을 사용하세요. `read:sessions` 권한이 필요하며, API 키를 사용할 수 있습니다.",
        "operationId": "get_v3_session_signature_field_image",
        "x-didit-sdk": {
          "resource": "sessions.signatures",
          "method": "download_field_image",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "사용자 인증(KYC) 또는 기업 확인(KYB) 세션입니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "required": true,
            "description": "전자 서명 단계: `signatures[]` 항목의 `node_id`입니다.",
            "schema": {
              "type": "string",
              "example": "feature_signature"
            }
          },
          {
            "name": "fieldId",
            "in": "path",
            "required": true,
            "description": "해당 서명자의 사본에 있는 필드입니다(필드의 `image_url`에 있는 것처럼).",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "이미지입니다.",
            "content": {
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "저장된 이미지가 기록된 SHA-256과 더 이상 일치하지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "code": "signature_document_changed",
                  "detail": "signature_document_changed"
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나, 이 세션을 읽을 수 없는 자격 증명입니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "You do not have permission to perform this action."
                }
              }
            }
          },
          "404": {
            "description": "일치하는 이미지가 없습니다. 세션, 단계 또는 필드가 존재하지 않거나, 삭제되었거나, 적용된 서명 또는 이니셜이 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Unknown field": {
                    "summary": "해당 필드가 없습니다",
                    "value": {
                      "code": "signature_field_not_found",
                      "detail": "signature_field_not_found"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.signatures.download_field_image(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"feature_signature\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.png\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.signatures.downloadFieldImage(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nawait writeFile(\"download.png\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.Signatures.DownloadFieldImage(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.png\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().signatures().downloadFieldImage(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\")\n        .writeTo(Path.of(\"download.png\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->sessions->signatures->downloadFieldImage('11111111-2222-3333-4444-555555555555', 'feature_signature', '11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.png');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.signatures.download_field_image(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nFile.binwrite(\"download.png\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.Signatures.DownloadFieldImageAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.png\");"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/signatures/{nodeId}/validate/": {
      "post": {
        "summary": "서명 다시 검증",
        "description": "전자 서명 단계의 서명된 문서를 다시 확인합니다. Didit은 서명된 각 PDF를 다시 읽고, 해당 SHA-256을 확인하며, 고급(AES) 서명의 경우 PAdES 서명, 인증서, 철회 데이터 및 타임스탬프를 검증한 다음(일반 서명에는 디지털 서명이 없으므로 파일 무결성만 확인됨) 각 서명자의 `validation`에 결과를 저장하고 업데이트된 항목을 반환합니다. 다시 서명되는 항목은 없습니다. 한 명의 서명자만 확인하려면 `signature_id`를 전송하세요. 이 값이 없으면 해당 단계의 모든 서명자를 확인하며, 서명하지 않은 서명자가 있으면 호출이 실패합니다.\n\n`write:sessions`가 필요하며, API 키로 작동합니다. 콘솔에서는 **Validate again** 버튼입니다.",
        "operationId": "post_v3_session_signature_validate",
        "x-didit-sdk": {
          "resource": "sessions.signatures",
          "method": "validate",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "사용자 인증(KYC) 또는 기업 확인(KYB) 세션입니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "required": true,
            "description": "전자 서명 단계: `signatures[]` 항목의 `node_id`입니다.",
            "schema": {
              "type": "string",
              "example": "feature_signature"
            }
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "signature_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "`signatures[]` 내 특정 서명자 항목의 `id`입니다."
                  }
                }
              },
              "example": {
                "signature_id": "0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "업데이트된 `validation`을 포함한 확인된 서명자입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "signatures": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SignatureResult"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "저장된 서명된 PDF가 서명 시 기록된 SHA-256과 더 이상 일치하지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Document changed": {
                    "summary": "서명된 파일이 해시와 더 이상 일치하지 않습니다.",
                    "value": {
                      "code": "signature_document_changed",
                      "detail": "signature_document_changed"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나, 이 세션을 읽을 수 없는 자격 증명입니다. 키가 누락되면 `403`을 반환하고, 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "You do not have permission to perform this action."
                }
              }
            }
          },
          "404": {
            "description": "일치하는 서명이 없습니다. 세션, 단계 또는 서명자가 존재하지 않거나 삭제되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Unknown signer": {
                    "summary": "이 단계에 해당 서명이 없습니다",
                    "value": {
                      "code": "signature_not_found",
                      "detail": "signature_not_found"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "해당 단계의 서명자가 서명하지 않았으므로 검증할 대상이 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not signed": {
                    "summary": "서명자가 아직 서명하지 않았습니다.",
                    "value": {
                      "code": "signature_not_signed",
                      "detail": "signature_not_signed"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.signatures.validate(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"feature_signature\",\n    signature_id=\"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.signatures.validate(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n  {\n    signature_id: \"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\",\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Signatures.Validate(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_signature\", didit.SessionsSignaturesValidateParams{\n\tSignatureID: didit.String(\"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsSignaturesValidateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().signatures().validate(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", SessionsSignaturesValidateParams.builder()\n        .signatureId(\"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->signatures->validate('11111111-2222-3333-4444-555555555555', 'feature_signature', [\n    'signature_id' => '0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.signatures.validate(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n  signature_id: \"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Signatures.ValidateAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", new SessionsSignaturesValidateParams\n{\n    SignatureId = \"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/document-ai/{sessionId}/documents/{documentUuid}/": {
      "patch": {
        "summary": "Document AI 문서 업데이트",
        "description": "KYC 또는 KYB 세션에서 업로드된 한 문서로부터 Document AI가 추출한 필드를 수정하거나, 검토 상태를 설정하거나, 둘 다 수행합니다. `extracted_data`는 JSON 객체여야 하며 키별로 병합됩니다. 전달한 키는 저장된 값을 대체하고(`null`로 전송된 키는 `null`로 저장됨) 생략한 키는 기존 값을 유지합니다. 문서 상태는 세션 결정에서 워크플로 노드의 Document AI 결과에 반영되며, 세션 상태 자체는 다시 계산되지 않습니다. 아무것도 변경하지 않은 호출을 포함하여 성공한 모든 호출은 트리거 `manual_review`와 함께 `data.updated` [webhook](https://docs.didit.me/ko/integration/webhooks)을 전송합니다. 범위가 지정된 API 키에는 `decisions: write` 권한이 필요합니다. [Document AI](https://docs.didit.me/ko/core-technology/document-ai/overview)를 참고하십시오.",
        "operationId": "patch_v3_document_ai_document",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_document_ai_data",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "인증 세션의 UUID(`POST /v3/session/`에서 반환된 `session_id`)입니다. 사용자 인증(KYC) 및 기업 확인(KYB) 세션 ID를 모두 지원하며, 서버는 두 세션 유형 전체에서 ID를 확인합니다. 올바른 형식의 UUID여야 합니다. 형식이 잘못된 값은 경로와 일치하지 않아 HTML `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "documentUuid",
            "in": "path",
            "required": true,
            "description": "Document AI 문서의 UUID(`GET /v3/session/{sessionId}/decision/`의 `document_ai_documents[].items[].uuid`)입니다. 경로의 세션에 속해 있어야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "44444444-5555-6666-7777-888888888888"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "extracted_data": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "필드 키(해당 문서에 대해 구성한 키)와 수정된 값입니다. JSON 객체여야 하며, 저장된 데이터에 키별로 병합됩니다. `null`을 전송하면 `400`이 반환되므로 생략하십시오.",
                    "example": {
                      "invoice_number": "INV-2026-0042"
                    }
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "Approved",
                      "Declined",
                      "In Review",
                      "Not Finished"
                    ],
                    "description": "문서의 새 검토 상태입니다.",
                    "example": "Approved"
                  }
                }
              },
              "example": {
                "extracted_data": {
                  "invoice_number": "INV-2026-0042"
                },
                "status": "Approved"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/document-ai/11111111-2222-3333-4444-555555555555/documents/44444444-5555-6666-7777-888888888888/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"extracted_data\": {\"invoice_number\": \"INV-2026-0042\"}, \"status\": \"Approved\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_document_ai_data(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"44444444-5555-6666-7777-888888888888\",\n    extracted_data={\"invoice_number\": \"INV-2026-0042\"},\n    status=\"Approved\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateDocumentAiData(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"44444444-5555-6666-7777-888888888888\",\n  {\n    extracted_data: { invoice_number: \"INV-2026-0042\" },\n    status: \"Approved\",\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateDocumentAiData(ctx, \"11111111-2222-3333-4444-555555555555\", \"44444444-5555-6666-7777-888888888888\", didit.SessionsUpdateDocumentAiDataParams{\n\tExtractedData: didit.Some(map[string]any{\"invoice_number\": \"INV-2026-0042\"}),\n\tStatus:        didit.Some(didit.SessionsUpdateDocumentAiDataParamsStatus(\"Approved\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUpdateDocumentAiDataParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateDocumentAiData(\"11111111-2222-3333-4444-555555555555\", \"44444444-5555-6666-7777-888888888888\", SessionsUpdateDocumentAiDataParams.builder()\n        .extractedData(Map.of(\"invoice_number\", \"INV-2026-0042\"))\n        .status(SessionsUpdateDocumentAiDataParams.Status.of(\"Approved\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateDocumentAiData('11111111-2222-3333-4444-555555555555', '44444444-5555-6666-7777-888888888888', [\n    'extracted_data' => ['invoice_number' => 'INV-2026-0042'],\n    'status' => 'Approved',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_document_ai_data(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"44444444-5555-6666-7777-888888888888\",\n  extracted_data: { invoice_number: \"INV-2026-0042\" },\n  status: \"Approved\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateDocumentAiDataAsync(\"11111111-2222-3333-4444-555555555555\", \"44444444-5555-6666-7777-888888888888\", new SessionsUpdateDocumentAiDataParams\n{\n    ExtractedData = new Dictionary<string, object> { [\"invoice_number\"] = \"INV-2026-0042\" },\n    Status = new SessionsUpdateDocumentAiDataParamsStatus(\"Approved\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "문서가 업데이트되었습니다. 병합 후의 문서를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "uuid",
                    "document_key",
                    "original_filename",
                    "file_url",
                    "status",
                    "extracted_data"
                  ],
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "문서 식별자입니다."
                    },
                    "document_key": {
                      "type": "string",
                      "description": "이 업로드에 해당하는 구성된 문서입니다."
                    },
                    "original_filename": {
                      "type": "string",
                      "nullable": true,
                      "description": "문서가 업로드된 파일 이름입니다."
                    },
                    "file_url": {
                      "type": "string",
                      "nullable": true,
                      "description": "업로드된 파일의 저장 경로입니다. 다운로드 링크가 아니며, 파일을 다운로드하려면 세션 결정에서 사전 서명된 `file_url`을 읽으십시오."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "Not Finished",
                        "Approved",
                        "Declined",
                        "In Review",
                        "Resub Requested"
                      ],
                      "description": "문서의 검토 상태입니다."
                    },
                    "extracted_data": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "병합 후 추출된 모든 필드이며, 필드 키를 키로 가집니다."
                    }
                  }
                },
                "example": {
                  "uuid": "44444444-5555-6666-7777-888888888888",
                  "document_key": "invoice",
                  "original_filename": "invoice-2026-09.pdf",
                  "file_url": "document_ai/11111111-2222-3333-4444-555555555555-66666666-7777-8888-9999-000000000000.pdf",
                  "status": "Approved",
                  "extracted_data": {
                    "invoice_number": "INV-2026-0042",
                    "total_amount": 1250.0,
                    "issue_date": "2026-09-01"
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류이며, 문서를 조회하기 전에 확인됩니다: `status`가 허용된 값 중 하나가 아니거나, `extracted_data`가 `null`로 전송되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid status": {
                    "summary": "status가 enum에 없습니다",
                    "value": {
                      "status": [
                        "\"Rejected\" is not a valid choice."
                      ]
                    }
                  },
                  "Null extracted_data": {
                    "summary": "extracted_data가 null입니다",
                    "value": {
                      "extracted_data": [
                        "This field may not be null."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "스코프 지정 키에 decisions: write 권한이 없음",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나, 삭제되었거나, 범위가 지정된 키의 제한 범위를 벗어났거나, 이 UUID를 가진 현재 문서가 세션에 속해 있지 않습니다. 세션 조회가 자격 증명 확인보다 먼저 실행되므로, 유효한 키가 없더라도 알 수 없는 `sessionId`에 대해 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "이 ID를 가진 세션이 존재하지 않거나 삭제되었습니다",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "세션이 범위가 지정된 키의 제한 범위를 벗어났습니다(방금 삭제된 세션에 대해서도 반환됨)",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "Unknown document": {
                    "summary": "documentUuid가 세션에 속하지 않습니다",
                    "value": {
                      "detail": "Document AI document not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. API 키당 분당 300회의 쓰기(POST, PATCH, DELETE) 요청으로 제한됩니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요. `X-RateLimit-*` 헤더에 한도 정보가 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "현재 분에 할당된 예산이 소진되었습니다",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/aml/dataset-freshness/": {
      "get": {
        "summary": "AML 데이터 세트 최신 상태 조회",
        "description": "[지속적인 AML 모니터링](https://docs.didit.me/ko/core-technology/aml-screening/continuous-monitoring-aml-screening#모니터링-실행-입증)의 감사 증거로서 AML 스크리닝의 기반이 되는 데이터세트가 얼마나 최신인지 소스 패밀리(`sanctions`, `pep`, `warnings`, `adverse_media`)별로 보고합니다. 응답은 플랫폼 전반에 적용됩니다. 경로에 세션이 없고 본문에 고객 데이터가 없으며 모든 애플리케이션에 동일한 응답이 제공됩니다.\n\n수락된 키의 경우 항상 `200`입니다. 먼저 `availability`를 확인하십시오. `available`이 아니면 `dataset_freshness`는 `null`입니다. 날짜는 절대 추정되지 않습니다. 데이터세트에 날짜가 보고되지 않은 패밀리는 `sources`에서 제외되며, 일부 데이터세트에서만 날짜가 보고된 패밀리는 `oldest_updated_at: null`이 됩니다. 측정값은 각 호출 시점이 아니라 지속적인 모니터링이 실행되는 동안 수집되며, `captured_at`에 수집 시점이 표시됩니다.\n\n범위가 지정된 API 키에는 `sessions: read`가 필요하며, 일부 워크플로나 승인된 세션으로 제한된 키는 이 endpoint를 호출할 수 없습니다. 요금은 청구되지 않습니다.",
        "operationId": "get_aml_dataset_freshness",
        "x-didit-sdk": {
          "resource": "aml",
          "method": "retrieve_dataset_freshness",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/aml/dataset-freshness/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.aml.retrieve_dataset_freshness()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.aml.retrieveDatasetFreshness();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.AML.RetrieveDatasetFreshness(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.aml().retrieveDatasetFreshness();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->aml->retrieveDatasetFreshness();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.aml.retrieve_dataset_freshness\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Aml.RetrieveDatasetFreshnessAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "최신 데이터 세트의 최신성 측정값 또는 이유와 함께 `null`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "dataset_freshness",
                    "availability"
                  ],
                  "properties": {
                    "dataset_freshness": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/AMLDatasetFreshness"
                        }
                      ],
                      "nullable": true,
                      "description": "최신 측정값 또는 `availability`가 `available`이 아닐 때 `null`입니다."
                    },
                    "availability": {
                      "type": "string",
                      "enum": [
                        "available",
                        "not_configured",
                        "not_yet_collected"
                      ],
                      "description": "측정값이 있는 경우 `available`, 이 환경에서 데이터셋 날짜를 수집하지 않는 경우 `not_configured`, 수집이 설정되었지만 아직 측정값이 없는 경우 `not_yet_collected`입니다."
                    }
                  }
                },
                "examples": {
                  "Available": {
                    "value": {
                      "dataset_freshness": {
                        "captured_at": "2026-10-17T06:00:12.345678+00:00",
                        "provider": "aml_data_source",
                        "catalog_version": "20261017054500-abc",
                        "sources": {
                          "sanctions": {
                            "last_updated_at": "2026-10-17T04:10:00+00:00",
                            "oldest_updated_at": "2026-10-15T22:30:00+00:00",
                            "dataset_count": 48,
                            "dated_dataset_count": 48
                          },
                          "pep": {
                            "last_updated_at": "2026-10-16T23:05:00+00:00",
                            "oldest_updated_at": null,
                            "dataset_count": 12,
                            "dated_dataset_count": 11
                          }
                        }
                      },
                      "availability": "available"
                    }
                  },
                  "Not collected yet": {
                    "value": {
                      "dataset_freshness": null,
                      "availability": "not_yet_collected"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 만료일이 지정되어 생성된 키만 만료될 수 있으며, 해당 날짜 이후에는 이를 사용한 모든 요청에 `401`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. 키가 누락된 경우 일반 메시지가 반환되며, 잘못되거나 취소되었거나 만료된 키는 `401`을 받습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without sessions read": {
                    "value": {
                      "detail": "This API key has no read access to sessions."
                    }
                  },
                  "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."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "이 API 키로 분당 600건을 초과하는 GET 요청이 발생했습니다. `Retry-After`에 명시된 시간(초)만큼 대기한 후 다시 시도하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "현재 1분 기간이 초기화될 때까지 남은 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "이 예산에서 분당 허용되는 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "윈도우가 리셋되는 Unix 시간입니다.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/lists/": {
      "get": {
        "summary": "목록 조회",
        "description": "애플리케이션의 목록을 최신순으로 반환합니다. 여기에는 Didit이 프로비저닝하는 시스템 목록(항목 유형별 차단 목록 1개, **High Risk Countries** 커스텀 목록 및 모든 시스템 허용 목록)과 사용자가 생성한 허용 목록 및 커스텀 목록이 포함됩니다. `list_type` 및 `entry_type`으로 필터링할 수 있으며, 삭제된 목록은 표시되지 않습니다. 결과는 `limit` 및 `offset`으로 페이지네이션됩니다. 범위 지정 API 키에는 `workflows: read` 권한이 필요합니다. 각 목록 유형의 기능은 [목록](https://docs.didit.me/ko/management-api/lists/overview)을 참조하십시오.",
        "operationId": "list_lists",
        "x-didit-sdk": {
          "resource": "lists",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_type",
            "in": "query",
            "required": false,
            "description": "이 타입의 목록만 해당합니다.",
            "schema": {
              "type": "string",
              "enum": [
                "blocklist",
                "allowlist",
                "custom"
              ]
            }
          },
          {
            "name": "entry_type",
            "in": "query",
            "required": false,
            "description": "이 항목 타입의 목록만 해당합니다.",
            "schema": {
              "type": "string",
              "enum": [
                "face",
                "document",
                "phone",
                "email",
                "ip_address",
                "device_fingerprint",
                "wallet_address",
                "bank_account",
                "country",
                "user",
                "business",
                "key"
              ]
            }
          },
          {
            "name": "ordering",
            "in": "query",
            "required": false,
            "description": "정렬 순서: `-created_at`(최신순, 기본값) 또는 `created_at`(오래된순).",
            "schema": {
              "type": "string",
              "enum": [
                "-created_at",
                "created_at"
              ],
              "default": "-created_at"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "페이지 크기입니다. 기본값은 50입니다. 1000000을 초과하는 값은 `400`을 반환하며, 0, 음수 또는 숫자가 아닌 값은 50으로 대체됩니다.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "반환할 첫 번째 항목의 0부터 시작하는 인덱스입니다. `next`를 따르는 것이 좋습니다. 1000000을 초과하는 값은 `400`을 반환하며, 음수이거나 숫자가 아닌 값은 0으로 대체됩니다.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/lists/?list_type=blocklist' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.lists.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.lists.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Lists.ListAutoPaging(ctx, didit.ListsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.lists().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->lists->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.lists.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Lists.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "목록 페이지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "필터와 일치하는 목록의 총 개수입니다."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "다음 페이지의 절대 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "이전 페이지의 절대 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ComplianceList"
                      }
                    }
                  }
                },
                "examples": {
                  "Lists": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "22222222-3333-4444-5555-666666666666",
                          "name": "Trusted office IPs",
                          "description": "Office egress ranges",
                          "list_type": "allowlist",
                          "entry_type": "ip_address",
                          "is_system": false,
                          "entry_count": 3,
                          "last_entry_added_at": "2026-10-02T08:15:27.501334Z",
                          "created_at": "2026-09-30T13:20:45.889120Z",
                          "updated_at": "2026-09-30T13:20:45.889120Z"
                        },
                        {
                          "uuid": "11111111-2222-3333-4444-555555555555",
                          "name": "Face Blocklist",
                          "description": "Blocked biometric faces. When a face matching an entry in this list is detected during liveness verification, the session will be automatically declined.",
                          "list_type": "blocklist",
                          "entry_type": "face",
                          "is_system": true,
                          "entry_count": 12,
                          "last_entry_added_at": "2026-10-09T16:42:03.118204Z",
                          "created_at": "2026-01-14T10:02:11.402917Z",
                          "updated_at": "2026-01-14T10:02:11.402917Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "쿼리 파라미터가 유효하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown list type": {
                    "value": {
                      "list_type": [
                        "\"denylist\" is not a valid choice."
                      ]
                    }
                  },
                  "Unsupported ordering": {
                    "value": {
                      "ordering": [
                        "\"name\" is not a valid choice."
                      ]
                    }
                  },
                  "Limit too large": {
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. 기타 인증 실패 시에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` 헤더가 누락되었거나(잘못되었거나 해지되었거나 만료된 키는 `401` 반환), 범위가 지정된 API 키에 `workflows: read` 권한이 없거나 허용 목록 외부의 IP 주소에서 사용되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no read access to workflows."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "API 키당 분당 600개의 요청을 처리하는 공유 읽기 속도 제한을 초과했습니다. 다시 시도하기 전에 `Retry-After`를 준수하십시오.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "목록 생성",
        "description": "API 키가 속한 애플리케이션에 허용 목록 또는 커스텀 목록을 생성합니다. 차단 목록은 생성할 수 없습니다. Didit은 항목 유형당 하나의 시스템 차단 목록을 프로비저닝하며, [목록 항목 생성](https://docs.didit.me/ko/management-api/lists/create-entry)을 통해 항목을 추가할 수 있습니다. `entry_type`은 생성 후 변경할 수 없으며 항목 값이 검증되고 일치되는 방식을 결정합니다. 허용 목록 항목은 일치하는 항목을 신뢰할 수 있는 항목으로 표시하며(예: 얼굴 허용 목록은 중복 얼굴 작업을 건너뜀) 차단 목록 일치 항목을 재정의하지 않습니다. 워크플로 또는 거래 규칙 조건에서 `value_type: \"list\"`로 임의의 목록을 참조할 수 있습니다. 스코프가 지정된 API 키에는 `workflows: write` 권한이 필요합니다.",
        "operationId": "create_list",
        "x-didit-sdk": {
          "resource": "lists",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "list_type",
                  "entry_type"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "목록 이름입니다. 시스템 목록을 포함하여 애플리케이션의 다른 모든 목록 이름과 달라야 합니다."
                  },
                  "description": {
                    "type": "string",
                    "default": "",
                    "description": "선택적 자유 텍스트 설명입니다."
                  },
                  "list_type": {
                    "type": "string",
                    "enum": [
                      "allowlist",
                      "custom"
                    ],
                    "description": "`allowlist` 또는 `custom`. `blocklist`는 `400`으로 거부됩니다."
                  },
                  "entry_type": {
                    "type": "string",
                    "enum": [
                      "face",
                      "document",
                      "phone",
                      "email",
                      "ip_address",
                      "device_fingerprint",
                      "wallet_address",
                      "bank_account",
                      "country",
                      "user",
                      "business",
                      "key"
                    ],
                    "description": "목록에 포함되는 항목 유형입니다. `face`, `document`(문서 번호), `phone`, `email`, `ip_address`(IP 주소 또는 CIDR 범위), `device_fingerprint`, `wallet_address`, `bank_account`, `country`(ISO 3166-1 alpha-3), `user` 또는 `business`(귀하의 `vendor_data`), 또는 `key`(모든 문자열)입니다. 항목 값이 검증되고 일치되는 방식을 결정합니다. 나중에 변경할 수 없습니다."
                  }
                }
              },
              "examples": {
                "IP allowlist": {
                  "value": {
                    "name": "Trusted office IPs",
                    "description": "Office egress ranges",
                    "list_type": "allowlist",
                    "entry_type": "ip_address"
                  }
                },
                "Custom country list": {
                  "value": {
                    "name": "Enhanced due diligence countries",
                    "list_type": "custom",
                    "entry_type": "country"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/lists/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"name\": \"Trusted office IPs\",\n    \"description\": \"Office egress ranges\",\n    \"list_type\": \"allowlist\",\n    \"entry_type\": \"ip_address\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.create(\n    name=\"Trusted office IPs\",\n    description=\"Office egress ranges\",\n    list_type=\"allowlist\",\n    entry_type=\"ip_address\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.create({\n  name: \"Trusted office IPs\",\n  description: \"Office egress ranges\",\n  list_type: \"allowlist\",\n  entry_type: \"ip_address\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Create(ctx, didit.ListsCreateParams{\n\tName:        \"Trusted office IPs\",\n\tDescription: didit.String(\"Office egress ranges\"),\n\tListType:    \"allowlist\",\n\tEntryType:   \"ip_address\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.ListsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().create(ListsCreateParams.builder()\n        .name(\"Trusted office IPs\")\n        .description(\"Office egress ranges\")\n        .listType(ListsCreateParams.ListType.of(\"allowlist\"))\n        .entryType(ListsCreateParams.EntryType.of(\"ip_address\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->lists->create([\n    'name' => 'Trusted office IPs',\n    'description' => 'Office egress ranges',\n    'list_type' => 'allowlist',\n    'entry_type' => 'ip_address',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.create(\n  name: \"Trusted office IPs\",\n  description: \"Office egress ranges\",\n  list_type: \"allowlist\",\n  entry_type: \"ip_address\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.CreateAsync(new ListsCreateParams\n{\n    Name = \"Trusted office IPs\",\n    Description = \"Office egress ranges\",\n    ListType = \"allowlist\",\n    EntryType = \"ip_address\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "목록이 생성되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComplianceList"
                },
                "examples": {
                  "New allowlist": {
                    "value": {
                      "uuid": "22222222-3333-4444-5555-666666666666",
                      "name": "Trusted office IPs",
                      "description": "Office egress ranges",
                      "list_type": "allowlist",
                      "entry_type": "ip_address",
                      "is_system": false,
                      "entry_count": 0,
                      "last_entry_added_at": null,
                      "created_at": "2026-10-12T09:15:44.031876Z",
                      "updated_at": "2026-10-12T09:15:44.031876Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "본문이 잘못되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Blocklist refused": {
                    "value": {
                      "list_type": [
                        "Cannot create additional blocklist lists. System blocklists are auto-created for each application."
                      ]
                    }
                  },
                  "Duplicate name": {
                    "value": {
                      "name": [
                        "A list with this name already exists for this application."
                      ]
                    }
                  },
                  "Missing fields": {
                    "value": {
                      "name": [
                        "This field is required."
                      ],
                      "list_type": [
                        "This field is required."
                      ],
                      "entry_type": [
                        "This field is required."
                      ]
                    }
                  },
                  "Unknown entry type": {
                    "value": {
                      "entry_type": [
                        "\"iban\" is not a valid choice."
                      ]
                    }
                  },
                  "Name too long": {
                    "value": {
                      "name": [
                        "Ensure this field has no more than 255 characters."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. 기타 인증 실패 시에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` 헤더가 누락되었거나(잘못되었거나 해지되었거나 만료된 키는 `401` 반환), 범위가 지정된 API 키에 `workflows: write` 권한이 없거나 허용 목록 외부의 IP 주소에서 사용되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/lists/{list_uuid}/": {
      "get": {
        "summary": "목록 조회",
        "description": "애플리케이션의 목록 하나를 항목 수 및 가장 최근 항목이 추가된 시간과 함께 반환합니다. 다른 애플리케이션의 목록이거나 삭제된 목록인 경우 `404`를 반환합니다. 이 요청은 목록 자체만 반환합니다. 목록의 값을 읽으려면 [List list entries](https://docs.didit.me/ko/management-api/lists/list-entries)를 사용하세요. 범위가 지정된 API 키에는 `workflows: read` 권한이 필요합니다.",
        "operationId": "get_list",
        "x-didit-sdk": {
          "resource": "lists",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "목록 조회(List lists) 또는 목록 생성(Create a list)에서 반환된 목록의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->lists->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComplianceList"
                },
                "examples": {
                  "System face blocklist": {
                    "value": {
                      "uuid": "11111111-2222-3333-4444-555555555555",
                      "name": "Face Blocklist",
                      "description": "Blocked biometric faces. When a face matching an entry in this list is detected during liveness verification, the session will be automatically declined.",
                      "list_type": "blocklist",
                      "entry_type": "face",
                      "is_system": true,
                      "entry_count": 12,
                      "last_entry_added_at": "2026-10-09T16:42:03.118204Z",
                      "created_at": "2026-01-14T10:02:11.402917Z",
                      "updated_at": "2026-01-14T10:02:11.402917Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. 기타 인증 실패 시에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` 헤더가 누락되었거나(잘못되었거나 해지되었거나 만료된 키는 `401` 반환), 범위가 지정된 API 키에 `workflows: read` 권한이 없거나 허용 목록 외부의 IP 주소에서 사용되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no read access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "API 키의 애플리케이션에 이 UUID를 가진 목록이 존재하지 않거나 삭제되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No List matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "API 키당 분당 600개의 요청을 처리하는 공유 읽기 속도 제한을 초과했습니다. 다시 시도하기 전에 `Retry-After`를 준수하십시오.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "목록 업데이트",
        "description": "목록의 이름을 바꾸거나 설명을 변경합니다. `name`과 `description`만 읽으며, 다른 필드는 모두 무시되므로 `list_type`과 `entry_type`은 생성 시의 값을 유지합니다. 시스템 목록은 수정할 수 없으며 `400`을 반환합니다. 응답에는 `name`과 `description`만 포함됩니다. 전체 목록은 [목록 가져오기](https://docs.didit.me/ko/management-api/lists/get)를 호출하세요. 스코프가 지정된 API 키에는 `workflows: write` 권한이 필요합니다.",
        "operationId": "update_list",
        "x-didit-sdk": {
          "resource": "lists",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "목록 조회(List lists) 또는 목록 생성(Create a list)에서 반환된 목록의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "새 이름입니다. 애플리케이션의 다른 모든 목록의 이름과 달라야 합니다."
                  },
                  "description": {
                    "type": "string",
                    "description": "새 설명입니다. 삭제하려면 빈 문자열을 전송하세요."
                  }
                }
              },
              "examples": {
                "Rename": {
                  "value": {
                    "name": "Trusted office and VPN IPs"
                  }
                },
                "Rename and describe": {
                  "value": {
                    "name": "Trusted office and VPN IPs",
                    "description": "Office egress ranges and the corporate VPN"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"name\": \"Trusted office and VPN IPs\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    name=\"Trusted office and VPN IPs\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.update(\"11111111-2222-3333-4444-555555555555\", {\n  name: \"Trusted office and VPN IPs\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.ListsUpdateParams{\n\tName: didit.String(\"Trusted office and VPN IPs\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.ListsUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().update(\"11111111-2222-3333-4444-555555555555\", ListsUpdateParams.builder()\n        .name(\"Trusted office and VPN IPs\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->lists->update('11111111-2222-3333-4444-555555555555', [\n    'name' => 'Trusted office and VPN IPs',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  name: \"Trusted office and VPN IPs\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new ListsUpdateParams\n{\n    Name = \"Trusted office and VPN IPs\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "목록이 업데이트되었습니다. 편집 가능한 필드만 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "name",
                    "description"
                  ],
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "업데이트 후 목록의 이름입니다."
                    },
                    "description": {
                      "type": "string",
                      "description": "업데이트 후 목록의 설명입니다."
                    }
                  }
                },
                "examples": {
                  "Renamed": {
                    "value": {
                      "name": "Trusted office and VPN IPs",
                      "description": "Office egress ranges"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "목록이 시스템 목록이거나 본문이 유효하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "System list": {
                    "value": {
                      "non_field_errors": [
                        "System lists cannot be modified."
                      ]
                    }
                  },
                  "Duplicate name": {
                    "value": {
                      "name": [
                        "A list with this name already exists for this application."
                      ]
                    }
                  },
                  "Blank name": {
                    "value": {
                      "name": [
                        "This field may not be blank."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. 기타 인증 실패 시에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` 헤더가 누락되었거나(잘못되었거나 해지되었거나 만료된 키는 `401` 반환), 범위가 지정된 API 키에 `workflows: write` 권한이 없거나 허용 목록 외부의 IP 주소에서 사용되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "API 키의 애플리케이션에 이 UUID를 가진 목록이 존재하지 않거나 삭제되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No List matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "summary": "목록을 삭제합니다.",
        "description": "허용 목록 또는 커스텀 목록을 해당 항목과 함께 삭제합니다. 삭제는 되돌릴 수 없습니다. 목록과 해당 항목은 더 이상 어떤 조회에서도 나타나지 않으며, 해당 목록을 참조하는 워크플로 및 거래 규칙 조건은 이후부터 빈 목록으로 평가합니다. 이미 평가된 세션 및 거래는 결과를 유지하며, 새 목록에 이름을 재사용할 수 있습니다. 시스템 목록은 삭제할 수 없으며 `400`을 반환합니다. 비우려면 [해당 항목을 삭제](https://docs.didit.me/ko/management-api/lists/delete-entry)하십시오. 범위가 지정된 API 키에는 `workflows: write` 권한이 필요합니다.",
        "operationId": "delete_list",
        "x-didit-sdk": {
          "resource": "lists",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "목록 조회(List lists) 또는 목록 생성(Create a list)에서 반환된 목록의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.lists.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.lists.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Lists.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.lists().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->lists->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.lists.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Lists.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ],
        "responses": {
          "204": {
            "description": "목록과 해당 항목이 삭제되었습니다. 본문이 없습니다."
          },
          "400": {
            "description": "목록이 시스템 목록입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "System list": {
                    "value": {
                      "detail": "System lists cannot be deleted."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. 기타 인증 실패 시에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` 헤더가 누락되었거나(잘못되었거나 해지되었거나 만료된 키는 `401` 반환), 범위가 지정된 API 키에 `workflows: write` 권한이 없거나 허용 목록 외부의 IP 주소에서 사용되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "API 키의 애플리케이션에 이 UUID를 가진 목록이 존재하지 않거나 이미 삭제되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No List matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/lists/{list_uuid}/entries/": {
      "get": {
        "summary": "목록 항목 조회",
        "description": "단일 목록의 현재 항목을 최신순으로 반환합니다. `search`는 대소문자를 구분하지 않고 항목의 `value` 또는 `display_label` 일부와 일치하는 항목을 검색하며, `reference_session_id`는 단일 개인 인증 세션에서 가져온 항목으로 결과를 좁힙니다. `metadata`의 이미지 URL은 호출할 때마다 새로 발급되는 유효 기간이 짧은 서명된 URL이며, `media: read` 권한이 없는 범위 지정 API 키는 해당 위치에 `null`을 받습니다. 범위 지정 API 키에는 `workflows: read` 권한이 필요합니다.",
        "operationId": "list_list_entries",
        "x-didit-sdk": {
          "resource": "lists.entries",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "목록 조회(List lists) 또는 목록 생성(Create a list)에서 반환된 목록의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "항목의 `value` 또는 `display_label`에 포함되어야 하는 대소문자를 구분하지 않는 텍스트.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "reference_session_id",
            "in": "query",
            "required": false,
            "description": "이 개인 인증 세션에서 가져온 항목만 해당합니다(예: 세션의 얼굴 중 어떤 얼굴이 이미 등록되어 있는지 확인하려는 경우).",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "페이지 크기입니다. 기본값은 50입니다. 1000000을 초과하는 값은 `400`을 반환하며, 0, 음수 또는 숫자가 아닌 값은 50으로 대체됩니다.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "반환할 첫 번째 항목의 0부터 시작하는 인덱스입니다. `next`를 따르는 것이 좋습니다. 1000000을 초과하는 값은 `400`을 반환하며, 음수이거나 숫자가 아닌 값은 0으로 대체됩니다.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/entries/?search=example.com' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.lists.entries.list(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.lists.entries.list(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Lists.Entries.ListAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.ListsEntriesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.lists().entries().list(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->lists->entries->list('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.lists.entries.list(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Lists.Entries.ListAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "최신순으로 정렬된 엔트리 페이지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "필터와 일치하는 항목의 총 개수입니다."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "다음 페이지의 절대 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "이전 페이지의 절대 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ComplianceListEntry"
                      }
                    }
                  }
                },
                "examples": {
                  "Entries": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "bbbbbbbb-cccc-dddd-eeee-ffffffffffff",
                          "value": "X1234567",
                          "display_label": "Jane Doe - X1234567",
                          "comment": "",
                          "added_by": "api",
                          "reference_session_id": "33333333-4444-5555-6666-777777777777",
                          "reference_session_number": 1042,
                          "reference_session_type": "kyc",
                          "reference_object_uuid": "66666666-7777-8888-9999-000000000000",
                          "metadata": {
                            "full_name": "Jane Doe",
                            "issuing_state": "ESP",
                            "document_type": "ID",
                            "region": "",
                            "document_number": "X1234567"
                          },
                          "created_at": "2026-10-12T10:06:12.774915Z"
                        },
                        {
                          "uuid": "eeeeeeee-ffff-0000-1111-222222222222",
                          "value": "y7654321",
                          "display_label": "",
                          "comment": "Reported by a partner",
                          "added_by": "api",
                          "reference_session_id": null,
                          "reference_session_number": null,
                          "reference_session_type": null,
                          "reference_object_uuid": null,
                          "metadata": null,
                          "created_at": "2026-10-03T07:48:30.552810Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "쿼리 파라미터가 유효하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid session id": {
                    "value": {
                      "reference_session_id": [
                        "Must be a valid UUID."
                      ]
                    }
                  },
                  "Limit too large": {
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. 기타 인증 실패 시에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` 헤더가 누락되었거나(잘못되었거나 해지되었거나 만료된 키는 `401` 반환), 범위가 지정된 API 키에 `workflows: read` 권한이 없거나 허용 목록 외부의 IP 주소에서 사용되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no read access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "API 키의 애플리케이션에 이 UUID를 가진 목록이 존재하지 않거나 삭제되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "List not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "API 키당 분당 600개의 요청을 처리하는 공유 읽기 속도 제한을 초과했습니다. 다시 시도하기 전에 `Retry-After`를 준수하십시오.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "목록 항목 생성",
        "description": "목록에 항목을 세 가지 방식 중 하나로 추가합니다. `value`로 추가하거나, `reference_session_id`가 있는 인증 세션에서 추가(Didit이 해당 목록 항목 유형에 대한 세션의 최신 기록에서 값을 읽어 항목에 연결)하거나, 거래, 사용자 또는 기업을 다시 가리키는 `reference_object_uuid` 및 `metadata.reference_type`과 함께 `value`로 추가합니다. 시스템 얼굴, 문서, 전화번호 및 이메일 차단 목록에서는 세션에서 읽은 레코드도 차단 목록에 포함된 것으로 플래그 지정되어 일치하는 새 세션이 거부됩니다. 시스템 사용자 및 기업 차단 목록에서는 일치하는 사용자 또는 기업이 `BLOCKED`로 설정됩니다. 이미 완료된 세션 및 거래는 변경되지 않습니다. 스코프가 지정된 API 키에는 `workflows: write`가 필요합니다. 각 모드에 대한 자세한 내용은 [목록 항목 생성](https://docs.didit.me/ko/management-api/lists/create-entry)을 참조하십시오.",
        "operationId": "create_list_entry",
        "x-didit-sdk": {
          "resource": "lists.entries",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "추가할 대상 목록의 UUID입니다. 이미지만 가지고 있는 얼굴의 경우 대신 목록에 얼굴 업로드(Upload a face to a list)를 사용하십시오.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "`value`, `reference_session_id` 또는 둘 다를 전송합니다. 적용되는 필드는 목록의 `entry_type`에 따라 다릅니다.",
                "properties": {
                  "value": {
                    "type": "string",
                    "description": "목록에 등록할 값이며, 목록의 `entry_type`에 따라 유효성이 검증됩니다. `email`은 유효한 이메일 주소, `phone`은 E.164 형식으로 저장되는 유효한 국제 전화번호, `ip_address`는 IP 주소 또는 CIDR 범위(예: `10.0.0.0/8`), `device_fingerprint`는 문자, 숫자, `-`, `_`, `:`, `.` 중 최소 8자(차단 목록은 서로 다른 여러 기기에서 보고된 지문을 거부함), `country`는 alpha-3로 저장되는 ISO 3166-1 alpha-2 또는 alpha-3 코드, `user` 및 `business`는 `vendor_data`, 기타 유형은 비어 있지 않은 문자열입니다. 전화번호와 국가 코드를 제외하고 소문자로 저장되며, 목록에는 각 값이 한 번만 포함됩니다(대소문자 구분 없음). `reference_session_id`가 전송되지 않는 한 필수이며, 문서 캡처 `face_image_source`를 사용하는 경우 비워 두어야 합니다."
                  },
                  "reference_session_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "값을 가져올 애플리케이션의 개인 또는 기업 확인(KYB) 세션입니다. Didit은 목록의 엔트리 유형(`face`, `document`, `phone`, `email`, `ip_address`, `device_fingerprint`)에 해당하는 세션의 가장 최근 레코드를 읽고, 엔트리를 세션 및 해당 레코드와 연결하며, 문서의 경우 `display_label` 및 `metadata`를 채웁니다. `device_fingerprint` 차단 목록의 경우, 기기 등급 핑거프린트만 있거나 둘 이상의 기기에서 완료된 세션은 거부되므로 정확한 핑거프린트를 `value`로 전송하십시오. 다른 엔트리 유형의 경우 또는 세션에 해당 레코드가 없는 경우 `value`도 함께 전송하십시오. 그러면 전송한 `value`가 저장되며 엔트리는 여전히 세션에 연결됩니다."
                  },
                  "reference_object_uuid": {
                    "type": "string",
                    "format": "uuid",
                    "description": "세션에서 생성되지 않은 경우 해당 항목이 나타내는 레코드의 UUID: 거래 UUID 또는 사용자나 기업의 `didit_internal_id`입니다. `metadata.reference_type`과 함께 사용하십시오. `reference_session_id`가 레코드를 제공하는 경우 세션의 레코드로 대체됩니다."
                  },
                  "face_image_source": {
                    "type": "string",
                    "enum": [
                      "liveness",
                      "front_image_camera_front",
                      "back_image_camera_front"
                    ],
                    "default": "liveness",
                    "description": "`reference_session_id`가 있는 얼굴 목록: 세션의 어느 이미지에서 얼굴을 가져왔는지를 나타냅니다. `liveness`(기본값)는 라이브니스 셀피입니다. `front_image_camera_front` 및 `back_image_camera_front`는 사용자가 문서의 앞면 또는 뒷면을 촬영하는 동안 전면 카메라가 촬영한 셀피입니다. 시스템 얼굴 차단 목록에서만 허용되며, `reference_session_id` 및 빈 `value`와 함께 사용됩니다. 각 셀피는 한 번만 추가할 수 있으며 하나의 선명한 얼굴이 표시되어야 합니다."
                  },
                  "reference_node_id": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 100,
                    "description": "문서 캡처 `face_image_source`가 지정된 경우: 둘 이상의 신분증 인증이 있는 워크플로에서 사용할 셀피의 신분증 인증 노드입니다. 기본값은 해당 이미지를 보유한 가장 최근의 신분증 인증입니다. `liveness`와 함께 사용하는 것은 거부됩니다."
                  },
                  "display_label": {
                    "type": "string",
                    "maxLength": 512,
                    "description": "사람이 읽기 쉬운 라벨입니다. 비어 있는 경우 Didit은 가능한 경우 세션에서 라벨을 도출합니다(예: 소지자의 성명 및 문서 번호)."
                  },
                  "comment": {
                    "type": "string",
                    "description": "등재 사유 등의 자유 형식 메모입니다."
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "엔트리와 함께 저장되고 저장된 그대로 반환되는 자유 형식 JSON입니다. 콘솔이 원본으로 다시 연결되도록 `reference_type` 및 `reference_id`를 사용하십시오. `reference_image_url` 및 `front_image_url`은 Didit에 의해서만 설정되며, 전송하더라도 제외됩니다. 세션에서 읽은 엔트리의 경우 Didit의 키가 사용자의 키와 병합됩니다.",
                    "properties": {
                      "reference_type": {
                        "type": "string",
                        "enum": [
                          "transaction",
                          "vendor_user",
                          "vendor_business"
                        ],
                        "description": "`reference_object_uuid`가 가리키는 대상입니다."
                      },
                      "reference_id": {
                        "type": "string",
                        "description": "소스 레코드의 식별자입니다."
                      }
                    }
                  }
                }
              },
              "examples": {
                "By value": {
                  "value": {
                    "value": "+14155552671",
                    "comment": "Reported fraud"
                  }
                },
                "From a session": {
                  "value": {
                    "reference_session_id": "33333333-4444-5555-6666-777777777777"
                  }
                },
                "Face from a document-capture selfie": {
                  "value": {
                    "reference_session_id": "33333333-4444-5555-6666-777777777777",
                    "face_image_source": "front_image_camera_front"
                  }
                },
                "From a transaction": {
                  "value": {
                    "value": "0x52908400098527886E0F7030069857D2E4169EE7",
                    "reference_object_uuid": "55555555-6666-7777-8888-999999999999",
                    "comment": "Linked to a chargeback",
                    "metadata": {
                      "reference_type": "transaction",
                      "reference_id": "55555555-6666-7777-8888-999999999999"
                    }
                  }
                },
                "Country": {
                  "value": {
                    "value": "PRK",
                    "comment": "Sanctioned jurisdiction"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/entries/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"value\": \"+14155552671\", \"comment\": \"Reported fraud\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.entries.create(\n    \"11111111-2222-3333-4444-555555555555\",\n    value=\"+14155552671\",\n    comment=\"Reported fraud\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.entries.create(\"11111111-2222-3333-4444-555555555555\", {\n  value: \"+14155552671\",\n  comment: \"Reported fraud\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Entries.Create(ctx, \"11111111-2222-3333-4444-555555555555\", didit.ListsEntriesCreateParams{\n\tValue:   didit.String(\"+14155552671\"),\n\tComment: didit.String(\"Reported fraud\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.ListsEntriesCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().entries().create(\"11111111-2222-3333-4444-555555555555\", ListsEntriesCreateParams.builder()\n        .value(\"+14155552671\")\n        .comment(\"Reported fraud\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->lists->entries->create('11111111-2222-3333-4444-555555555555', [\n    'value' => '+14155552671',\n    'comment' => 'Reported fraud',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.entries.create(\n  \"11111111-2222-3333-4444-555555555555\",\n  value: \"+14155552671\",\n  comment: \"Reported fraud\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.Entries.CreateAsync(\"11111111-2222-3333-4444-555555555555\", new ListsEntriesCreateParams\n{\n    Value = \"+14155552671\",\n    Comment = \"Reported fraud\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "항목이 생성되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComplianceListEntry"
                },
                "examples": {
                  "By value": {
                    "value": {
                      "uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                      "value": "+14155552671",
                      "display_label": "",
                      "comment": "Reported fraud",
                      "added_by": "api",
                      "reference_session_id": null,
                      "reference_session_number": null,
                      "reference_session_type": null,
                      "reference_object_uuid": null,
                      "metadata": null,
                      "created_at": "2026-10-12T10:04:51.220391Z"
                    }
                  },
                  "Document from a session": {
                    "value": {
                      "uuid": "bbbbbbbb-cccc-dddd-eeee-ffffffffffff",
                      "value": "X1234567",
                      "display_label": "Jane Doe - X1234567",
                      "comment": "",
                      "added_by": "api",
                      "reference_session_id": "33333333-4444-5555-6666-777777777777",
                      "reference_session_number": 1042,
                      "reference_session_type": "kyc",
                      "reference_object_uuid": "66666666-7777-8888-9999-000000000000",
                      "metadata": {
                        "full_name": "Jane Doe",
                        "issuing_state": "ESP",
                        "document_type": "ID",
                        "region": "",
                        "document_number": "X1234567"
                      },
                      "created_at": "2026-10-12T10:06:12.774915Z"
                    }
                  },
                  "From a transaction": {
                    "value": {
                      "uuid": "dddddddd-eeee-ffff-0000-111111111111",
                      "value": "0x52908400098527886e0f7030069857d2e4169ee7",
                      "display_label": "",
                      "comment": "Linked to a chargeback",
                      "added_by": "api",
                      "reference_session_id": null,
                      "reference_session_number": null,
                      "reference_session_type": null,
                      "reference_object_uuid": "55555555-6666-7777-8888-999999999999",
                      "metadata": {
                        "reference_type": "transaction",
                        "reference_id": "55555555-6666-7777-8888-999999999999"
                      },
                      "created_at": "2026-10-12T10:20:40.117062Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "본문이 잘못되었거나, 값이 이미 목록에 있거나, 세션에서 해당 값을 제공할 수 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Nothing to list": {
                    "value": {
                      "value": [
                        "Either 'value' or 'reference_session_id' must be provided."
                      ]
                    }
                  },
                  "Duplicate value": {
                    "value": {
                      "value": [
                        "An entry with this value already exists in this list."
                      ]
                    }
                  },
                  "Invalid phone": {
                    "value": {
                      "value": [
                        "Invalid phone number. Provide a valid international number (e.g. +1234567890)."
                      ]
                    }
                  },
                  "Invalid IP": {
                    "value": {
                      "value": [
                        "Invalid IP address or CIDR range (e.g. 192.168.1.1 or 10.0.0.0/24)."
                      ]
                    }
                  },
                  "Invalid country": {
                    "value": {
                      "value": [
                        "Invalid country code: XX. Provide a valid ISO 3166-1 alpha-2 or alpha-3 country code."
                      ]
                    }
                  },
                  "Device-class fingerprint": {
                    "value": {
                      "value": [
                        "This value is a device-class fingerprint: several distinct devices have reported it, so blocklisting it would decline unrelated people. Block the user by document, face, email or phone instead."
                      ]
                    }
                  },
                  "Unknown session": {
                    "value": {
                      "reference_session_id": [
                        "Session not found or does not belong to this application."
                      ]
                    }
                  },
                  "No data in session": {
                    "value": {
                      "value": [
                        "Either provide a 'value' or ensure the session contains data for this entry type."
                      ]
                    }
                  },
                  "Selfie on another list": {
                    "value": {
                      "face_image_source": [
                        "A document-capture selfie can only be added to the face blocklist."
                      ]
                    }
                  },
                  "No clear face in selfie": {
                    "value": {
                      "face_image_source": [
                        "No clear face was found in this selfie, so it cannot be blocklisted."
                      ]
                    }
                  },
                  "Selfie already listed": {
                    "value": {
                      "face_image_source": [
                        "This selfie is already in the blocklist."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. 기타 인증 실패 시에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` 헤더가 누락되었거나(잘못되었거나 해지되었거나 만료된 키는 `401` 반환), 범위가 지정된 API 키에 `workflows: write` 권한이 없거나 허용 목록 외부의 IP 주소에서 사용되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "API 키의 애플리케이션에 이 UUID를 가진 목록이 존재하지 않거나 삭제되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "List not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "503": {
            "description": "문서 캡처 셀피의 얼굴 분석을 일시적으로 사용할 수 없습니다. 아무것도 추가되지 않았으므로 나중에 다시 시도하십시오.",
            "content": {
              "application/json": {
                "examples": {
                  "Unavailable": {
                    "value": {
                      "detail": "Service temporarily unavailable. Please try again later."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/lists/{list_uuid}/entries/{entry_uuid}/": {
      "delete": {
        "summary": "목록 항목을 삭제합니다.",
        "description": "시스템 목록을 포함하여 목록에서 항목 하나를 삭제합니다. 해당 항목은 즉시 더 이상 일치하지 않으며, 삭제는 되돌릴 수 없습니다. 값을 다시 등록하려면 새 항목을 생성해야 합니다. 시스템 얼굴, 문서, 전화번호 또는 이메일 차단 목록의 경우 해당 항목이 나타내는 레코드에 더 이상 차단 목록 등록 플래그가 지정되지 않습니다. 시스템 사용자 또는 기업 차단 목록의 경우 `vendor_data`가 항목의 값과 일치하거나(`didit_internal_id`가 `reference_object_uuid`와 일치하는) `BLOCKED` 상태인 애플리케이션의 사용자 또는 기업이 `ACTIVE`로 돌아갑니다. 이미 완료된 세션 및 거래는 상태를 유지합니다. 범위가 지정된 API 키에는 `workflows: write` 권한이 필요합니다.",
        "operationId": "delete_list_entry",
        "x-didit-sdk": {
          "resource": "lists.entries",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "해당 항목이 포함된 목록의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "entry_uuid",
            "in": "path",
            "required": true,
            "description": "목록 항목 목록 조회(List list entries) 또는 목록 항목 생성(Create a list entry)에서 반환된 항목의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/entries/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.lists.entries.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.lists.entries.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Lists.Entries.Delete(ctx, \"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.lists().entries().delete(\"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->lists->entries->delete('11111111-2222-3333-4444-555555555555', 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.lists.entries.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\"\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Lists.Entries.DeleteAsync(\"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\");"
          }
        ],
        "responses": {
          "204": {
            "description": "항목이 삭제되었습니다. 응답 본문이 없습니다."
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. 기타 인증 실패 시에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` 헤더가 누락되었거나(잘못되었거나 해지되었거나 만료된 키는 `401` 반환), 범위가 지정된 API 키에 `workflows: write` 권한이 없거나 허용 목록 외부의 IP 주소에서 사용되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 목록에 해당 UUID를 가진 항목이 존재하지 않거나, 목록이 해당 API 키의 애플리케이션에 속해 있지 않거나 삭제되었거나, 항목이 이미 삭제되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No ListEntry matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/lists/{list_uuid}/entries/face-upload/": {
      "post": {
        "summary": "목록에 얼굴 업로드",
        "description": "참조할 인증 세션이 없을 때를 위해 base64로 인코딩된 JPEG 또는 PNG 이미지로부터 얼굴 차단 목록 또는 얼굴 허용 목록에 얼굴을 추가합니다. Didit은 이미지에서 얼굴을 감지하여 가장 큰 얼굴을 사용하고, `value`와 `reference_object_uuid`가 새 얼굴의 UUID인 항목을 생성합니다. 차단 목록에 등록된 얼굴은 얼굴이 일치하는 새 세션을 거부하며, 허용 목록에 등록된 얼굴은 중복 얼굴 작업을 건너뛰고 차단 목록 일치 항목을 재정의하지 않습니다. 샌드박스 애플리케이션에서는 이미지가 분석되지 않으며 해당 항목은 어떤 것과도 일치하지 않습니다. 스코프가 지정된 API 키에는 `workflows: write` 권한이 필요합니다. 기존 세션에서 얼굴을 목록에 추가하려면 대신 `reference_session_id`와 함께 [목록 항목 생성](https://docs.didit.me/ko/management-api/lists/create-entry)을 사용하세요.",
        "operationId": "upload_list_entry_face",
        "x-didit-sdk": {
          "resource": "lists.entries",
          "method": "upload_face",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "`entry_type: face` 및 `list_type: blocklist` 또는 `allowlist`인 목록의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "image"
                ],
                "properties": {
                  "image": {
                    "type": "string",
                    "format": "byte",
                    "description": "디코딩 시 최대 2MB 크기의 얼굴이 선명하게 보이는 Base64 인코딩된 JPEG 또는 PNG입니다. `data:image/...;base64,` 접두사 없이 순수 Base64 문자열만 전송해야 합니다."
                  },
                  "comment": {
                    "type": "string",
                    "default": "",
                    "description": "목록 등록 사유 등과 같은 선택적 자유 텍스트 메모입니다."
                  }
                }
              },
              "examples": {
                "Face image": {
                  "value": {
                    "image": "/9j/4AAQSkZJRgABAQAAAQABAAD...",
                    "comment": "Known fraud attempt"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/entries/face-upload/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d \"{\\\"image\\\": \\\"$(base64 < face.jpg | tr -d '\\n')\\\", \\\"comment\\\": \\\"Known fraud attempt\\\"}\""
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.entries.upload_face(\n    \"11111111-2222-3333-4444-555555555555\",\n    image=\"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n    comment=\"Known fraud attempt\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.entries.uploadFace(\"11111111-2222-3333-4444-555555555555\", {\n  image: \"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n  comment: \"Known fraud attempt\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Entries.UploadFace(ctx, \"11111111-2222-3333-4444-555555555555\", didit.ListsEntriesUploadFaceParams{\n\tImage:   \"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n\tComment: didit.String(\"Known fraud attempt\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.ListsEntriesUploadFaceParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().entries().uploadFace(\"11111111-2222-3333-4444-555555555555\", ListsEntriesUploadFaceParams.builder()\n        .image(\"/9j/4AAQSkZJRgABAQAAAQABAAD...\")\n        .comment(\"Known fraud attempt\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->lists->entries->uploadFace('11111111-2222-3333-4444-555555555555', [\n    'image' => '/9j/4AAQSkZJRgABAQAAAQABAAD...',\n    'comment' => 'Known fraud attempt',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.entries.upload_face(\n  \"11111111-2222-3333-4444-555555555555\",\n  image: \"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n  comment: \"Known fraud attempt\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.Entries.UploadFaceAsync(\"11111111-2222-3333-4444-555555555555\", new ListsEntriesUploadFaceParams\n{\n    Image = \"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n    Comment = \"Known fraud attempt\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "얼굴 항목이 생성되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComplianceListEntry"
                },
                "examples": {
                  "Uploaded face": {
                    "value": {
                      "uuid": "cccccccc-dddd-eeee-ffff-000000000000",
                      "value": "44444444-5555-6666-7777-888888888888",
                      "display_label": "Manually uploaded face",
                      "comment": "Known fraud attempt",
                      "added_by": "api",
                      "reference_session_id": null,
                      "reference_session_number": null,
                      "reference_session_type": null,
                      "reference_object_uuid": "44444444-5555-6666-7777-888888888888",
                      "metadata": {
                        "reference_image_url": "https://media.example.com/faces/reference.jpg?expires=1760263938&signature=3f9a1c"
                      },
                      "created_at": "2026-10-12T10:12:18.904467Z"
                    }
                  },
                  "Sandbox application": {
                    "value": {
                      "uuid": "cccccccc-dddd-eeee-ffff-000000000000",
                      "value": "44444444-5555-6666-7777-888888888888",
                      "display_label": "Sandbox face entry",
                      "comment": "Known fraud attempt",
                      "added_by": "api",
                      "reference_session_id": null,
                      "reference_session_number": null,
                      "reference_session_type": null,
                      "reference_object_uuid": "44444444-5555-6666-7777-888888888888",
                      "metadata": {
                        "sandbox": true
                      },
                      "created_at": "2026-10-12T10:12:18.904467Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "목록이 얼굴 업로드를 지원하지 않거나 이미지가 누락되었거나 유효하지 않거나 너무 크거나 사용할 수 있는 얼굴이 표시되지 않습니다. 항목이 생성되지 않았습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not a face list": {
                    "value": {
                      "detail": "Face upload is only available for face-type lists."
                    }
                  },
                  "Custom face list": {
                    "value": {
                      "detail": "Face upload is only available for face blocklists and allowlists."
                    }
                  },
                  "Missing image": {
                    "value": {
                      "image": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid base64": {
                    "value": {
                      "image": [
                        "Invalid base64 encoding."
                      ]
                    }
                  },
                  "Too large": {
                    "value": {
                      "image": [
                        "Image exceeds maximum size of 2 MB."
                      ]
                    }
                  },
                  "Unreadable image": {
                    "value": {
                      "image": "Invalid image. Provide a valid base64-encoded JPG or PNG."
                    }
                  },
                  "No face": {
                    "value": {
                      "image": "No face detected in the image. Please upload a clear photo with a visible face."
                    }
                  },
                  "No usable face": {
                    "value": {
                      "image": "Could not extract face embedding. Try a different image."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. 기타 인증 실패 시에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` 헤더가 누락되었거나(잘못되었거나 해지되었거나 만료된 키는 `401` 반환), 범위가 지정된 API 키에 `workflows: write` 권한이 없거나 허용 목록 외부의 IP 주소에서 사용되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "API 키의 애플리케이션에 이 UUID를 가진 목록이 존재하지 않거나 삭제되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "List not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "503": {
            "description": "얼굴 분석을 일시적으로 사용할 수 없습니다. 항목이 생성되지 않았으므로 나중에 다시 시도하십시오.",
            "content": {
              "application/json": {
                "examples": {
                  "Unavailable": {
                    "value": {
                      "detail": "Service temporarily unavailable. Please try again later."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/blocklist/": {
      "get": {
        "summary": "차단 목록 항목 목록 조회",
        "description": "현재 차단 목록에 등록된 애플리케이션 인증 세션의 얼굴, 신분증, 전화번호, 이메일 주소의 페이지네이션된 피드를 최신 `blocklisted_at` 순으로 반환합니다. `item_type`으로 필터링할 수 있습니다. 삭제된 세션의 항목은 포함되지 않습니다. 이 피드는 세션에서 차단 목록에 등록된 레코드([세션 항목을 차단 목록에 추가](https://docs.didit.me/ko/management-api/blocklist/add), 콘솔에서 추가, 또는 세션에서 생성된 목록 항목을 통해 추가)를 다룹니다. 수동으로 목록에 추가된 값, 업로드된 얼굴, 신분증 촬영 셀피에서 추출된 얼굴 및 기타 항목 유형은 [목록 항목 조회](https://docs.didit.me/ko/management-api/lists/list-entries)로 확인합니다. `face_image` 및 `front_image`는 유효 기간이 짧은 서명된 URL이며, `media: read` 권한이 없는 범위 지정 API 키에는 `null`이 반환됩니다. 범위 지정 API 키에는 `workflows: read` 권한이 필요합니다.",
        "operationId": "list_blocklist_items",
        "x-didit-sdk": {
          "resource": "blocklist",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Blocklist"
        ],
        "parameters": [
          {
            "name": "item_type",
            "in": "query",
            "required": false,
            "description": "이 타입의 항목만 해당합니다. 생략하면 모든 타입이 반환됩니다.",
            "schema": {
              "type": "string",
              "enum": [
                "face",
                "document",
                "phone",
                "email"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "페이지 크기입니다. 기본값은 50입니다. 1000000을 초과하는 값은 `400`을 반환하며, 0, 음수 또는 숫자가 아닌 값은 50으로 대체됩니다.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "반환할 첫 번째 항목의 0부터 시작하는 인덱스입니다. `next`를 따르는 것이 좋습니다. 1000000을 초과하는 값은 `400`을 반환하며, 음수이거나 숫자가 아닌 값은 0으로 대체됩니다.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/blocklist/?item_type=document' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.blocklist.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.blocklist.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Blocklist.ListAutoPaging(ctx, didit.BlocklistListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.blocklist().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->blocklist->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.blocklist.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Blocklist.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "최신순으로 정렬된 차단 목록 항목 페이지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "필터와 일치하는 차단 목록 항목의 총 개수입니다."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "다음 페이지의 절대 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "이전 페이지의 절대 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BlocklistedItem"
                      }
                    }
                  }
                },
                "examples": {
                  "Mixed feed": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "type": "document",
                          "session_id": "33333333-4444-5555-6666-777777777777",
                          "session_number": 1042,
                          "blocklisted_at": "2026-10-12T10:06:12.701553Z",
                          "face_image": null,
                          "document_type": "ID",
                          "document_number": "X1234567",
                          "front_image": "https://media.example.com/documents/front.jpg?expires=1760263938&signature=8b2e47",
                          "phone_number": null,
                          "country_code": null,
                          "email": null
                        },
                        {
                          "type": "phone",
                          "session_id": "77777777-8888-9999-0000-111111111111",
                          "session_number": 1017,
                          "blocklisted_at": "2026-10-08T15:31:09.400127Z",
                          "face_image": null,
                          "document_type": null,
                          "document_number": null,
                          "front_image": null,
                          "phone_number": "+14155552671",
                          "country_code": "US",
                          "email": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "쿼리 파라미터가 유효하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown item type": {
                    "value": {
                      "item_type": [
                        "\"wallet\" is not a valid choice."
                      ]
                    }
                  },
                  "Limit too large": {
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. 기타 인증 실패 시에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` 헤더가 누락되었거나(잘못되었거나 해지되었거나 만료된 키는 `401` 반환), 범위가 지정된 API 키에 `workflows: read` 권한이 없거나 허용 목록 외부의 IP 주소에서 사용되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no read access to workflows."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "API 키당 분당 600개의 요청을 처리하는 공유 읽기 속도 제한을 초과했습니다. 다시 시도하기 전에 `Retry-After`를 준수하십시오.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/blocklist/add/": {
      "post": {
        "summary": "세션 항목을 차단 목록에 추가",
        "description": "애플리케이션의 단일 개인 인증 세션에 사용된 얼굴, 신분증 문서, 전화번호 또는 이메일 주소를 차단 목록에 추가합니다. 선택한 각 유형에 대해 Didit은 세션의 가장 최신 기록을 가져와 차단 목록에 등록된 것으로 표시하고 세션에 연결된 항목을 일치하는 시스템 차단 목록(`added_by: \"api\"`)에 추가합니다. 이에 따라 일치하는 얼굴, 문서 번호, 전화번호 또는 이메일 주소를 가진 새 세션은 거부됩니다. 선택한 모든 항목을 먼저 검사하므로 하나라도 누락되면 아무것도 차단 목록에 추가되지 않습니다. 이미 등록된 항목에 대해 호출을 반복하면 단일 항목이 유지되고 `blocklisted_at`이 갱신됩니다. 해당 세션 자체와 이미 완료된 세션은 변경되지 않습니다. 범위가 지정된 API 키에는 `workflows: write` 권한이 필요합니다.",
        "operationId": "add_to_blocklist",
        "x-didit-sdk": {
          "resource": "blocklist",
          "method": "add",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Blocklist"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "session_id"
                ],
                "description": "최소 하나의 `blocklist_*` 플래그가 `true`여야 합니다.",
                "properties": {
                  "session_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "애플리케이션의 사용자 인증 세션입니다. 삭제된 세션은 거부됩니다."
                  },
                  "blocklist_face": {
                    "type": "boolean",
                    "default": false,
                    "description": "세션의 얼굴을 차단 목록에 추가합니다."
                  },
                  "blocklist_document": {
                    "type": "boolean",
                    "default": false,
                    "description": "세션의 신분증 문서를 차단 목록에 추가합니다. 문서에는 발급 국가, 문서 유형, 문서 번호, 성명이 필요합니다."
                  },
                  "blocklist_phone": {
                    "type": "boolean",
                    "default": false,
                    "description": "세션의 전화번호를 차단 목록에 추가합니다."
                  },
                  "blocklist_email": {
                    "type": "boolean",
                    "default": false,
                    "description": "세션의 이메일 주소를 차단 목록에 추가합니다."
                  }
                }
              },
              "examples": {
                "Face and document": {
                  "value": {
                    "session_id": "33333333-4444-5555-6666-777777777777",
                    "blocklist_face": true,
                    "blocklist_document": true
                  }
                },
                "Phone only": {
                  "value": {
                    "session_id": "33333333-4444-5555-6666-777777777777",
                    "blocklist_phone": true
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/blocklist/add/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"session_id\": \"33333333-4444-5555-6666-777777777777\",\n    \"blocklist_face\": true,\n    \"blocklist_document\": true\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.blocklist.add(\n    session_id=\"33333333-4444-5555-6666-777777777777\",\n    blocklist_face=True,\n    blocklist_document=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.blocklist.add({\n  session_id: \"33333333-4444-5555-6666-777777777777\",\n  blocklist_face: true,\n  blocklist_document: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Blocklist.Add(ctx, didit.BlocklistAddParams{\n\tSessionID:         \"33333333-4444-5555-6666-777777777777\",\n\tBlocklistFace:     didit.Bool(true),\n\tBlocklistDocument: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BlocklistAddParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.blocklist().add(BlocklistAddParams.builder()\n        .sessionId(\"33333333-4444-5555-6666-777777777777\")\n        .blocklistFace(true)\n        .blocklistDocument(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->blocklist->add([\n    'session_id' => '33333333-4444-5555-6666-777777777777',\n    'blocklist_face' => true,\n    'blocklist_document' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.blocklist.add(\n  session_id: \"33333333-4444-5555-6666-777777777777\",\n  blocklist_face: true,\n  blocklist_document: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Blocklist.AddAsync(new BlocklistAddParams\n{\n    SessionId = \"33333333-4444-5555-6666-777777777777\",\n    BlocklistFace = true,\n    BlocklistDocument = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "선택한 항목이 차단 목록에 추가되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "message"
                  ],
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "항상 `Successfully updated blocklist.`입니다."
                    }
                  }
                },
                "examples": {
                  "Blocklisted": {
                    "value": {
                      "message": "Successfully updated blocklist."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "본문이 잘못되었거나, 세션이 이 애플리케이션의 인증 세션이 아니거나, 선택한 유형의 기록이 없습니다. 아무것도 차단 목록에 추가되지 않았습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown session": {
                    "value": {
                      "non_field_errors": [
                        "Session not found"
                      ]
                    }
                  },
                  "No item selected": {
                    "value": {
                      "non_field_errors": [
                        "Must specify at least one item to blocklist"
                      ]
                    }
                  },
                  "No face record": {
                    "value": {
                      "non_field_errors": [
                        "Session does not have a face record"
                      ]
                    }
                  },
                  "Incomplete document": {
                    "value": {
                      "non_field_errors": [
                        "To blocklist a document, the document must have an issuing state, document type, document number and full name"
                      ]
                    }
                  },
                  "Invalid session id": {
                    "value": {
                      "session_id": [
                        "Must be a valid UUID."
                      ]
                    }
                  },
                  "Missing session id": {
                    "value": {
                      "session_id": [
                        "This field is required."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. 기타 인증 실패 시에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` 헤더가 누락되었거나(잘못되었거나 해지되었거나 만료된 키는 `401` 반환), 범위가 지정된 API 키에 `workflows: write` 권한이 없거나 허용 목록 외부의 IP 주소에서 사용되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/blocklist/remove/": {
      "post": {
        "summary": "차단 목록에서 세션 항목 제거",
        "description": "애플리케이션의 개인 인증 세션 하나에 연결된 얼굴, 신분증, 전화번호 또는 이메일 주소의 차단을 해제합니다. 선택한 각 유형에 대해 Didit은 해당 세션의 가장 최근 레코드를 가져와 차단 목록 플래그를 지우고 해당 레코드에서 생성된 시스템 차단 목록 항목을 삭제하여 새 세션이 더 이상 거부되지 않도록 합니다. 값으로 목록에 추가된 항목은 변경되지 않습니다. [List list entries](https://docs.didit.me/ko/management-api/lists/list-entries)로 찾고 [Delete a list entry](https://docs.didit.me/ko/management-api/lists/delete-entry)로 삭제하십시오. 차단 목록에 없는 레코드의 차단을 해제해도 오류 없이 완료되며 아무것도 변경되지 않고, 이미 완료된 세션은 변경되지 않습니다. 범위가 지정된 API 키에는 `workflows: write`가 필요합니다.",
        "operationId": "remove_from_blocklist",
        "x-didit-sdk": {
          "resource": "blocklist",
          "method": "remove",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Blocklist"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "session_id"
                ],
                "description": "최소 하나의 `unblock_*` 플래그가 `true`여야 합니다.",
                "properties": {
                  "session_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "애플리케이션의 사용자 인증 세션입니다. 삭제된 세션은 거부됩니다."
                  },
                  "unblock_face": {
                    "type": "boolean",
                    "default": false,
                    "description": "세션의 얼굴에 대한 차단을 해제합니다."
                  },
                  "unblock_document": {
                    "type": "boolean",
                    "default": false,
                    "description": "세션의 신분증에 대한 차단을 해제합니다."
                  },
                  "unblock_phone": {
                    "type": "boolean",
                    "default": false,
                    "description": "세션의 전화번호에 대한 차단을 해제합니다."
                  },
                  "unblock_email": {
                    "type": "boolean",
                    "default": false,
                    "description": "세션의 이메일 주소에 대한 차단을 해제합니다."
                  }
                }
              },
              "examples": {
                "Face and document": {
                  "value": {
                    "session_id": "33333333-4444-5555-6666-777777777777",
                    "unblock_face": true,
                    "unblock_document": true
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/blocklist/remove/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"session_id\": \"33333333-4444-5555-6666-777777777777\",\n    \"unblock_face\": true,\n    \"unblock_document\": true\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.blocklist.remove(\n    session_id=\"33333333-4444-5555-6666-777777777777\",\n    unblock_face=True,\n    unblock_document=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.blocklist.remove({\n  session_id: \"33333333-4444-5555-6666-777777777777\",\n  unblock_face: true,\n  unblock_document: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Blocklist.Remove(ctx, didit.BlocklistRemoveParams{\n\tSessionID:       \"33333333-4444-5555-6666-777777777777\",\n\tUnblockFace:     didit.Bool(true),\n\tUnblockDocument: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BlocklistRemoveParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.blocklist().remove(BlocklistRemoveParams.builder()\n        .sessionId(\"33333333-4444-5555-6666-777777777777\")\n        .unblockFace(true)\n        .unblockDocument(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->blocklist->remove([\n    'session_id' => '33333333-4444-5555-6666-777777777777',\n    'unblock_face' => true,\n    'unblock_document' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.blocklist.remove(\n  session_id: \"33333333-4444-5555-6666-777777777777\",\n  unblock_face: true,\n  unblock_document: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Blocklist.RemoveAsync(new BlocklistRemoveParams\n{\n    SessionId = \"33333333-4444-5555-6666-777777777777\",\n    UnblockFace = true,\n    UnblockDocument = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "선택한 항목에 대한 차단이 해제되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "message"
                  ],
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "항상 `Successfully removed from blocklist.`입니다."
                    }
                  }
                },
                "examples": {
                  "Unblocked": {
                    "value": {
                      "message": "Successfully removed from blocklist."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "본문이 잘못되었거나, 세션이 이 애플리케이션의 인증 세션이 아니거나, 선택한 유형의 기록이 없습니다. 변경된 내용이 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown session": {
                    "value": {
                      "non_field_errors": [
                        "Session not found"
                      ]
                    }
                  },
                  "No item selected": {
                    "value": {
                      "non_field_errors": [
                        "Must specify at least one item to unblock"
                      ]
                    }
                  },
                  "No email record": {
                    "value": {
                      "non_field_errors": [
                        "Session does not have an email record"
                      ]
                    }
                  },
                  "Invalid session id": {
                    "value": {
                      "session_id": [
                        "Must be a valid UUID."
                      ]
                    }
                  },
                  "Missing session id": {
                    "value": {
                      "session_id": [
                        "This field is required."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. 기타 인증 실패 시에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` 헤더가 누락되었거나(잘못되었거나 해지되었거나 만료된 키는 `401` 반환), 범위가 지정된 API 키에 `workflows: write` 권한이 없거나 허용 목록 외부의 IP 주소에서 사용되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/": {
      "get": {
        "summary": "webhook 구성 가져오기",
        "description": "한 번의 호출로 애플리케이션의 webhook 설정을 반환합니다. 서명 비밀이 포함된 각 [webhook 대상](https://docs.didit.me/ko/management-api/webhook/list-destinations), 대상이 구독할 수 있는 이벤트 유형, 애플리케이션 수준(레거시) webhook URL, 버전 및 비밀, 데이터 및 생체 인식 템플릿 보존 정책, Digital ID 지갑 반환 호스트가 포함됩니다. Didit은 각각 자체 `secret_shared_key`로 서명된 webhook을 대상에 전송합니다. 최상위 `webhook_url`, `webhook_version` 및 `secret_shared_key`는 활성화된 대상이 없을 때만 사용되며, 그 경우에도 `status.updated` 및 `data.updated`에 대해서만 사용됩니다. 응답에 서명 비밀이 포함되어 있으므로 로그나 클라이언트 측 코드에 노출되지 않도록 주의하십시오. 범위가 지정된 API 키에는 `webhooks: read` 권한이 필요합니다.",
        "operationId": "get_webhook_config",
        "x-didit-sdk": {
          "resource": "webhooks",
          "method": "retrieve_config",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/webhook/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.retrieve_config()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.retrieveConfig();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.RetrieveConfig(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().retrieveConfig();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->retrieveConfig();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.retrieve_config\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.RetrieveConfigAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "webhook 구성입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookConfig"
                },
                "examples": {
                  "One destination": {
                    "value": {
                      "webhook_url": "https://yourapp.com/webhooks/didit",
                      "webhook_version": "v3",
                      "secret_shared_key": "dGhpcy1pcy10aGUtYXBwLWxldmVsLXNlY3JldC0wMDA",
                      "capture_method": "MOBILE",
                      "data_retention_months": 24,
                      "face_retention_policy": "delete_with_session",
                      "face_retention_days": null,
                      "biometric_consent_mode": "auto",
                      "available_events": [
                        {
                          "value": "status.updated",
                          "label": "Session status updated"
                        },
                        {
                          "value": "data.updated",
                          "label": "Session data updated"
                        },
                        {
                          "value": "user.status.updated",
                          "label": "User status updated"
                        },
                        {
                          "value": "user.data.updated",
                          "label": "User data updated"
                        },
                        {
                          "value": "business.status.updated",
                          "label": "Business status updated"
                        },
                        {
                          "value": "business.data.updated",
                          "label": "Business data updated"
                        },
                        {
                          "value": "activity.created",
                          "label": "Activity created"
                        },
                        {
                          "value": "transaction.created",
                          "label": "Transaction created"
                        },
                        {
                          "value": "transaction.status.updated",
                          "label": "Transaction status updated"
                        },
                        {
                          "value": "travel_rule.status.updated",
                          "label": "Travel Rule Status Updated"
                        },
                        {
                          "value": "workflow.compliance_changed",
                          "label": "Workflow Compliance Changed"
                        }
                      ],
                      "allowed_return_hosts": [
                        "shop.example.com"
                      ],
                      "endpoints": [
                        {
                          "uuid": "11111111-2222-3333-4444-555555555555",
                          "label": "Production session webhooks",
                          "url": "https://yourapp.com/webhooks/didit",
                          "enabled": true,
                          "webhook_version": "v3",
                          "secret_shared_key": "dGhpcy1pcy1hbi1leGFtcGxlLXNlY3JldC0wMDAwMDA",
                          "subscribed_events": [
                            "status.updated",
                            "data.updated"
                          ],
                          "created_at": "2026-01-04T08:00:00.000000Z",
                          "updated_at": "2026-04-22T14:09:11.523671Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 생성 시 설정된 만료일이 지났습니다. 잘못되었거나 취소된 키도 `401`을 수신하며, 누락된 키는 `403`을 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. `x-api-key`가 누락되었거나 유효하지 않거나 폐기된 경우 `You do not have permission to perform this action.`을 수신합니다. 이 endpoint에 필요한 접근 권한이 없는 범위 지정 키는 누락된 권한을 명시하는 메시지를 수신하며, IP 허용 목록 외부에서 사용된 키는 `This API key can't be used from this IP address.`를 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks read": {
                    "value": {
                      "detail": "This API key has no read access to webhooks."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: 이 API 키의 현재 1분 시간 창에서 600개를 초과하는 GET 요청이 발생했습니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요.",
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "1분 동안 허용되는 요청 수(600)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "현재 윈도우가 리셋되는 Unix 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "초과된 예산의 이름입니다.",
                "schema": {
                  "type": "string",
                  "example": "generic-get"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "webhook 구성 업데이트",
        "description": "애플리케이션 수준 설정을 부분 업데이트합니다. 레거시 webhook URL, 버전 및 시크릿, 데이터 및 생체 인식 템플릿 보존 정책, Digital ID 지갑 반환 호스트가 포함됩니다. 변경할 필드만 전송하세요. 응답은 `GET /v3/webhook/`과 동일한 형태의 전체 구성입니다. 대상은 여기서 관리되지 않습니다. `/v3/webhook/destinations/` endpoint를 사용하여 대상을 생성, 업데이트 및 삭제하고, 이 endpoint에 `endpoints` 필드를 전송하지 마세요. `data_retention_months` 변경 사항은 기존 세션에도 적용되며, 이로 인해 삭제된 세션은 복구할 수 없습니다. 먼저 [데이터 보존](https://docs.didit.me/ko/console/data-retention)을 확인하세요. 범위가 지정된 API 키에는 `webhooks: write`가 필요합니다.",
        "operationId": "update_webhook_config",
        "x-didit-sdk": {
          "resource": "webhooks",
          "method": "update_config",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "변경할 필드만 전송하십시오. 대상은 여기서 관리되지 않습니다.",
                "properties": {
                  "webhook_url": {
                    "type": "string",
                    "format": "uri",
                    "nullable": true,
                    "maxLength": 2000,
                    "description": "레거시 애플리케이션 수준 webhook URL입니다. Didit은 애플리케이션에 활성화된 대상이 없을 때만 이를 사용하며, 그 경우에도 `status.updated` 및 `data.updated`에만 사용합니다. 이는 대상을 생성하지 않으며, 다음 대상 생성, 업데이트 또는 삭제 시 대체됩니다. webhook을 수신하려면 대신 `POST /v3/webhook/destinations/`로 대상을 생성하세요."
                  },
                  "webhook_version": {
                    "type": "string",
                    "enum": [
                      "v1",
                      "v2",
                      "v3"
                    ],
                    "description": "레거시 `webhook_url`의 payload 버전입니다."
                  },
                  "rotate_secret_key": {
                    "type": "boolean",
                    "default": false,
                    "description": "`true`는 애플리케이션 수준의 `secret_shared_key`를 새로운 임의의 값으로 즉시 교체하며, 새 값은 응답에 포함됩니다. 대상 비밀은 변경되지 않습니다. `true`로 호출할 때마다 새 비밀이 생성되므로 멱등적이지 않습니다."
                  },
                  "capture_method": {
                    "type": "string",
                    "enum": [
                      "MOBILE",
                      "MOBILE_AND_DESKTOP"
                    ],
                    "description": "레거시 애플리케이션 설정입니다. 인증 흐름에서는 이를 읽지 않습니다."
                  },
                  "data_retention_months": {
                    "type": "integer",
                    "nullable": true,
                    "minimum": 1,
                    "maximum": 120,
                    "description": "자동 삭제 기간(월 단위, 1개월은 30일로 계산) 또는 자동 삭제를 사용하지 않는 경우 `null`입니다. 변경 사항은 기존 세션에도 적용됩니다. 새로운 기간보다 오래된 모든 사용자 인증 세션은 자동으로 삭제되며, 해당 삭제는 되돌릴 수 없습니다."
                  },
                  "face_retention_policy": {
                    "type": "string",
                    "enum": [
                      "delete_with_session",
                      "retain_until_user_deleted"
                    ],
                    "description": "세션이 삭제될 때 세션의 얼굴 임베딩에 수행되는 작업입니다. `retain_until_user_deleted`를 사용하려면 동일한 요청에 `face_retention_days`가 포함되어 있거나 이미 설정되어 있어야 합니다. 변경 사항은 이후의 세션 삭제부터 적용되며, 기존 생체 인식 템플릿을 생성하거나 영구 삭제하지 않습니다."
                  },
                  "face_retention_days": {
                    "type": "integer",
                    "nullable": true,
                    "minimum": 1,
                    "maximum": 3650,
                    "description": "`retain_until_user_deleted` 적용 시 생체 인식 템플릿의 보존 기간(일)입니다."
                  },
                  "biometric_consent_mode": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "always",
                      "never"
                    ],
                    "description": "호스팅 플로우 및 네이티브 SDK에서 얼굴 캡처 전 사용자에게 명시적인 생체 인식 동의를 요청하는 시점입니다. `auto`(기본값)는 선언된 주, 사용자의 IP, 또는 신분증 발급 국가/지역이 일리노이, 텍사스, 콜로라도에 해당하거나 사용자가 주 정보 없이 미국 내에 있는 것으로 보일 때와 같이 트리거가 적용되는 경우에만 요청합니다. `always`는 얼굴을 캡처하는 워크플로의 모든 사용자에게 요청합니다. `never`는 해당 단계를 절대 표시하지 않으며, 셀피 촬영 전에 직접 동의를 수집해야 합니다. 모든 변경 사항은 감사 로그에 기록됩니다. [생체 인식 동의](https://docs.didit.me/ko/getting-started/biometric-consent)를 참고하십시오."
                  },
                  "allowed_return_hosts": {
                    "type": "array",
                    "maxItems": 20,
                    "description": "디지털 ID 지갑 반환 호스트의 전체 목록을 대체합니다. `shop.example.com`과 같은 순수 호스트 이름만 허용되며 스킴, 포트, 경로 또는 와일드카드는 사용할 수 없습니다. 값은 소문자로 변환되며 중복은 제거됩니다. 목록을 지우려면 `[]`를 전송하십시오.",
                    "items": {
                      "type": "string",
                      "maxLength": 253
                    }
                  },
                  "allowed_domains": {
                    "type": "array",
                    "maxItems": 50,
                    "items": {
                      "type": "string",
                      "maxLength": 300
                    },
                    "description": "허용된 오리진의 전체 목록을 대체합니다. 오리진(예: `https://app.example.com`, `localhost`의 경우에만 `http`)은 호스팅 인증 플로우가 임베드될 수 있고 세션 콜백을 통해 사용자를 다시 보낼 수 있는 위치입니다. 서버 간 호출에는 영향을 미치지 않습니다. 빈 목록은 제한이 없음을 의미합니다. Didit은 기본 포트 없이 각 오리진을 소문자로 저장합니다. 유효하지 않은 항목은 `allowed_domains`에서 `400` 오류가 발생합니다. 제한을 제거하려면 `[]`를 전송하십시오.",
                    "example": [
                      "https://app.example.com"
                    ]
                  }
                }
              },
              "examples": {
                "Enable biometric template retention": {
                  "value": {
                    "face_retention_policy": "retain_until_user_deleted",
                    "face_retention_days": 365,
                    "biometric_consent_mode": "auto"
                  }
                },
                "Rotate the legacy secret": {
                  "value": {
                    "rotate_secret_key": true
                  }
                },
                "Set data retention": {
                  "value": {
                    "data_retention_months": 24
                  }
                },
                "Register return hosts": {
                  "value": {
                    "allowed_return_hosts": [
                      "shop.example.com",
                      "app.example.com"
                    ]
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/webhook/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"face_retention_policy\": \"retain_until_user_deleted\", \"face_retention_days\": 365}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.update_config(\n    face_retention_policy=\"retain_until_user_deleted\",\n    face_retention_days=365,\n    biometric_consent_mode=\"auto\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.updateConfig({\n  face_retention_policy: \"retain_until_user_deleted\",\n  face_retention_days: 365,\n  biometric_consent_mode: \"auto\",\n});\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.WebhooksUpdateConfigParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().updateConfig(WebhooksUpdateConfigParams.builder()\n        .faceRetentionPolicy(WebhooksUpdateConfigParams.FaceRetentionPolicy.of(\"retain_until_user_deleted\"))\n        .faceRetentionDays(365L)\n        .biometricConsentMode(WebhooksUpdateConfigParams.BiometricConsentMode.of(\"auto\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->updateConfig([\n    'face_retention_policy' => 'retain_until_user_deleted',\n    'face_retention_days' => 365,\n    'biometric_consent_mode' => 'auto',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.update_config(\n  face_retention_policy: \"retain_until_user_deleted\",\n  face_retention_days: 365,\n  biometric_consent_mode: \"auto\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.UpdateConfigAsync(new WebhooksUpdateConfigParams\n{\n    FaceRetentionPolicy = new WebhooksUpdateConfigParamsFaceRetentionPolicy(\"retain_until_user_deleted\"),\n    FaceRetentionDays = 365,\n    BiometricConsentMode = new WebhooksUpdateConfigParamsBiometricConsentMode(\"auto\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "업데이트 후의 전체 설정으로, `GET /v3/webhook/`과 동일한 형태입니다. 시크릿을 교체한 경우 응답을 폐기하기 전에 새 `secret_shared_key`를 저장하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookConfig"
                },
                "examples": {
                  "Retention enabled": {
                    "value": {
                      "webhook_url": "https://yourapp.com/webhooks/didit",
                      "webhook_version": "v3",
                      "secret_shared_key": "dGhpcy1pcy10aGUtYXBwLWxldmVsLXNlY3JldC0wMDA",
                      "capture_method": "MOBILE",
                      "data_retention_months": 24,
                      "face_retention_policy": "retain_until_user_deleted",
                      "face_retention_days": 365,
                      "biometric_consent_mode": "auto",
                      "available_events": [
                        {
                          "value": "status.updated",
                          "label": "Session status updated"
                        },
                        {
                          "value": "data.updated",
                          "label": "Session data updated"
                        },
                        {
                          "value": "user.status.updated",
                          "label": "User status updated"
                        },
                        {
                          "value": "user.data.updated",
                          "label": "User data updated"
                        },
                        {
                          "value": "business.status.updated",
                          "label": "Business status updated"
                        },
                        {
                          "value": "business.data.updated",
                          "label": "Business data updated"
                        },
                        {
                          "value": "activity.created",
                          "label": "Activity created"
                        },
                        {
                          "value": "transaction.created",
                          "label": "Transaction created"
                        },
                        {
                          "value": "transaction.status.updated",
                          "label": "Transaction status updated"
                        },
                        {
                          "value": "travel_rule.status.updated",
                          "label": "Travel Rule Status Updated"
                        },
                        {
                          "value": "workflow.compliance_changed",
                          "label": "Workflow Compliance Changed"
                        }
                      ],
                      "allowed_return_hosts": [
                        "shop.example.com"
                      ],
                      "endpoints": [
                        {
                          "uuid": "11111111-2222-3333-4444-555555555555",
                          "label": "Production session webhooks",
                          "url": "https://yourapp.com/webhooks/didit",
                          "enabled": true,
                          "webhook_version": "v3",
                          "secret_shared_key": "dGhpcy1pcy1hbi1leGFtcGxlLXNlY3JldC0wMDAwMDA",
                          "subscribed_events": [
                            "status.updated",
                            "data.updated"
                          ],
                          "created_at": "2026-01-04T08:00:00.000000Z",
                          "updated_at": "2026-04-22T14:09:11.523671Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 실패: 유효하지 않은 각 필드가 메시지 목록에 매핑되며, 아무것도 변경되지 않습니다. 유효한 JSON이 아닌 본문은 `{\"detail\": \"JSON parse error - ...\"}`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "각 유효하지 않은 필드를 메시지 목록에 매핑한 것입니다.",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Retention days missing": {
                    "value": {
                      "face_retention_days": [
                        "A finite retention duration is required when face retention is enabled."
                      ],
                      "biometric_consent_mode": "auto"
                    }
                  },
                  "Retention window out of range": {
                    "value": {
                      "data_retention_months": [
                        "Ensure this value is less than or equal to 120."
                      ]
                    }
                  },
                  "Invalid return host": {
                    "value": {
                      "allowed_return_hosts": [
                        "'https://shop.example.com' is not a hostname. Register the bare host (e.g. shop.example.com): no scheme, port, path or wildcard."
                      ]
                    }
                  },
                  "Invalid choice": {
                    "value": {
                      "face_retention_policy": [
                        "\"forever\" is not a valid choice."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 생성 시 설정된 만료일이 지났습니다. 잘못되었거나 취소된 키도 `401`을 수신하며, 누락된 키는 `403`을 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. `x-api-key`가 누락되었거나 유효하지 않거나 폐기된 경우 `You do not have permission to perform this action.`을 수신합니다. 이 endpoint에 필요한 접근 권한이 없는 범위 지정 키는 누락된 권한을 명시하는 메시지를 수신하며, IP 허용 목록 외부에서 사용된 키는 `This API key can't be used from this IP address.`를 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks write": {
                    "value": {
                      "detail": "This API key has no write access to webhooks."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: 이 API 키의 현재 1분 시간 창에서 300개를 초과하는 쓰기 요청(POST, PATCH, PUT, DELETE)이 발생했습니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요.",
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "1분 동안 허용되는 요청 수(300)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "현재 윈도우가 리셋되는 Unix 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "초과된 예산의 이름입니다.",
                "schema": {
                  "type": "string",
                  "example": "generic-write"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/destinations/{destination_uuid}/analytics/": {
      "get": {
        "summary": "webhook 대상 분석 가져오기",
        "description": "단일 webhook 대상에 대한 전체 범위(`summary`) 및 UTC 일별(`points`) 전송 합계, 실패율 및 응답 시간입니다. 모든 시도가 전송으로 집계됩니다: 이벤트의 첫 발송, 각 자동 [재시도](https://docs.didit.me/ko/integration/webhooks#재시도-정책) 및 각 재발송. 기록된 HTTP 상태가 400 이상인 경우 전송 실패로 간주되므로, 타임아웃(`504`로 기록) 및 연결 실패(`503`)도 실패로 집계됩니다. 아직 대기열에 있는 전송은 `total_deliveries`에만 집계됩니다. 전송 기록은 약 30일 동안 유지됩니다. 범위가 지정된 API 키에는 `webhooks: read` 권한이 필요합니다.",
        "operationId": "get_webhook_destination_analytics",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "retrieve_analytics",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "webhook 대상의 UUID입니다(`GET /v3/webhook/destinations/`에서 반환된 `uuid`).",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "description": "포함할 첫 번째 UTC 날짜로, `YYYY-MM-DD` 형식(포함)입니다. 사용 가능한 가장 오래된 전송부터 시작하려면 생략하십시오. `dateFrom`도 별칭으로 허용됩니다.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-10-01"
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "description": "포함할 마지막 UTC 일자(`YYYY-MM-DD`, 해당 일자 포함)입니다. `date_from`보다 이전일 수 없습니다. `dateTo`도 별칭으로 허용됩니다.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-10-16"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/analytics/?date_from=2026-10-01&date_to=2026-10-16' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.retrieve_analytics(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.retrieveAnalytics(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.RetrieveAnalytics(ctx, \"11111111-2222-3333-4444-555555555555\", didit.WebhooksDestinationsRetrieveAnalyticsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().retrieveAnalytics(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->retrieveAnalytics('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.retrieve_analytics(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.RetrieveAnalyticsAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "해당 대상의 전송 통계입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "summary",
                    "points"
                  ],
                  "properties": {
                    "summary": {
                      "type": "object",
                      "description": "요청된 기간에 대한 합계입니다.",
                      "required": [
                        "total_deliveries",
                        "failed_deliveries",
                        "min_response_time_ms",
                        "avg_response_time_ms",
                        "max_response_time_ms",
                        "error_rate_percentage"
                      ],
                      "properties": {
                        "total_deliveries": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "대기열에 있는 시도를 포함한 전송 시도입니다."
                        },
                        "failed_deliveries": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "기록된 HTTP 상태가 400 이상인 시도 횟수입니다."
                        },
                        "min_response_time_ms": {
                          "type": "integer",
                          "nullable": true,
                          "description": "밀리초 단위의 가장 빠른 시도 시간이며, 기록된 시간이 있는 시도가 없는 경우 `null`입니다."
                        },
                        "avg_response_time_ms": {
                          "type": "integer",
                          "nullable": true,
                          "description": "밀리초 단위의 평균 시도 시간(반올림됨)이며, 기록된 시간이 있는 시도가 없는 경우 `null`입니다."
                        },
                        "max_response_time_ms": {
                          "type": "integer",
                          "nullable": true,
                          "description": "밀리초 단위의 가장 느린 시도 시간이며, 기록된 시간이 있는 시도가 없으면 `null`입니다."
                        },
                        "error_rate_percentage": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 100,
                          "description": "`failed_deliveries` / `total_deliveries` x 100, 정수로 반올림. 전송이 없는 경우 `0`."
                        }
                      }
                    },
                    "points": {
                      "type": "array",
                      "description": "전송이 발생한 UTC 일자당 항목 1개(가장 오래된 항목부터 정렬)입니다. 전송이 없었던 날은 생략되므로 차트로 표시할 때는 빈 구간을 0으로 채우세요.",
                      "items": {
                        "type": "object",
                        "required": [
                          "date",
                          "total_deliveries",
                          "failed_deliveries",
                          "min_response_time_ms",
                          "avg_response_time_ms",
                          "max_response_time_ms"
                        ],
                        "properties": {
                          "date": {
                            "type": "string",
                            "format": "date",
                            "description": "UTC 날짜, `YYYY-MM-DD`입니다."
                          },
                          "total_deliveries": {
                            "type": "integer",
                            "minimum": 0,
                            "description": "대기열에 있는 시도를 포함한 전송 시도입니다."
                          },
                          "failed_deliveries": {
                            "type": "integer",
                            "minimum": 0,
                            "description": "기록된 HTTP 상태가 400 이상인 시도 횟수입니다."
                          },
                          "min_response_time_ms": {
                            "type": "integer",
                            "nullable": true,
                            "description": "밀리초 단위의 가장 빠른 시도 시간이며, 기록된 시간이 있는 시도가 없는 경우 `null`입니다."
                          },
                          "avg_response_time_ms": {
                            "type": "integer",
                            "nullable": true,
                            "description": "밀리초 단위의 평균 시도 시간(반올림됨)이며, 기록된 시간이 있는 시도가 없는 경우 `null`입니다."
                          },
                          "max_response_time_ms": {
                            "type": "integer",
                            "nullable": true,
                            "description": "밀리초 단위의 가장 느린 시도 시간이며, 기록된 시간이 있는 시도가 없으면 `null`입니다."
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Three days of deliveries": {
                    "value": {
                      "summary": {
                        "total_deliveries": 1250,
                        "failed_deliveries": 12,
                        "min_response_time_ms": 38,
                        "avg_response_time_ms": 164,
                        "max_response_time_ms": 5004,
                        "error_rate_percentage": 1
                      },
                      "points": [
                        {
                          "date": "2026-10-14",
                          "total_deliveries": 410,
                          "failed_deliveries": 0,
                          "min_response_time_ms": 38,
                          "avg_response_time_ms": 152,
                          "max_response_time_ms": 911
                        },
                        {
                          "date": "2026-10-15",
                          "total_deliveries": 395,
                          "failed_deliveries": 12,
                          "min_response_time_ms": 41,
                          "avg_response_time_ms": 190,
                          "max_response_time_ms": 5004
                        },
                        {
                          "date": "2026-10-16",
                          "total_deliveries": 445,
                          "failed_deliveries": 0,
                          "min_response_time_ms": 40,
                          "avg_response_time_ms": 151,
                          "max_response_time_ms": 1220
                        }
                      ]
                    }
                  },
                  "No deliveries in range": {
                    "value": {
                      "summary": {
                        "total_deliveries": 0,
                        "failed_deliveries": 0,
                        "min_response_time_ms": null,
                        "avg_response_time_ms": null,
                        "max_response_time_ms": null,
                        "error_rate_percentage": 0
                      },
                      "points": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`date_from` 또는 `date_to`가 `YYYY-MM-DD` 형식의 날짜가 아니거나, `date_to`가 `date_from`보다 이전입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "각 유효하지 않은 필드를 메시지 목록에 매핑한 것입니다.",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Malformed date": {
                    "value": {
                      "date_from": [
                        "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
                      ]
                    }
                  },
                  "Reversed range": {
                    "value": {
                      "date_to": [
                        "date_to must be greater than or equal to date_from."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 생성 시 설정된 만료일이 지났습니다. 잘못되었거나 취소된 키도 `401`을 수신하며, 누락된 키는 `403`을 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. `x-api-key`가 누락되었거나 유효하지 않거나 폐기된 경우 `You do not have permission to perform this action.`을 수신합니다. 이 endpoint에 필요한 접근 권한이 없는 범위 지정 키는 누락된 권한을 명시하는 메시지를 수신하며, IP 허용 목록 외부에서 사용된 키는 `This API key can't be used from this IP address.`를 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks read": {
                    "value": {
                      "detail": "This API key has no read access to webhooks."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 이 UUID를 가진 대상이 존재하지 않거나 삭제되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Destination not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: 이 API 키의 현재 1분 시간 창에서 600개를 초과하는 GET 요청이 발생했습니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요.",
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "1분 동안 허용되는 요청 수(600)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "현재 윈도우가 리셋되는 Unix 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "초과된 예산의 이름입니다.",
                "schema": {
                  "type": "string",
                  "example": "generic-get"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/destinations/{destination_uuid}/deliveries/": {
      "get": {
        "summary": "webhook 대상 전송 내역 목록 조회",
        "description": "하나의 webhook 대상으로 전송된 모든 시도를 최신순으로 페이징합니다. 각 이벤트의 첫 번째 전송, 각 자동 [재시도](https://docs.didit.me/ko/integration/webhooks#재시도-정책) 및 각 재전송은 개별 항목으로 구분됩니다. 항목에는 HTTP 상태 및 응답 시간이 포함되지만 payload는 포함되지 않으므로, 헤더와 본문을 확인하려면 단일 전송 건을 조회하십시오. `count`는 100까지 정확하며 그 이상은 100으로 표시되므로 `next`가 `null`이 될 때까지 따라가십시오. 전송 기록은 약 30일 동안 사용할 수 있습니다. 범위가 지정된 API 키에는 `webhooks: read` 및 `decisions: read` 권한이 필요합니다. 일부 워크플로 또는 승인된 세션으로 제한된 키는 이 endpoint를 사용할 수 없습니다.",
        "operationId": "list_webhook_destination_deliveries",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "list_deliveries",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "webhook 대상의 UUID입니다(`GET /v3/webhook/destinations/`에서 반환된 `uuid`).",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "페이지당 최대 전송 건수입니다. 기본값은 50입니다. 양의 정수가 아닌 값은 50으로 대체되며, 1000000을 초과하는 값은 `400`을 반환합니다.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "example": 50
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "건너뛸 전송 수입니다. 기본값은 0입니다. 응답의 `next` 및 `previous` URL을 따르는 것을 권장합니다.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "example": 0
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "description": "포함할 첫 번째 UTC 날짜로, `YYYY-MM-DD` 형식(포함)입니다. 사용 가능한 가장 오래된 전송부터 시작하려면 생략하십시오. `dateFrom`도 별칭으로 허용됩니다.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-10-01"
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "description": "포함할 마지막 UTC 일자(`YYYY-MM-DD`, 해당 일자 포함)입니다. `date_from`보다 이전일 수 없습니다. `dateTo`도 별칭으로 허용됩니다.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-10-16"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/deliveries/?limit=50&date_from=2026-10-01' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.webhooks.destinations.list_deliveries(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.webhooks.destinations.listDeliveries(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Webhooks.Destinations.ListDeliveriesAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.WebhooksDestinationsListDeliveriesParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.webhooks().destinations().listDeliveries(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->webhooks->destinations->listDeliveries('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.webhooks.destinations.list_deliveries(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Webhooks.Destinations.ListDeliveriesAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "최신순으로 정렬된 전송 페이지 하나입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "일치하는 전송 건수이며 100개까지는 정확하고 그 이상은 100개로 제한됩니다. 추가 페이지가 있는지 확인하려면 `next`를 사용하십시오."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "다음 페이지의 절대 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "이전 페이지의 절대 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDestinationDelivery"
                      }
                    }
                  }
                },
                "examples": {
                  "Failed delivery, its retry and a queued event": {
                    "value": {
                      "count": 3,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "66666666-7777-8888-9999-000000000003",
                          "session_id": null,
                          "request_url": "https://yourapp.com/webhooks/didit",
                          "response_status": null,
                          "response_time_ms": null,
                          "status": "APPROVED",
                          "webhook_type": "transaction.created",
                          "created_at": "2026-10-15T09:23:02.871190Z"
                        },
                        {
                          "uuid": "66666666-7777-8888-9999-000000000002",
                          "session_id": "22222222-3333-4444-5555-666666666666",
                          "request_url": "https://yourapp.com/webhooks/didit",
                          "response_status": 200,
                          "response_time_ms": 143,
                          "status": "In Progress",
                          "webhook_type": "status.updated",
                          "created_at": "2026-10-15T09:22:19.104233Z"
                        },
                        {
                          "uuid": "66666666-7777-8888-9999-000000000001",
                          "session_id": "22222222-3333-4444-5555-666666666666",
                          "request_url": "https://yourapp.com/webhooks/didit",
                          "response_status": 503,
                          "response_time_ms": 412,
                          "status": "In Progress",
                          "webhook_type": "status.updated",
                          "created_at": "2026-10-15T09:21:18.412345Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`date_from` 또는 `date_to`가 `YYYY-MM-DD` 형식의 날짜가 아니거나, `date_to`가 `date_from`보다 이전이거나, `limit` 또는 `offset`이 1000000을 초과합니다(해당 오류는 메시지의 JSON 배열로 반환됩니다).",
            "content": {
              "application/json": {
                "examples": {
                  "Malformed date": {
                    "value": {
                      "date_from": [
                        "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
                      ]
                    }
                  },
                  "Reversed range": {
                    "value": {
                      "date_to": [
                        "date_to must be greater than or equal to date_from."
                      ]
                    }
                  },
                  "Limit too large": {
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 생성 시 설정된 만료일이 지났습니다. 잘못되었거나 취소된 키도 `401`을 수신하며, 누락된 키는 `403`을 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. `x-api-key`가 누락되었거나 유효하지 않거나 폐기된 경우 `You do not have permission to perform this action.`을 수신합니다. 이 endpoint에 필요한 접근 권한이 없는 범위 지정 키는 누락된 권한을 명시하는 메시지를 수신하며, IP 허용 목록 외부에서 사용된 키는 `This API key can't be used from this IP address.`를 수신합니다. 일부 워크플로나 승인된 세션으로 제한된 키는 `This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint.`를 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks read": {
                    "value": {
                      "detail": "This API key has no read access to webhooks."
                    }
                  },
                  "Scoped key without decisions read": {
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "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."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 이 UUID를 가진 대상이 존재하지 않거나 삭제되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Destination not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: 이 API 키의 현재 1분 시간 창에서 600개를 초과하는 GET 요청이 발생했습니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요.",
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "1분 동안 허용되는 요청 수(600)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "현재 윈도우가 리셋되는 Unix 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "초과된 예산의 이름입니다.",
                "schema": {
                  "type": "string",
                  "example": "generic-get"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/destinations/{destination_uuid}/deliveries/{delivery_uuid}/": {
      "get": {
        "summary": "webhook 대상 전송 내역 가져오기",
        "description": "Didit이 전송한 정확한 요청 헤더와 JSON 본문, endpoint가 반환한 HTTP 상태 및 응답 시간을 포함하여 webhook 대상으로의 단일 전송 시도를 조회합니다. `request_header`와 `request_body`는 JSON 텍스트입니다. 서명 헤더와 payload를 읽으려면 이를 파싱하십시오. 예를 들어 대상의 `secret_shared_key`에 대해 [서명 검증](https://docs.didit.me/ko/integration/webhooks#서명-검증)을 확인할 수 있습니다. 전송 데이터에는 서명 비밀이 절대 포함되지 않으며, Didit은 endpoint의 응답 본문을 기록하지 않습니다. 범위가 지정된 API 키에는 `webhooks: read` 및 `decisions: read` 권한이 필요합니다. 일부 워크플로 또는 승인된 세션으로 제한된 키는 이 endpoint를 사용할 수 없습니다.",
        "operationId": "get_webhook_destination_delivery",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "retrieve_delivery",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "전송이 전달된 webhook 대상의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "delivery_uuid",
            "in": "path",
            "required": true,
            "description": "전송의 UUID입니다(`GET /v3/webhook/destinations/{destination_uuid}/deliveries/`에서 반환된 항목의 `uuid`).",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "66666666-7777-8888-9999-000000000001"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/deliveries/66666666-7777-8888-9999-000000000001/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.retrieve_delivery(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"66666666-7777-8888-9999-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.retrieveDelivery(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"66666666-7777-8888-9999-000000000001\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.RetrieveDelivery(ctx, \"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().retrieveDelivery(\"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->retrieveDelivery('11111111-2222-3333-4444-555555555555', '66666666-7777-8888-9999-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.retrieve_delivery(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"66666666-7777-8888-9999-000000000001\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.RetrieveDeliveryAsync(\"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "요청 헤더 및 본문이 포함된 전송입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDestinationDeliveryDetail"
                },
                "examples": {
                  "Connection failure": {
                    "value": {
                      "uuid": "66666666-7777-8888-9999-000000000001",
                      "session_id": "22222222-3333-4444-5555-666666666666",
                      "request_url": "https://yourapp.com/webhooks/didit",
                      "response_status": 503,
                      "response_time_ms": 412,
                      "status": "In Progress",
                      "webhook_type": "status.updated",
                      "created_at": "2026-10-15T09:21:18.412345Z",
                      "request_header": "{\"Content-Type\": \"application/json\", \"X-Signature\": \"a5e02a03404e1337a0198e6be15d34abbd053c658a0e51e5d0e78554213ef29b\", \"X-Signature-V2\": \"927e7cb770c94ce745939bff73f04aa200015f3bc64795ba46c2aaf78a6cedc5\", \"X-Signature-Simple\": \"e37b0d4c716c72bb5ae7127b9cc455d28ab4686e9e22312b4ec2327409a73302\", \"X-Timestamp\": \"1792056078\", \"User-Agent\": \"DiditWebhook/2.0 +https://didit.me\"}",
                      "request_body": "{\"application_id\":\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\"created_at\":1792056057,\"environment\":\"live\",\"event_id\":\"33333333-4444-5555-6666-777777777777\",\"sandbox_scenario\":null,\"session_id\":\"22222222-3333-4444-5555-666666666666\",\"status\":\"In Progress\",\"timestamp\":1792056078,\"vendor_data\":\"user-123\",\"webhook_type\":\"status.updated\",\"workflow_id\":\"44444444-5555-6666-7777-888888888888\",\"workflow_version\":3}"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 생성 시 설정된 만료일이 지났습니다. 잘못되었거나 취소된 키도 `401`을 수신하며, 누락된 키는 `403`을 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. `x-api-key`가 누락되었거나 유효하지 않거나 폐기된 경우 `You do not have permission to perform this action.`을 수신합니다. 이 endpoint에 필요한 접근 권한이 없는 범위 지정 키는 누락된 권한을 명시하는 메시지를 수신하며, IP 허용 목록 외부에서 사용된 키는 `This API key can't be used from this IP address.`를 수신합니다. 일부 워크플로나 승인된 세션으로 제한된 키는 `This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint.`를 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks read": {
                    "value": {
                      "detail": "This API key has no read access to webhooks."
                    }
                  },
                  "Scoped key without decisions read": {
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "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."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 해당 대상이 존재하지 않거나 삭제되었거나, 전송이 존재하지 않거나 다른 대상에 속해 있거나 더 이상 사용할 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Destination not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  },
                  "Delivery not found": {
                    "value": {
                      "detail": "Webhook delivery not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: 이 API 키의 현재 1분 시간 창에서 600개를 초과하는 GET 요청이 발생했습니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요.",
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "1분 동안 허용되는 요청 수(600)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "현재 윈도우가 리셋되는 Unix 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "초과된 예산의 이름입니다.",
                "schema": {
                  "type": "string",
                  "example": "generic-get"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/destinations/{destination_uuid}/deliveries/{delivery_uuid}/resend/": {
      "post": {
        "summary": "webhook 대상 전송 재전송",
        "description": "endpoint가 다운된 후 등 이전 전송을 다시 보냅니다. Didit은 저장된 payload를 가져와 새로운 `timestamp`를 설정하고, 대상의 현재 `secret_shared_key`(`X-Signature`, `X-Signature-V2`, `X-Signature-Simple` 및 `X-Timestamp`)로 다시 서명한 후, 대상의 URL이 이후 변경되었거나 대상이 비활성화되었더라도 해당 전송의 `request_url`로 POST 요청을 전송합니다. `event_id` 및 payload의 나머지 부분은 변경되지 않으므로 `event_id`를 기준으로 중복을 제거하십시오. 이 호출은 귀하의 endpoint 응답을 최대 5초 동안 대기하며, endpoint의 응답 결과와 관계없이 새 전송과 함께 `200`을 반환합니다(`response_status` 참조). 재전송은 자동으로 재시도되지 않으며, 호출할 때마다 다시 전송되어 새로운 전송이 생성됩니다. 또한 요청 본문은 없습니다. 범위가 지정된 API 키에는 `webhooks: write` 및 `decisions: read` 권한이 필요합니다. 일부 워크플로나 승인된 세션으로 제한된 키는 이 endpoint를 사용할 수 없습니다.",
        "operationId": "resend_webhook_destination_delivery",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "resend_delivery",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "전송이 전달된 webhook 대상의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "delivery_uuid",
            "in": "path",
            "required": true,
            "description": "다시 전송할 전송의 UUID입니다(`GET /v3/webhook/destinations/{destination_uuid}/deliveries/`에서 반환된 항목의 `uuid`).",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "66666666-7777-8888-9999-000000000001"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/deliveries/66666666-7777-8888-9999-000000000001/resend/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.resend_delivery(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"66666666-7777-8888-9999-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.resendDelivery(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"66666666-7777-8888-9999-000000000001\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.ResendDelivery(ctx, \"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().resendDelivery(\"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->resendDelivery('11111111-2222-3333-4444-555555555555', '66666666-7777-8888-9999-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.resend_delivery(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"66666666-7777-8888-9999-000000000001\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.ResendDeliveryAsync(\"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "이미 시도된 새 전송입니다. `response_status`는 이번에 endpoint가 응답한 내용(`504` 시간 초과, `503` 연결 실패)입니다. 원래 전송은 변경되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDestinationDeliveryDetail"
                },
                "examples": {
                  "Accepted on resend": {
                    "value": {
                      "uuid": "66666666-7777-8888-9999-000000000004",
                      "session_id": "22222222-3333-4444-5555-666666666666",
                      "request_url": "https://yourapp.com/webhooks/didit",
                      "response_status": 200,
                      "response_time_ms": 151,
                      "status": "In Progress",
                      "webhook_type": "status.updated",
                      "created_at": "2026-10-16T14:05:42.330981Z",
                      "request_header": "{\"Content-Type\": \"application/json\", \"X-Signature\": \"b8eb1e376517ee0cad8ba98ff7f8fd35fc72eca231000963a96a335f82328835\", \"X-Signature-V2\": \"9efd2ce9ed1303e1d05273ef9608a59363ed9789a05253db4748b3e8e50cb109\", \"X-Signature-Simple\": \"bf3a9dc04b2c20ab539203b0cd5cca2a10f630bf62d8feb6d68d82af80f64774\", \"X-Timestamp\": \"1792159542\", \"User-Agent\": \"DiditWebhook/2.0 +https://didit.me\"}",
                      "request_body": "{\"application_id\":\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\"created_at\":1792056057,\"environment\":\"live\",\"event_id\":\"33333333-4444-5555-6666-777777777777\",\"sandbox_scenario\":null,\"session_id\":\"22222222-3333-4444-5555-666666666666\",\"status\":\"In Progress\",\"timestamp\":1792159542,\"vendor_data\":\"user-123\",\"webhook_type\":\"status.updated\",\"workflow_id\":\"44444444-5555-6666-7777-888888888888\",\"workflow_version\":3}"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "저장된 전송 내역에 다시 서명할 수 없습니다. 아무것도 전송되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    },
                    "code": {
                      "type": "string",
                      "description": "기계 판독 가능한 고정 오류 코드입니다. `detail`이 아닌 이 값을 기준으로 분기 처리하십시오."
                    }
                  }
                },
                "examples": {
                  "Unsignable delivery": {
                    "value": {
                      "detail": "Invalid webhook data format",
                      "code": "invalid_webhook_payload"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 생성 시 설정된 만료일이 지났습니다. 잘못되었거나 취소된 키도 `401`을 수신하며, 누락된 키는 `403`을 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. `x-api-key`가 누락되었거나 유효하지 않거나 폐기된 경우 `You do not have permission to perform this action.`을 수신합니다. 이 endpoint에 필요한 접근 권한이 없는 범위 지정 키는 누락된 권한을 명시하는 메시지를 수신하며, IP 허용 목록 외부에서 사용된 키는 `This API key can't be used from this IP address.`를 수신합니다. 일부 워크플로나 승인된 세션으로 제한된 키는 `This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint.`를 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks write": {
                    "value": {
                      "detail": "This API key has no write access to webhooks."
                    }
                  },
                  "Scoped key without decisions read": {
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "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."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 해당 대상이 존재하지 않거나 삭제되었거나, 전송이 존재하지 않거나 다른 대상에 속해 있거나 더 이상 사용할 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Destination not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  },
                  "Delivery not found": {
                    "value": {
                      "detail": "Webhook delivery not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: 이 API 키의 현재 1분 시간 창에서 300개를 초과하는 쓰기 요청(POST, PATCH, PUT, DELETE)이 발생했습니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요.",
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "1분 동안 허용되는 요청 수(300)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "현재 윈도우가 리셋되는 Unix 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "초과된 예산의 이름입니다.",
                "schema": {
                  "type": "string",
                  "example": "generic-write"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/events/": {
      "get": {
        "summary": "모니터링 이벤트 목록 조회",
        "description": "애플리케이션에 저장된 모니터링 이벤트를 최신 `occurred_at` 순으로 나열하며, AND 조건으로 결합되는 선택적 필터를 사용할 수 있습니다. 다중 값 필터(`event_category`, `action_type`, `status`, `retention_class`)는 파라미터를 반복하여 지정하며 값 중 하나라도 일치하면 반환됩니다. 다른 필터는 정확히 일치해야 하며 알 수 없는 값은 이벤트를 반환하지 않습니다. 각 결과는 요약 정보입니다. payload, 기기 컨텍스트, IP 강화 데이터 및 규칙 증거를 확인하려면 `GET /v3/events/{event_uuid}/`를 호출하고, 단일 주체의 기록을 확인하려면 `GET /v3/events/subjects/{vendor_data}/`를 호출하는 것이 좋습니다. 이벤트 수집 활성화 여부와 관계없이 조회가 작동합니다. 범위가 지정된 API 키에는 `transactions: read` 권한이 필요합니다. [이벤트 수집](https://docs.didit.me/ko/transaction-monitoring/events)을 참조하십시오.",
        "operationId": "list_monitoring_events",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "페이지당 최대 이벤트 수입니다. 기본값은 50입니다. 1000000을 초과하는 값은 `400`을 반환하며, 숫자가 아니거나 0 또는 음수인 값은 50으로 대체됩니다.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "example": 50
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "건너뛸 이벤트 수입니다. 기본값은 0입니다. 응답의 `next` URL을 따르는 것을 권장합니다.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "example": 0
          },
          {
            "name": "event_category",
            "in": "query",
            "required": false,
            "description": "이 카테고리에 속하는 이벤트만 해당합니다. 여러 값을 지정하려면 파라미터를 반복하십시오(`?event_category=payment&event_category=dispute`). 이 중 하나라도 일치하는 이벤트가 반환됩니다.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "auth",
                  "session",
                  "gameplay",
                  "bonus",
                  "affiliate",
                  "payment",
                  "dispute",
                  "security",
                  "responsible_gambling",
                  "custom"
                ]
              }
            },
            "example": [
              "payment",
              "dispute"
            ]
          },
          {
            "name": "action_type",
            "in": "query",
            "required": false,
            "description": "이러한 작업 유형(정확히 일치, 대소문자 구분)의 이벤트만 해당합니다. 여러 값에 대해 반복하십시오.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "example": [
              "deposit_completed",
              "chargeback_opened"
            ]
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "이러한 상태의 이벤트만 해당합니다. 여러 값에 대해 반복하십시오.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "ACCEPTED",
                  "APPROVED",
                  "IN_REVIEW",
                  "DECLINED"
                ]
              }
            },
            "example": [
              "IN_REVIEW",
              "DECLINED"
            ]
          },
          {
            "name": "retention_class",
            "in": "query",
            "required": false,
            "description": "이 보존 등급에 속하는 이벤트만 해당합니다. 여러 값에 대해 반복하십시오.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "low_value",
                  "standard",
                  "risk_relevant",
                  "monetary_or_compliance"
                ]
              }
            },
            "example": [
              "risk_relevant"
            ]
          },
          {
            "name": "subject_vendor_data",
            "in": "query",
            "required": false,
            "description": "주체의 `vendor_data`에 대한 정확한 일치입니다. 동일한 ID가 개인과 기업을 모두 가리킬 수 있으므로, `subject_entity_type`을 추가하여 하나를 선택하거나 `GET /v3/events/subjects/{vendor_data}/`를 사용하십시오.",
            "schema": {
              "type": "string"
            },
            "example": "user-42"
          },
          {
            "name": "subject_entity_type",
            "in": "query",
            "required": false,
            "description": "`company`는 기업 대상의 이벤트만 반환합니다. 비어 있지 않은 다른 값(예: `individual`)은 개인의 이벤트만 반환합니다. 둘 다 반환하려면 생략하세요.",
            "schema": {
              "type": "string",
              "enum": [
                "individual",
                "company"
              ]
            },
            "example": "individual"
          },
          {
            "name": "business_vendor_data",
            "in": "query",
            "required": false,
            "description": "이벤트와 함께 전송된 `business.vendor_data`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "merchant-7"
          },
          {
            "name": "session_id",
            "in": "query",
            "required": false,
            "description": "`session.session_id`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "web-session-abc"
          },
          {
            "name": "device_fingerprint",
            "in": "query",
            "required": false,
            "description": "`device_context.fingerprint`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "fp-a8c1"
          },
          {
            "name": "ip_address",
            "in": "query",
            "required": false,
            "description": "이벤트의 IP 주소에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "203.0.113.42"
          },
          {
            "name": "game_id",
            "in": "query",
            "required": false,
            "description": "승격된 `game_id`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "poker-holdem-01"
          },
          {
            "name": "round_id",
            "in": "query",
            "required": false,
            "description": "승격된 `round_id`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "round-88231"
          },
          {
            "name": "affiliate_code",
            "in": "query",
            "required": false,
            "description": "승격된 `affiliate_code`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "aff-summer"
          },
          {
            "name": "payment_reference_id",
            "in": "query",
            "required": false,
            "description": "결제 참조(`transaction_context.payment_reference_id` 또는 `payload.payment_reference_id`에서 가져옴)에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "dep_735"
          },
          {
            "name": "counterparty_vendor_data",
            "in": "query",
            "required": false,
            "description": "승격된 `counterparty_vendor_data`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "user-77"
          },
          {
            "name": "matched_only",
            "in": "query",
            "required": false,
            "description": "`true`(대소문자 구분 없이 `1` 또는 `yes`도 가능)는 하나 이상의 규칙과 일치한 이벤트(`rules_matched_count`가 0 초과)만 반환합니다. 그 외의 값은 무시됩니다.",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "example": true
          },
          {
            "name": "occurred_from",
            "in": "query",
            "required": false,
            "description": "`occurred_at`이 이 시점 이후(해당 시점 포함)인 이벤트만 해당합니다. ISO 8601 값을 전송하십시오: `2026-10-01T00:00:00Z`, `+`가 퍼센트 인코딩된 명시적 오프셋(`2026-10-01T02:00:00%2B02:00`. 인코딩되지 않은 `+`는 공백으로 디코딩되어 값이 더 이상 파싱되지 않음), 또는 해당 날짜의 00:00:00 UTC를 의미하는 날짜 단독 형식(`2026-10-01`). 오프셋이 없는 값은 UTC로 해석됩니다. 다른 형식의 값은 허용되지 않습니다.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-01T00:00:00Z"
          },
          {
            "name": "occurred_to",
            "in": "query",
            "required": false,
            "description": "`occurred_at`이 이 시점 이전(해당 시점 포함)인 이벤트만 해당합니다. 날짜만 전달하면 해당 날짜의 시작을 의미하므로 `occurred_to=2026-10-15`는 10월 15일의 나머지 시간을 제외합니다. 이를 포함하려면 `2026-10-15T23:59:59Z`를 전송하십시오. ISO 8601 값을 전송하십시오: `2026-10-01T00:00:00Z`, `+`가 퍼센트 인코딩된 명시적 오프셋(`2026-10-01T02:00:00%2B02:00`. 인코딩되지 않은 `+`는 공백으로 디코딩되어 값이 더 이상 파싱되지 않음), 또는 해당 날짜의 00:00:00 UTC를 의미하는 날짜 단독 형식(`2026-10-01`). 오프셋이 없는 값은 UTC로 해석됩니다. 다른 형식의 값은 허용되지 않습니다.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-17T23:59:59Z"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "`event_id`, `action_type`, `subject_vendor_data` 또는 `counterparty_vendor_data`에 대해 대소문자를 구분하지 않는 부분 문자열 일치 검색.",
            "schema": {
              "type": "string"
            },
            "example": "chargeback"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/events/?event_category=payment&event_category=dispute&matched_only=true&occurred_from=2026-10-01T00:00:00Z&limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.monitoring_events.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.monitoringEvents.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.MonitoringEvents.ListAutoPaging(ctx, didit.MonitoringEventsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.monitoringEvents().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->monitoringEvents->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.monitoring_events.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.MonitoringEvents.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "이벤트 요약 페이지 하나입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitoringEventPage"
                },
                "examples": {
                  "Payment and dispute events": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "event_uuid": "11111111-2222-3333-4444-555555555555",
                          "event_id": "chargeback-2026-10-16-000318",
                          "event_category": "dispute",
                          "action_type": "chargeback_opened",
                          "occurred_at": "2026-10-16T14:02:11Z",
                          "received_at": "2026-10-16T14:02:12.418230Z",
                          "status": "IN_REVIEW",
                          "score": 60,
                          "subject_vendor_data": "user-42",
                          "subject_entity_type": "individual",
                          "subject_uuid": "66666666-7777-8888-9999-000000000000",
                          "counterparty_vendor_data": null,
                          "session_id": null,
                          "device_fingerprint": null,
                          "ip_address": null,
                          "ip_country": null,
                          "amount": "250.000000000000000000",
                          "currency": "EUR",
                          "game_id": null,
                          "round_id": null,
                          "bonus_id": null,
                          "affiliate_code": null,
                          "payment_reference_id": "dep_735",
                          "retention_class": "monetary_or_compliance",
                          "rules_matched_count": 1,
                          "correlation_pending": false,
                          "is_droppable": false
                        },
                        {
                          "event_uuid": "22222222-3333-4444-5555-666666666666",
                          "event_id": "login-2026-10-15-000912",
                          "event_category": "auth",
                          "action_type": "login",
                          "occurred_at": "2026-10-15T08:30:00.120000Z",
                          "received_at": "2026-10-15T08:30:00.734512Z",
                          "status": "ACCEPTED",
                          "score": 0,
                          "subject_vendor_data": "user-42",
                          "subject_entity_type": "individual",
                          "subject_uuid": "66666666-7777-8888-9999-000000000000",
                          "counterparty_vendor_data": null,
                          "session_id": "web-session-abc",
                          "device_fingerprint": "fp-a8c1",
                          "ip_address": "203.0.113.42",
                          "ip_country": "ES",
                          "amount": null,
                          "currency": null,
                          "game_id": null,
                          "round_id": null,
                          "bonus_id": null,
                          "affiliate_code": null,
                          "payment_reference_id": null,
                          "retention_class": "standard",
                          "rules_matched_count": 0,
                          "correlation_pending": false,
                          "is_droppable": true
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`limit` 또는 `offset`이 1000000보다 큽니다. 본문은 메시지 1개가 포함된 JSON 배열입니다. 숫자가 아니거나 양수가 아닌 `limit`는 실패하는 대신 기본값 50으로 대체됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "limit too large": {
                    "summary": "limit이 1000000을 초과함",
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  },
                  "offset too large": {
                    "summary": "offset이 1000000을 초과함",
                    "value": [
                      "offset must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "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: read` 권한이 없는 범위 제한 키이거나, 특정 워크플로 또는 승인된 세션으로 제한된 키이거나(이러한 키는 거래 모니터링 데이터에 절대 접근할 수 없음), 키의 IP 허용 목록 외부에서 발생한 요청입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "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 read 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": "속도 제한 초과: `GET` 요청은 API 키당 분당 600개의 요청 한도를 공유합니다. `Retry-After`초 동안 대기한 후 재시도하세요.",
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "모니터링 이벤트 생성",
        "description": "백엔드에서 비금전적 이벤트(로그인, 세션, 게임플레이, 보너스, 제휴사, 결제, 분쟁, 보안, 책임감 있는 도박 또는 커스텀)를 전송합니다. 이벤트는 해당 카테고리 계약에 대해 유효성이 검사되고, 저장되며, 고유한 공용 주소당 한 번씩 IP 보강이 수행되고, 응답이 반환되기 전에 실시간 이벤트 규칙에 의해 평가됩니다. 주체 간 규칙 및 긴 윈도우 규칙은 비동기식으로 실행되며(`correlation_pending: true`), 샌드박스 애플리케이션에서는 규칙이 실행되지 않습니다. `event_id`는 멱등성 키입니다. 동일한 `event_category`, `action_type`, `occurred_at`, `subject.vendor_data`, `payload`를 가진 동일한 `event_id`는 `idempotent_replay: true` 및 저장된 결과와 함께 `200`을 반환하고(다른 엔벨로프 필드는 비교되지 않음), 다른 값은 `409`를 반환합니다. 이벤트 수집은 애플리케이션별로 활성화(opt-in)됩니다. 활성화될 때까지 이 endpoint는 `code: event_monitoring_disabled`와 함께 `403`을 반환하고 아무것도 저장하지 않습니다. 범위가 지정된 API 키에는 `transactions: write`가 필요합니다. [이벤트 수집](https://docs.didit.me/ko/transaction-monitoring/events) 및 [이벤트 규칙](https://docs.didit.me/ko/transaction-monitoring/event-rules)을 참조하십시오. 브라우저나 앱에서 이벤트를 전송하려면 [SDK 이벤트 제출](https://docs.didit.me/ko/transaction-monitoring/sdk-event-submission)을 사용하십시오.",
        "operationId": "create_monitoring_event",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "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"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/events/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"event_id\": \"login-2026-10-17-000001\",\n    \"event_category\": \"auth\",\n    \"action_type\": \"login\",\n    \"occurred_at\": \"2026-10-17T09:15:02.481Z\",\n    \"subject\": {\"vendor_data\": \"user-42\", \"entity_type\": \"individual\"},\n    \"session\": {\"session_id\": \"web-session-abc\", \"sequence\": 142},\n    \"device_context\": {\n      \"fingerprint\": \"fp-a8c1\",\n      \"network_context\": {\"ip_address\": \"203.0.113.42\"}\n    },\n    \"payload\": {\"method\": \"password\"}\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.create(\n    event_id=\"login-2026-10-17-000001\",\n    event_category=\"auth\",\n    action_type=\"login\",\n    occurred_at=\"2026-10-17T09:15:02.481Z\",\n    time_zone=\"Europe/Madrid\",\n    subject={\n        \"vendor_data\": \"user-42\",\n        \"entity_type\": \"individual\",\n    },\n    session={\n        \"session_id\": \"web-session-abc\",\n        \"sequence\": 142,\n    },\n    device_context={\n        \"fingerprint\": \"fp-a8c1\",\n        \"network_context\": {\n            \"ip_address\": \"203.0.113.42\",\n        },\n    },\n    payload={\"method\": \"password\"},\n    custom_values={\"vip_tier\": \"gold\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.create({\n  event_id: \"login-2026-10-17-000001\",\n  event_category: \"auth\",\n  action_type: \"login\",\n  occurred_at: \"2026-10-17T09:15:02.481Z\",\n  time_zone: \"Europe/Madrid\",\n  subject: {\n    vendor_data: \"user-42\",\n    entity_type: \"individual\",\n  },\n  session: {\n    session_id: \"web-session-abc\",\n    sequence: 142,\n  },\n  device_context: {\n    fingerprint: \"fp-a8c1\",\n    network_context: {\n      ip_address: \"203.0.113.42\",\n    },\n  },\n  payload: { method: \"password\" },\n  custom_values: { vip_tier: \"gold\" },\n});\nconsole.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;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.MonitoringEventCreateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().create(MonitoringEventCreateRequest.builder()\n        .eventId(\"login-2026-10-17-000001\")\n        .eventCategory(MonitoringEventCreateRequest.EventCategory.of(\"auth\"))\n        .actionType(\"login\")\n        .occurredAt(OffsetDateTime.parse(\"2026-10-17T09:15:02.481Z\"))\n        .timeZone(\"Europe/Madrid\")\n        .subject(MonitoringEventCreateRequest.Subject.builder()\n                .vendorData(\"user-42\")\n                .entityType(\"individual\")\n                .build())\n        .session(MonitoringEventCreateRequest.Session.builder()\n                .sessionId(\"web-session-abc\")\n                .sequence(142L)\n                .build())\n        .deviceContext(MonitoringEventCreateRequest.DeviceContext.builder()\n                .fingerprint(\"fp-a8c1\")\n                .networkContext(MonitoringEventCreateRequest.DeviceContext.NetworkContext.builder()\n                        .ipAddress(\"203.0.113.42\")\n                        .build())\n                .build())\n        .payload(Map.of(\"method\", \"password\"))\n        .customValues(Map.of(\"vip_tier\", MonitoringEventCreateRequest.CustomValuesValue.ofString(\"gold\")))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->monitoringEvents->create([\n    'event_id' => 'login-2026-10-17-000001',\n    'event_category' => 'auth',\n    'action_type' => 'login',\n    'occurred_at' => '2026-10-17T09:15:02.481Z',\n    'time_zone' => 'Europe/Madrid',\n    'subject' => [\n        'vendor_data' => 'user-42',\n        'entity_type' => 'individual',\n    ],\n    'session' => [\n        'session_id' => 'web-session-abc',\n        'sequence' => 142,\n    ],\n    'device_context' => [\n        'fingerprint' => 'fp-a8c1',\n        'network_context' => [\n            'ip_address' => '203.0.113.42',\n        ],\n    ],\n    'payload' => ['method' => 'password'],\n    'custom_values' => ['vip_tier' => 'gold'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.create(\n  event_id: \"login-2026-10-17-000001\",\n  event_category: \"auth\",\n  action_type: \"login\",\n  occurred_at: \"2026-10-17T09:15:02.481Z\",\n  time_zone: \"Europe/Madrid\",\n  subject: {\n    vendor_data: \"user-42\",\n    entity_type: \"individual\",\n  },\n  session: {\n    session_id: \"web-session-abc\",\n    sequence: 142,\n  },\n  device_context: {\n    fingerprint: \"fp-a8c1\",\n    network_context: {\n      ip_address: \"203.0.113.42\",\n    },\n  },\n  payload: { method: \"password\" },\n  custom_values: { vip_tier: \"gold\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.CreateAsync(new MonitoringEventCreateRequest\n{\n    EventId = \"login-2026-10-17-000001\",\n    EventCategory = \"auth\",\n    ActionType = \"login\",\n    OccurredAt = DateTimeOffset.Parse(\"2026-10-17T09:15:02.481Z\"),\n    TimeZone = \"Europe/Madrid\",\n    Subject = new()\n    {\n        VendorData = \"user-42\",\n        EntityType = \"individual\",\n    },\n    Session = new MonitoringEventCreateRequestSession\n    {\n        SessionId = \"web-session-abc\",\n        Sequence = 142,\n    },\n    DeviceContext = new MonitoringEventCreateRequestDeviceContext\n    {\n        Fingerprint = \"fp-a8c1\",\n        NetworkContext = new MonitoringEventCreateRequestDeviceContextNetworkContext\n        {\n            IpAddress = \"203.0.113.42\",\n        },\n    },\n    Payload = new Dictionary<string, object> { [\"method\"] = \"password\" },\n    CustomValues = new Dictionary<string, object> { [\"vip_tier\"] = \"gold\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "이벤트가 저장되고 평가되었습니다.",
            "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
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "200": {
            "description": "멱등 재생: 이 `event_id` 및 동일한 내용을 가진 이벤트가 이미 저장되어 있습니다. 아무것도 다시 저장되거나 평가되지 않았으며 본문은 저장된 이벤트를 설명합니다.",
            "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": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "검증 실패. 본문은 필드별 키로 구성되며, 중첩된 필드는 중첩 객체입니다. 아무것도 저장되지 않습니다.",
            "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": "스코프가 지정된 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."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`event_id`가 다른 콘텐츠(카테고리, 작업 유형, `occurred_at`, 대상 `vendor_data` 또는 payload)를 가진 이벤트에 이미 사용되었습니다. 새 `event_id`로 이벤트를 전송하십시오.",
            "content": {
              "application/json": {
                "examples": {
                  "event_id reused": {
                    "value": {
                      "event_id": "event_id 'login-2026-10-17-000001' already exists with a different payload."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: 거래 생성 및 이벤트 수집(`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": []
          }
        ]
      }
    },
    "/v3/events/batch/": {
      "post": {
        "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",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "create_batch",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "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"
                    }
                  }
                ]
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/events/batch/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"events\": [\n      {\"event_id\": \"login-2026-10-17-000001\", \"event_category\": \"auth\", \"action_type\": \"login\",\n       \"occurred_at\": \"2026-10-17T09:15:02.481Z\", \"subject\": {\"vendor_data\": \"user-42\"}},\n      {\"event_id\": \"deposit-2026-10-17-000002\", \"event_category\": \"payment\", \"action_type\": \"deposit_completed\",\n       \"occurred_at\": \"2026-10-17T09:16:40.000Z\", \"subject\": {\"vendor_data\": \"user-42\"},\n       \"transaction_context\": {\"amount\": \"100.00\", \"currency\": \"EUR\", \"payment_reference_id\": \"dep_736\"},\n       \"payload\": {\"payment_method\": \"card\", \"status\": \"completed\"}}\n    ]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.create_batch(\n    events=[{\n        \"event_id\": \"login-2026-10-17-000001\",\n        \"event_category\": \"auth\",\n        \"action_type\": \"login\",\n        \"occurred_at\": \"2026-10-17T09:15:02.481Z\",\n        \"subject\": {\n            \"vendor_data\": \"user-42\",\n        },\n    }, {\n        \"event_id\": \"deposit-2026-10-17-000002\",\n        \"event_category\": \"payment\",\n        \"action_type\": \"deposit_completed\",\n        \"occurred_at\": \"2026-10-17T09:16:40Z\",\n        \"subject\": {\n            \"vendor_data\": \"user-42\",\n        },\n        \"transaction_context\": {\n            \"amount\": \"100.00\",\n            \"currency\": \"EUR\",\n            \"payment_reference_id\": \"dep_736\",\n        },\n        \"payload\": {\"payment_method\": \"card\", \"status\": \"completed\"},\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.createBatch({\n  events: [{\n    event_id: \"login-2026-10-17-000001\",\n    event_category: \"auth\",\n    action_type: \"login\",\n    occurred_at: \"2026-10-17T09:15:02.481Z\",\n    subject: {\n      vendor_data: \"user-42\",\n    },\n  }, {\n    event_id: \"deposit-2026-10-17-000002\",\n    event_category: \"payment\",\n    action_type: \"deposit_completed\",\n    occurred_at: \"2026-10-17T09:16:40Z\",\n    subject: {\n      vendor_data: \"user-42\",\n    },\n    transaction_context: {\n      amount: \"100.00\",\n      currency: \"EUR\",\n      payment_reference_id: \"dep_736\",\n    },\n    payload: { payment_method: \"card\", status: \"completed\" },\n  }],\n});\nconsole.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;\nimport java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.MonitoringEventCreateRequest;\nimport me.didit.types.MonitoringEventsCreateBatchParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().createBatch(MonitoringEventsCreateBatchParams.builder()\n        .events(List.of(\n                MonitoringEventCreateRequest.builder()\n                        .eventId(\"login-2026-10-17-000001\")\n                        .eventCategory(MonitoringEventCreateRequest.EventCategory.of(\"auth\"))\n                        .actionType(\"login\")\n                        .occurredAt(OffsetDateTime.parse(\"2026-10-17T09:15:02.481Z\"))\n                        .subject(MonitoringEventCreateRequest.Subject.builder()\n                                .vendorData(\"user-42\")\n                                .build())\n                        .build(),\n                MonitoringEventCreateRequest.builder()\n                        .eventId(\"deposit-2026-10-17-000002\")\n                        .eventCategory(MonitoringEventCreateRequest.EventCategory.of(\"payment\"))\n                        .actionType(\"deposit_completed\")\n                        .occurredAt(OffsetDateTime.parse(\"2026-10-17T09:16:40Z\"))\n                        .subject(MonitoringEventCreateRequest.Subject.builder()\n                                .vendorData(\"user-42\")\n                                .build())\n                        .transactionContext(MonitoringEventCreateRequest.TransactionContext.builder()\n                                .amount(\"100.00\")\n                                .currency(\"EUR\")\n                                .paymentReferenceId(\"dep_736\")\n                                .build())\n                        .payload(Map.of(\"payment_method\", \"card\", \"status\", \"completed\"))\n                        .build()))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->monitoringEvents->createBatch([\n    'events' => [[\n        'event_id' => 'login-2026-10-17-000001',\n        'event_category' => 'auth',\n        'action_type' => 'login',\n        'occurred_at' => '2026-10-17T09:15:02.481Z',\n        'subject' => [\n            'vendor_data' => 'user-42',\n        ],\n    ], [\n        'event_id' => 'deposit-2026-10-17-000002',\n        'event_category' => 'payment',\n        'action_type' => 'deposit_completed',\n        'occurred_at' => '2026-10-17T09:16:40Z',\n        'subject' => [\n            'vendor_data' => 'user-42',\n        ],\n        'transaction_context' => [\n            'amount' => '100.00',\n            'currency' => 'EUR',\n            'payment_reference_id' => 'dep_736',\n        ],\n        'payload' => ['payment_method' => 'card', 'status' => 'completed'],\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.create_batch(\n  events: [{\n    event_id: \"login-2026-10-17-000001\",\n    event_category: \"auth\",\n    action_type: \"login\",\n    occurred_at: \"2026-10-17T09:15:02.481Z\",\n    subject: {\n      vendor_data: \"user-42\",\n    },\n  }, {\n    event_id: \"deposit-2026-10-17-000002\",\n    event_category: \"payment\",\n    action_type: \"deposit_completed\",\n    occurred_at: \"2026-10-17T09:16:40Z\",\n    subject: {\n      vendor_data: \"user-42\",\n    },\n    transaction_context: {\n      amount: \"100.00\",\n      currency: \"EUR\",\n      payment_reference_id: \"dep_736\",\n    },\n    payload: { payment_method: \"card\", status: \"completed\" },\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.CreateBatchAsync(new MonitoringEventsCreateBatchParams\n{\n    Events = new MonitoringEventCreateRequest[]\n    {\n        new()\n        {\n            EventId = \"login-2026-10-17-000001\",\n            EventCategory = \"auth\",\n            ActionType = \"login\",\n            OccurredAt = DateTimeOffset.Parse(\"2026-10-17T09:15:02.481Z\"),\n            Subject = new()\n            {\n                VendorData = \"user-42\",\n            },\n        },\n        new()\n        {\n            EventId = \"deposit-2026-10-17-000002\",\n            EventCategory = \"payment\",\n            ActionType = \"deposit_completed\",\n            OccurredAt = DateTimeOffset.Parse(\"2026-10-17T09:16:40Z\"),\n            Subject = new()\n            {\n                VendorData = \"user-42\",\n            },\n            TransactionContext = new MonitoringEventCreateRequestTransactionContext\n            {\n                Amount = \"100.00\",\n                Currency = \"EUR\",\n                PaymentReferenceId = \"dep_736\",\n            },\n            Payload = new Dictionary<string, object> { [\"payment_method\"] = \"card\", [\"status\"] = \"completed\" },\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "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": []
          }
        ]
      }
    },
    "/v3/events/sdk-token/": {
      "post": {
        "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",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "create_sdk_token",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "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"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/events/sdk-token/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"vendor_data\": \"user-42\",\n    \"allowed_event_categories\": [\"auth\", \"session\", \"gameplay\"],\n    \"ttl_seconds\": 900,\n    \"max_uses\": 1000,\n    \"bind_to_origin\": \"https://app.example.com\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.create_sdk_token(\n    vendor_data=\"user-42\",\n    allowed_event_categories=[\"auth\", \"session\", \"gameplay\"],\n    ttl_seconds=900,\n    max_uses=1000,\n    bind_to_origin=\"https://app.example.com\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.createSdkToken({\n  vendor_data: \"user-42\",\n  allowed_event_categories: [\"auth\", \"session\", \"gameplay\"],\n  ttl_seconds: 900,\n  max_uses: 1000,\n  bind_to_origin: \"https://app.example.com\",\n});\nconsole.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;\nimport me.didit.Didit;\nimport me.didit.types.MonitoringEventsCreateSdkTokenParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().createSdkToken(MonitoringEventsCreateSdkTokenParams.builder()\n        .vendorData(\"user-42\")\n        .allowedEventCategories(List.of(MonitoringEventsCreateSdkTokenParams.AllowedEventCategories.of(\"auth\"), MonitoringEventsCreateSdkTokenParams.AllowedEventCategories.of(\"session\"), MonitoringEventsCreateSdkTokenParams.AllowedEventCategories.of(\"gameplay\")))\n        .ttlSeconds(900L)\n        .maxUses(1000L)\n        .bindToOrigin(\"https://app.example.com\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->monitoringEvents->createSdkToken([\n    'vendor_data' => 'user-42',\n    'allowed_event_categories' => ['auth', 'session', 'gameplay'],\n    'ttl_seconds' => 900,\n    'max_uses' => 1000,\n    'bind_to_origin' => 'https://app.example.com',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.create_sdk_token(\n  vendor_data: \"user-42\",\n  allowed_event_categories: [\"auth\", \"session\", \"gameplay\"],\n  ttl_seconds: 900,\n  max_uses: 1000,\n  bind_to_origin: \"https://app.example.com\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.CreateSdkTokenAsync(new MonitoringEventsCreateSdkTokenParams\n{\n    VendorData = \"user-42\",\n    AllowedEventCategories = new MonitoringEventsCreateSdkTokenParamsAllowedEventCategories[] { \"auth\", \"session\", \"gameplay\" },\n    TtlSeconds = 900,\n    MaxUses = 1000,\n    BindToOrigin = \"https://app.example.com\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "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": []
          }
        ]
      }
    },
    "/v3/events/{event_uuid}/": {
      "get": {
        "summary": "모니터링 이벤트 조회",
        "description": "목록이 반환하는 모든 정보와 함께 payload, 커스텀 값, 기기 컨텍스트, 필드 출처(`field_sources`), 승격된 도메인 필드, `expires_at`, 증거가 포함된 일치하는 모든 규칙 실행 내역, IP 보강 정보 및 규칙이 첨부한 태그를 포함하여 단일 모니터링 이벤트를 조회합니다. `correlation_pending`이 `true`인 동안에는 비동기 규칙이 계속 실행되어야 합니다. 최종 `status`, `score` 및 `rule_runs`를 확인하려면 몇 분 후에 이벤트를 다시 읽으십시오. 이벤트 수집 활성화 여부와 관계없이 조회가 작동합니다. 범위가 지정된 API 키에는 `transactions: read` 권한이 필요합니다. [Evidence](https://docs.didit.me/ko/transaction-monitoring/event-rules#증거) 및 [IP 보강](https://docs.didit.me/ko/transaction-monitoring/ip-enrichment)을 참조하십시오.",
        "operationId": "get_monitoring_event",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "parameters": [
          {
            "name": "event_uuid",
            "in": "path",
            "required": true,
            "description": "자체 `event_id`가 아닌 이벤트의 Didit 식별자(생성, 일괄 처리, 목록 또는 타임라인 응답의 `event_uuid`)입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/events/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->monitoringEvents->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "증거가 포함된 이벤트입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitoringEventDetail"
                },
                "examples": {
                  "Login from a VPN, in review": {
                    "value": {
                      "event_uuid": "33333333-4444-5555-6666-777777777777",
                      "event_id": "login-2026-10-17-000001",
                      "event_category": "auth",
                      "action_type": "login",
                      "occurred_at": "2026-10-17T09:15:02.481000Z",
                      "received_at": "2026-10-17T09:15:02.903114Z",
                      "status": "IN_REVIEW",
                      "score": 40,
                      "subject_vendor_data": "user-42",
                      "subject_entity_type": "individual",
                      "subject_uuid": "66666666-7777-8888-9999-000000000000",
                      "counterparty_vendor_data": null,
                      "session_id": "web-session-abc",
                      "device_fingerprint": "fp-a8c1",
                      "ip_address": "203.0.113.42",
                      "ip_country": "ES",
                      "amount": null,
                      "currency": null,
                      "game_id": null,
                      "round_id": null,
                      "bonus_id": null,
                      "affiliate_code": null,
                      "payment_reference_id": null,
                      "retention_class": "risk_relevant",
                      "rules_matched_count": 1,
                      "correlation_pending": false,
                      "is_droppable": true,
                      "payload": {
                        "method": "password"
                      },
                      "custom_values": {
                        "vip_tier": "gold",
                        "vpn_or_proxy_detected": true
                      },
                      "device_context": {
                        "fingerprint": "fp-a8c1",
                        "network_context": {
                          "ip_address": "203.0.113.42",
                          "ip_country": "Spain",
                          "ip_country_code": "ES",
                          "ip_city": "Madrid",
                          "asn_number": 64500,
                          "asn_organization": "Example Networks",
                          "is_vpn_or_tor": true,
                          "is_data_center": false
                        }
                      },
                      "field_sources": {
                        "subject.vendor_data": "customer",
                        "event_category": "customer",
                        "action_type": "customer",
                        "occurred_at": "customer",
                        "received_at": "server",
                        "payload.method": "customer",
                        "session.session_id": "customer",
                        "session.sequence": "customer",
                        "device_context.fingerprint": "customer",
                        "device_context.network_context.ip_address": "customer",
                        "device_context.network_context.ip_country": "server",
                        "device_context.network_context.ip_country_code": "server",
                        "device_context.network_context.ip_city": "server",
                        "device_context.network_context.asn_number": "server",
                        "device_context.network_context.asn_organization": "server",
                        "device_context.network_context.is_vpn_or_tor": "server",
                        "device_context.network_context.is_data_center": "server"
                      },
                      "session_sequence": 142,
                      "table_id": null,
                      "hand_id": null,
                      "match_id": null,
                      "market_id": null,
                      "side": null,
                      "role": null,
                      "net_result_amount": null,
                      "payment_fingerprint": null,
                      "instrument_reference_hash": null,
                      "withdrawal_address_hash": null,
                      "dispute_id": null,
                      "chargeback_id": null,
                      "changed_field": null,
                      "identity_match_ref": null,
                      "schema_version": 1,
                      "expires_at": "2027-01-15T09:15:02.481000Z",
                      "rules_evaluated_count": 6,
                      "rule_runs": [
                        {
                          "rule_uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                          "rule_title": "Login from VPN or Tor",
                          "library_key": null,
                          "matched": true,
                          "mode": "ACTIVE",
                          "is_async": false,
                          "severity": "MEDIUM",
                          "score_delta": 40,
                          "action_summary": "score +40; add_tag:VPN_LOGIN",
                          "matched_payload": [
                            {
                              "field": "event.ip.is_vpn_or_tor",
                              "operator": "eq",
                              "expected_value": true,
                              "current_value": true,
                              "matched": true,
                              "group_index": null,
                              "group_logic": "AND",
                              "field_source": "server"
                            }
                          ],
                          "created_at": "2026-10-17T09:15:02.951207Z"
                        }
                      ],
                      "ip_enrichment": {
                        "ip_country_code": "ES",
                        "ip_city": "Madrid",
                        "asn_number": 64500,
                        "asn_organization": "Example Networks",
                        "is_vpn_or_tor": true,
                        "is_data_center": false,
                        "proxy_type": null,
                        "last_enriched_at": "2026-10-17T09:15:02.910442Z"
                      },
                      "subject_profile": null,
                      "tags": [
                        "VPN_LOGIN"
                      ]
                    }
                  }
                }
              }
            }
          },
          "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: read` 권한이 없는 범위 제한 키이거나, 특정 워크플로 또는 승인된 세션으로 제한된 키이거나(이러한 키는 거래 모니터링 데이터에 절대 접근할 수 없음), 키의 IP 허용 목록 외부에서 발생한 요청입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "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 read 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."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 이 `event_uuid`를 가진 이벤트가 존재하지 않습니다. 저장된 적이 없거나, 삭제되었거나, 다른 애플리케이션에 속해 있습니다. UUID가 아닌 경로 세그먼트는 라우트와 일치하지 않아 마찬가지로 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No MonitoringEvent matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: `GET` 요청은 API 키당 분당 600개의 요청 한도를 공유합니다. `Retry-After`초 동안 대기한 후 재시도하세요.",
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/events/subjects/{vendor_data}/": {
      "get": {
        "summary": "대상 이벤트 타임라인 가져오기",
        "description": "단일 대상의 모든 모니터링 이벤트를 `occurred_at` 기준 최신순으로 조회합니다. `vendor_data`는 엔티티 유형 내에서만 고유하므로 동일한 ID가 개인과 기업을 모두 지정할 수 있습니다. `entity_type`으로 가져올 타임라인을 선택하며 기본값은 `individual`이므로 기업의 이벤트를 조회하려면 `entity_type=company`가 필요합니다. `GET /v3/events/`의 필터가 추가로 적용되며, 이벤트가 없는 `vendor_data`는 `404` 대신 빈 페이지를 반환합니다. 스코프가 지정된 API 키에는 `transactions: read` 권한이 필요합니다. [이벤트 다시 조회하기](https://docs.didit.me/ko/transaction-monitoring/events#이벤트-조회)를 참고하십시오.",
        "operationId": "get_monitoring_event_subject_timeline",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "retrieve_subject_timeline",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "description": "대상에 대한 귀하의 id입니다(해당 이벤트의 `subject.vendor_data`). URL 인코딩해야 합니다. `/`가 포함된 값은 이 endpoint에서 처리할 수 없습니다.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "user-42"
          },
          {
            "name": "entity_type",
            "in": "query",
            "required": false,
            "description": "`company`는 해당 `vendor_data`를 가진 기업을 반환하며, 그 외의 값이나 비어 있는 경우에는 개인을 반환합니다. `entity_type`이 없는 경우 `subject_entity_type`을 별칭으로 사용할 수 있습니다.",
            "schema": {
              "type": "string",
              "enum": [
                "individual",
                "company"
              ],
              "default": "individual"
            },
            "example": "individual"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "페이지당 최대 이벤트 수입니다. 기본값은 50입니다. 1000000을 초과하는 값은 `400`을 반환하며, 숫자가 아니거나 0 또는 음수인 값은 50으로 대체됩니다.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "example": 50
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "건너뛸 이벤트 수입니다. 기본값은 0입니다. 응답의 `next` URL을 따르는 것을 권장합니다.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "example": 0
          },
          {
            "name": "event_category",
            "in": "query",
            "required": false,
            "description": "이 카테고리에 속하는 이벤트만 해당합니다. 여러 값을 지정하려면 파라미터를 반복하십시오(`?event_category=payment&event_category=dispute`). 이 중 하나라도 일치하는 이벤트가 반환됩니다.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "auth",
                  "session",
                  "gameplay",
                  "bonus",
                  "affiliate",
                  "payment",
                  "dispute",
                  "security",
                  "responsible_gambling",
                  "custom"
                ]
              }
            },
            "example": [
              "payment",
              "dispute"
            ]
          },
          {
            "name": "action_type",
            "in": "query",
            "required": false,
            "description": "이러한 작업 유형(정확히 일치, 대소문자 구분)의 이벤트만 해당합니다. 여러 값에 대해 반복하십시오.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "example": [
              "deposit_completed",
              "chargeback_opened"
            ]
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "이러한 상태의 이벤트만 해당합니다. 여러 값에 대해 반복하십시오.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "ACCEPTED",
                  "APPROVED",
                  "IN_REVIEW",
                  "DECLINED"
                ]
              }
            },
            "example": [
              "IN_REVIEW",
              "DECLINED"
            ]
          },
          {
            "name": "retention_class",
            "in": "query",
            "required": false,
            "description": "이 보존 등급에 속하는 이벤트만 해당합니다. 여러 값에 대해 반복하십시오.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "low_value",
                  "standard",
                  "risk_relevant",
                  "monetary_or_compliance"
                ]
              }
            },
            "example": [
              "risk_relevant"
            ]
          },
          {
            "name": "business_vendor_data",
            "in": "query",
            "required": false,
            "description": "이벤트와 함께 전송된 `business.vendor_data`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "merchant-7"
          },
          {
            "name": "session_id",
            "in": "query",
            "required": false,
            "description": "`session.session_id`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "web-session-abc"
          },
          {
            "name": "device_fingerprint",
            "in": "query",
            "required": false,
            "description": "`device_context.fingerprint`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "fp-a8c1"
          },
          {
            "name": "ip_address",
            "in": "query",
            "required": false,
            "description": "이벤트의 IP 주소에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "203.0.113.42"
          },
          {
            "name": "game_id",
            "in": "query",
            "required": false,
            "description": "승격된 `game_id`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "poker-holdem-01"
          },
          {
            "name": "round_id",
            "in": "query",
            "required": false,
            "description": "승격된 `round_id`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "round-88231"
          },
          {
            "name": "affiliate_code",
            "in": "query",
            "required": false,
            "description": "승격된 `affiliate_code`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "aff-summer"
          },
          {
            "name": "payment_reference_id",
            "in": "query",
            "required": false,
            "description": "결제 참조(`transaction_context.payment_reference_id` 또는 `payload.payment_reference_id`에서 가져옴)에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "dep_735"
          },
          {
            "name": "counterparty_vendor_data",
            "in": "query",
            "required": false,
            "description": "승격된 `counterparty_vendor_data`에 대한 정확한 일치입니다.",
            "schema": {
              "type": "string"
            },
            "example": "user-77"
          },
          {
            "name": "matched_only",
            "in": "query",
            "required": false,
            "description": "`true`(대소문자 구분 없이 `1` 또는 `yes`도 가능)는 하나 이상의 규칙과 일치한 이벤트(`rules_matched_count`가 0 초과)만 반환합니다. 그 외의 값은 무시됩니다.",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "example": true
          },
          {
            "name": "occurred_from",
            "in": "query",
            "required": false,
            "description": "`occurred_at`이 이 시점 이후(해당 시점 포함)인 이벤트만 해당합니다. ISO 8601 값을 전송하십시오: `2026-10-01T00:00:00Z`, `+`가 퍼센트 인코딩된 명시적 오프셋(`2026-10-01T02:00:00%2B02:00`. 인코딩되지 않은 `+`는 공백으로 디코딩되어 값이 더 이상 파싱되지 않음), 또는 해당 날짜의 00:00:00 UTC를 의미하는 날짜 단독 형식(`2026-10-01`). 오프셋이 없는 값은 UTC로 해석됩니다. 다른 형식의 값은 허용되지 않습니다.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-01T00:00:00Z"
          },
          {
            "name": "occurred_to",
            "in": "query",
            "required": false,
            "description": "`occurred_at`이 이 시점 이전(해당 시점 포함)인 이벤트만 해당합니다. 날짜만 전달하면 해당 날짜의 시작을 의미하므로 `occurred_to=2026-10-15`는 10월 15일의 나머지 시간을 제외합니다. 이를 포함하려면 `2026-10-15T23:59:59Z`를 전송하십시오. ISO 8601 값을 전송하십시오: `2026-10-01T00:00:00Z`, `+`가 퍼센트 인코딩된 명시적 오프셋(`2026-10-01T02:00:00%2B02:00`. 인코딩되지 않은 `+`는 공백으로 디코딩되어 값이 더 이상 파싱되지 않음), 또는 해당 날짜의 00:00:00 UTC를 의미하는 날짜 단독 형식(`2026-10-01`). 오프셋이 없는 값은 UTC로 해석됩니다. 다른 형식의 값은 허용되지 않습니다.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-17T23:59:59Z"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "`event_id`, `action_type`, `subject_vendor_data` 또는 `counterparty_vendor_data`에 대해 대소문자를 구분하지 않는 부분 문자열 일치 검색.",
            "schema": {
              "type": "string"
            },
            "example": "chargeback"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/events/subjects/user-42/?entity_type=individual&limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.monitoring_events.retrieve_subject_timeline(\n    \"user-42\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.monitoringEvents.retrieveSubjectTimeline(\"user-42\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.MonitoringEvents.RetrieveSubjectTimelineAutoPaging(ctx, \"user-42\", didit.MonitoringEventsRetrieveSubjectTimelineParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.monitoringEvents().retrieveSubjectTimeline(\"user-42\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->monitoringEvents->retrieveSubjectTimeline('user-42') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.monitoring_events.retrieve_subject_timeline(\"user-42\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.MonitoringEvents.RetrieveSubjectTimelineAsync(\"user-42\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "대상자의 이벤트 페이지 하나입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitoringEventPage"
                },
                "examples": {
                  "Individual timeline": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "event_uuid": "11111111-2222-3333-4444-555555555555",
                          "event_id": "chargeback-2026-10-16-000318",
                          "event_category": "dispute",
                          "action_type": "chargeback_opened",
                          "occurred_at": "2026-10-16T14:02:11Z",
                          "received_at": "2026-10-16T14:02:12.418230Z",
                          "status": "IN_REVIEW",
                          "score": 60,
                          "subject_vendor_data": "user-42",
                          "subject_entity_type": "individual",
                          "subject_uuid": "66666666-7777-8888-9999-000000000000",
                          "counterparty_vendor_data": null,
                          "session_id": null,
                          "device_fingerprint": null,
                          "ip_address": null,
                          "ip_country": null,
                          "amount": "250.000000000000000000",
                          "currency": "EUR",
                          "game_id": null,
                          "round_id": null,
                          "bonus_id": null,
                          "affiliate_code": null,
                          "payment_reference_id": "dep_735",
                          "retention_class": "monetary_or_compliance",
                          "rules_matched_count": 1,
                          "correlation_pending": false,
                          "is_droppable": false
                        },
                        {
                          "event_uuid": "22222222-3333-4444-5555-666666666666",
                          "event_id": "login-2026-10-15-000912",
                          "event_category": "auth",
                          "action_type": "login",
                          "occurred_at": "2026-10-15T08:30:00.120000Z",
                          "received_at": "2026-10-15T08:30:00.734512Z",
                          "status": "ACCEPTED",
                          "score": 0,
                          "subject_vendor_data": "user-42",
                          "subject_entity_type": "individual",
                          "subject_uuid": "66666666-7777-8888-9999-000000000000",
                          "counterparty_vendor_data": null,
                          "session_id": "web-session-abc",
                          "device_fingerprint": "fp-a8c1",
                          "ip_address": "203.0.113.42",
                          "ip_country": "ES",
                          "amount": null,
                          "currency": null,
                          "game_id": null,
                          "round_id": null,
                          "bonus_id": null,
                          "affiliate_code": null,
                          "payment_reference_id": null,
                          "retention_class": "standard",
                          "rules_matched_count": 0,
                          "correlation_pending": false,
                          "is_droppable": true
                        }
                      ]
                    }
                  },
                  "No events": {
                    "value": {
                      "count": 0,
                      "next": null,
                      "previous": null,
                      "results": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`limit` 또는 `offset`이 1000000보다 큽니다. 본문은 메시지 1개가 포함된 JSON 배열입니다. 숫자가 아니거나 양수가 아닌 `limit`는 실패하는 대신 기본값 50으로 대체됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "limit too large": {
                    "summary": "limit이 1000000을 초과함",
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  },
                  "offset too large": {
                    "summary": "offset이 1000000을 초과함",
                    "value": [
                      "offset must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "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: read` 권한이 없는 범위 제한 키이거나, 특정 워크플로 또는 승인된 세션으로 제한된 키이거나(이러한 키는 거래 모니터링 데이터에 절대 접근할 수 없음), 키의 IP 허용 목록 외부에서 발생한 요청입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "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 read 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": "속도 제한 초과: `GET` 요청은 API 키당 분당 600개의 요청 한도를 공유합니다. `Retry-After`초 동안 대기한 후 재시도하세요.",
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/events/enrichment-metrics/": {
      "get": {
        "summary": "이벤트 강화 메트릭 조회",
        "description": "지정된 기간 동안 애플리케이션의 이벤트 수집 및 IP 강화 카운터를 모든 레인(서버, 배치 및 기기)에 걸쳐 합산하여 반환하므로, 이벤트 양을 모니터링하고 강화가 이벤트당 한 번이 아닌 고유 주소당 한 번 처리되는지 확인할 수 있습니다. 기간은 오늘과 이전 `days` 일을 포함하며, UTC 달력 날짜 기준으로 계산됩니다. 분모가 0일 경우 세 가지 비율은 null입니다. 범위가 지정된 API 키에는 `transactions: read`가 필요합니다. [IP 강화](https://docs.didit.me/ko/transaction-monitoring/events#ip-보강)를 참고하십시오.",
        "operationId": "get_monitoring_event_enrichment_metrics",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "retrieve_enrichment_metrics",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "기간(일 단위)입니다. 기본값은 30이며, 값은 1에서 365 사이로 제한되고, 정수가 아닌 값은 30으로 대체됩니다. 적용된 값은 `period_days`로 반환됩니다.",
            "schema": {
              "type": "integer",
              "default": 30,
              "minimum": 1,
              "maximum": 365
            },
            "example": 30
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/events/enrichment-metrics/?days=30' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.retrieve_enrichment_metrics()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.retrieveEnrichmentMetrics();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.RetrieveEnrichmentMetrics(ctx, didit.MonitoringEventsRetrieveEnrichmentMetricsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().retrieveEnrichmentMetrics();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->monitoringEvents->retrieveEnrichmentMetrics();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.retrieve_enrichment_metrics\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.RetrieveEnrichmentMetricsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "해당 기간의 카운터 및 비율입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "events_ingested",
                    "events_rejected",
                    "enrichment_lookups",
                    "enrichment_cache_hits",
                    "enrichment_provider_calls",
                    "enrichment_skipped_low_value",
                    "unique_ips_seen",
                    "period_days",
                    "cache_hit_rate",
                    "unique_ip_ratio",
                    "provider_calls_per_1k_events"
                  ],
                  "properties": {
                    "events_ingested": {
                      "type": "integer",
                      "description": "새 이벤트가 저장되었습니다. 멱등성 재전송은 계산되지 않습니다."
                    },
                    "events_rejected": {
                      "type": "integer",
                      "description": "배치 요청(서버 및 디바이스 레인) 내에서 거부된 항목 수입니다. 거부된 단일 이벤트 요청은 포함되지 않습니다."
                    },
                    "enrichment_lookups": {
                      "type": "integer",
                      "description": "캐시 또는 새로 확인하여 공인 IP 주소가 확인된 이벤트입니다."
                    },
                    "enrichment_cache_hits": {
                      "type": "integer",
                      "description": "캐시에서 응답된 조회 수."
                    },
                    "enrichment_provider_calls": {
                      "type": "integer",
                      "description": "주소를 새로 확인해야 했던 조회 수."
                    },
                    "enrichment_skipped_low_value": {
                      "type": "integer",
                      "description": "주소가 아직 알려지지 않은 낮은 가치의 텔레메트리 이벤트입니다. 자체적으로 주소를 새로 확인하지 않습니다."
                    },
                    "unique_ips_seen": {
                      "type": "integer",
                      "description": "새로운 주소 확인이 필요했던 주소입니다."
                    },
                    "period_days": {
                      "type": "integer",
                      "description": "클램핑 후 적용된 `days` 값입니다."
                    },
                    "cache_hit_rate": {
                      "type": "number",
                      "nullable": true,
                      "description": "`enrichment_cache_hits / enrichment_lookups`, 소수점 넷째 자리까지 반올림. 조회가 없었던 경우 null."
                    },
                    "unique_ip_ratio": {
                      "type": "number",
                      "nullable": true,
                      "description": "`unique_ips_seen / events_ingested` 값으로 소수점 4자리까지 반올림됩니다. 수집된 이벤트가 없으면 Null입니다."
                    },
                    "provider_calls_per_1k_events": {
                      "type": "number",
                      "nullable": true,
                      "description": "수집된 이벤트 1,000건당 신규 해결 건수이며, 소수점 둘째 자리에서 반올림됩니다. 수집된 이벤트가 없는 경우 null입니다."
                    }
                  }
                },
                "examples": {
                  "Last 30 days": {
                    "value": {
                      "events_ingested": 128450,
                      "events_rejected": 214,
                      "enrichment_lookups": 41230,
                      "enrichment_cache_hits": 40118,
                      "enrichment_provider_calls": 1112,
                      "enrichment_skipped_low_value": 74320,
                      "unique_ips_seen": 1112,
                      "period_days": 30,
                      "cache_hit_rate": 0.973,
                      "unique_ip_ratio": 0.0087,
                      "provider_calls_per_1k_events": 8.66
                    }
                  },
                  "No events yet": {
                    "value": {
                      "events_ingested": 0,
                      "events_rejected": 0,
                      "enrichment_lookups": 0,
                      "enrichment_cache_hits": 0,
                      "enrichment_provider_calls": 0,
                      "enrichment_skipped_low_value": 0,
                      "unique_ips_seen": 0,
                      "period_days": 30,
                      "cache_hit_rate": null,
                      "unique_ip_ratio": null,
                      "provider_calls_per_1k_events": null
                    }
                  }
                }
              }
            }
          },
          "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: read` 권한이 없는 범위 제한 키이거나, 특정 워크플로 또는 승인된 세션으로 제한된 키이거나(이러한 키는 거래 모니터링 데이터에 절대 접근할 수 없음), 키의 IP 허용 목록 외부에서 발생한 요청입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "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 read 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": "속도 제한 초과: `GET` 요청은 API 키당 분당 600개의 요청 한도를 공유합니다. `Retry-After`초 동안 대기한 후 재시도하세요.",
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/events/{event_uuid}/delete/": {
      "delete": {
        "summary": "모니터링 이벤트 삭제",
        "description": "실수로 전송된 이벤트 등 모니터링 이벤트 하나를 해당 규칙 실행 기록, 메모, 태그 링크와 함께 영구적으로 삭제합니다. `204` 응답 후에는 모든 조회에서 해당 이벤트가 사라지며(조회 시 `404` 반환, 목록이나 대상 타임라인에 더 이상 표시되지 않음), 삭제는 되돌릴 수 없고 해당 `event_id`는 새 이벤트에 다시 사용할 수 있습니다. 영향을 받지 않는 항목: 이벤트가 연결되었던 사용자 또는 기업, 규칙에 의해 생성된 케이스, 규칙에 의해 추가된 목록 항목, 다른 이벤트에 이미 적용된 점수 및 상태. 개인이나 기업에 관한 모든 정보를 삭제하려면 사용자 또는 기업을 대신 삭제하십시오. 해당 이벤트도 함께 삭제됩니다. 스코프가 지정된 API 키에는 `transactions: write` 권한이 필요합니다.",
        "operationId": "delete_monitoring_event",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "parameters": [
          {
            "name": "event_uuid",
            "in": "path",
            "required": true,
            "description": "자체 `event_id`가 아닌 이벤트의 Didit 식별자(생성, 일괄 처리, 목록 또는 타임라인 응답의 `event_uuid`)입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/events/11111111-2222-3333-4444-555555555555/delete/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.monitoring_events.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.monitoringEvents.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.MonitoringEvents.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.monitoringEvents().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->monitoringEvents->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.monitoring_events.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.MonitoringEvents.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ],
        "responses": {
          "204": {
            "description": "이벤트가 삭제되었습니다. 본문이 없습니다."
          },
          "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 허용 목록 외부에서 발생한 요청입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "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."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 이 `event_uuid`를 가진 이벤트가 존재하지 않습니다. 저장된 적이 없거나, 삭제되었거나, 다른 애플리케이션에 속해 있습니다. UUID가 아닌 경로 세그먼트는 라우트와 일치하지 않아 마찬가지로 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No MonitoringEvent matches the given query."
                    }
                  }
                }
              }
            }
          },
          "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": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/parties/{partyUuid}/regenerate/": {
      "post": {
        "summary": "주요 인물 당사자의 KYC 세션 재생성",
        "description": "기업 확인(KYB) 세션의 주요 인물 당사자에게 이전 개인 KYC 세션이 삭제되었거나 해당 인물이 시작하기 전에 만료된 후 새로운 개인 KYC 세션을 부여하여 주요 인물 확인을 다시 완료할 수 있도록 합니다. 요청 본문은 전송하지 마십시오. 당사자의 KYC 세션이 삭제되었거나(`kyc_session_deleted: true`) 해당 인물이 시작하기 전에 만료된 경우(`Expired`, 시작되지 않음)에 작동합니다. 아직 진행 중인 세션이나 다른 상태(`Approved`, `Declined`, `In Review`, `Abandoned`, ...)로 종료된 세션은 삭제되지 않은 한 `409`를 반환합니다. 세션이 없었던 당사자나 기업 당사자는 항상 `409`를 반환합니다. Didit은 해당 당사자가 인증받았던 워크플로(최신 게시된 버전) 또는 더 이상 알 수 없는 경우 주요 인물 설정에서 당사자의 역할에 할당한 워크플로를 사용하여 새로운 호스팅 KYC 세션을 생성하므로, 해당 링크의 유효 기간은 해당 KYC 워크플로의 세션 만료 시간 동안 지속됩니다. 이메일이 등록되어 있으면 해당 당사자에게 링크를 이메일로 전송하고, `is_skipped`를 지우며, 주요 인물 확인 및 기업 세션 상태를 다시 계산합니다. 그런 다음 트리거 `console_key_people_regenerate`와 함께 기업 세션에 대한 `data.updated` [webhook](https://docs.didit.me/ko/integration/webhooks)을 전송합니다. 당사자를 대신 제외하려면 `PATCH /v3/session/{sessionId}/kyb/parties/{partyUuid}/`를 사용하십시오. 범위가 지정된 API 키에는 `decisions: write`가 필요하며, `sessions: write`가 없으면 `kyc_session_url`을 `null`로 수신합니다. 삭제된 세션은 해당 인물이 이미 인증을 시작했거나 완료했더라도 대상이 됩니다. 가져온 세션은 만료를 통해서는 대상이 되지 않으며, 반드시 삭제되었어야 합니다.",
        "operationId": "post_v3_session_kyb_party_regenerate",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "regenerate_kyb_party",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "상위 기업 확인(KYB) 세션의 UUID입니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "partyUuid",
            "in": "path",
            "required": true,
            "description": "주요 인물(Key People) 당사자의 UUID(기업 세션 결정의 `key_people_checks[].submitted.parties[].uuid`)입니다. `sessionId`로 참조되는 세션에 속해 있어야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/session/33333333-4444-5555-6666-777777777777/kyb/parties/0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41/regenerate/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.regenerate_kyb_party(\n    \"33333333-4444-5555-6666-777777777777\",\n    \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.regenerateKybParty(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.RegenerateKYBParty(ctx, \"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().regenerateKybParty(\"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->regenerateKybParty('33333333-4444-5555-6666-777777777777', '0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.regenerate_kyb_party(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.RegenerateKybPartyAsync(\"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "새 KYC 세션이 생성되었습니다. 업데이트된 당사자와 해당 KYC 워크플로의 세션 만료 시간 이후 만료되는 새 하위 세션을 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KYBKeyPeopleParty"
                },
                "example": {
                  "uuid": "0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41",
                  "entity_type": "person",
                  "source": "USER",
                  "name": "Jane Smith",
                  "first_name": "Jane",
                  "last_name": "Smith",
                  "company_name": null,
                  "registration_number": null,
                  "email": "user@example.com",
                  "nationality": "GB",
                  "phone_number": null,
                  "date_of_birth": "1980-05-04",
                  "position": "Director",
                  "custom_fields": {},
                  "is_active": true,
                  "is_skipped": false,
                  "requires_verification": true,
                  "roles": [
                    {
                      "role": "director",
                      "ownership_percent": null,
                      "voting_percent": null
                    }
                  ],
                  "kyc_session_id": "55555555-6666-7777-8888-999999999999",
                  "kyc_session_status": "Not Started",
                  "kyc_session_url": "https://verify.didit.me/session/abc123def456",
                  "kyc_session_deleted": false,
                  "kyb_sub_session_id": null,
                  "kyb_sub_session_status": null,
                  "kyb_sub_session_url": null,
                  "kyb_sub_session_deleted": false,
                  "verification_workflow_type": "kyc",
                  "verification_workflow_id": "12121212-3434-5656-7878-909090909090",
                  "verification_workflow_label": "Key People KYC",
                  "verification_workflow_features": [
                    {
                      "feature": "ID_VERIFICATION",
                      "status": "Not Finished"
                    },
                    {
                      "feature": "LIVENESS",
                      "status": "Not Finished"
                    },
                    {
                      "feature": "AML",
                      "status": "Not Finished"
                    }
                  ],
                  "didit_internal_id": null
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "스코프 지정 키에 decisions: write 권한이 없음",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나, 삭제되었거나, 범위가 지정된 키의 제한 범위를 벗어났습니다. 또는 애플리케이션에 이 UUID를 가진 당사자가 없거나, 해당 당사자가 다른 세션에 속해 있습니다. 각 사례마다 고유한 `detail`이 있습니다. 세션 조회가 자격 증명 확인보다 먼저 실행되므로, 유효한 키가 없더라도 알 수 없는 `sessionId`에 대해 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "이 ID를 가진 세션이 존재하지 않거나 삭제되었습니다",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "세션이 범위가 지정된 키의 워크플로 또는 승인 전용 제한 범위를 벗어났습니다",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "Unknown party": {
                    "summary": "귀하의 애플리케이션에 이 UUID를 가진 당사자가 없습니다",
                    "value": {
                      "detail": "No BusinessParty matches the given query."
                    }
                  },
                  "Party of another session": {
                    "summary": "partyUuid가 존재하지만 다른 세션에 속해 있음",
                    "value": {
                      "detail": "Party does not belong to the given session."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "해당 당사자에게 대체할 수 있는 적격 KYC 세션이 없습니다. 삭제되지 않은 한, 여전히 진행 중인 세션이나 다른 상태(`Approved`, `Declined`, `In Review`, `Abandoned` 등)로 끝난 세션은 재생성할 수 없습니다. 세션을 가진 적이 없는 당사자나 기업 당사자 역시 `409`를 반환합니다. 적격 세션은 사용자가 시작하기 전에 삭제되었거나 만료된 세션입니다. 삭제된 세션은 사용자가 이미 인증을 시작했거나 완료했더라도 자격이 주어집니다. 가져온 세션은 만료를 통해 자격이 주어지지 않으며, 반드시 삭제되었어야 합니다. `code`에 따라 분기 처리하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "detail",
                    "code"
                  ],
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "kyb_party_kyc_session_not_deleted"
                      ],
                      "description": "기계 판독 가능한 고정 오류 코드입니다."
                    }
                  }
                },
                "example": {
                  "detail": "This party's KYC session is still live (it has neither been deleted nor expired without starting), so it cannot be regenerated.",
                  "code": "kyb_party_kyc_session_not_deleted"
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. API 키당 분당 300회의 쓰기(POST, PATCH, DELETE) 요청으로 제한됩니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요. `X-RateLimit-*` 헤더에 한도 정보가 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "현재 분에 할당된 예산이 소진되었습니다",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/transactions/{transaction_id}/notes/": {
      "get": {
        "summary": "거래 메모 목록 조회",
        "description": "모니터링 대상 거래의 메모를 최신순(`created_at` 내림차순)으로 나열합니다. 여기에는 API를 통해 추가한 메모, 검토자가 Console에서 작성한 메모 및 상태 변경 사항, Didit이 자동으로 추가한 메모(규칙의 `add_note` 작업 또는 사용자 작업 인증 세션 생성 문제로 발생하며 `actor_name`이 `Rule Engine`으로 표시됨)가 포함됩니다. `metadata`로 메모 유형을 구분할 수 있습니다.\n\n`limit` 및 `offset`으로 페이지가 매겨집니다. `count`는 100까지 정확하며 100을 초과하면 100으로 제한되므로 `count`에서 페이지를 계산하는 대신 `next`가 `null`이 될 때까지 따라가십시오. 이는 부작용이 없는 읽기 작업입니다.\n\n범위가 지정된 API 키에는 `transactions: read` 권한이 필요합니다. 특정 워크플로나 승인된 세션으로 제한된 키는 이 endpoint를 호출할 수 없습니다. 검토자는 [거래 상세 정보](https://docs.didit.me/ko/transaction-monitoring/console#거래-상세)의 **메모** 아래에서 동일한 목록을 확인할 수 있습니다.",
        "operationId": "list_transaction_notes",
        "x-didit-sdk": {
          "resource": "transactions.notes",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "Didit 거래 UUID: `POST /v3/transactions/` 및 `GET /v3/transactions/`에서 반환된 `uuid`입니다. 자체 `txn_id`는 허용되지 않습니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "abcdef12-3456-7890-abcd-ef1234567890"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "description": "페이지당 메모 수입니다. 기본값은 50입니다. 양의 정수가 아닌 값은 50으로 대체되며, 1000000을 초과하는 값은 `400`을 반환합니다."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "description": "반환할 첫 번째 노트의 0부터 시작하는 위치입니다. `next`를 따르는 것이 좋습니다. 0 이상의 정수가 아닌 값은 0으로 대체되며, 1000000을 초과하는 값은 `400`을 반환합니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/abcdef12-3456-7890-abcd-ef1234567890/notes/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.notes.list(\n    \"abcdef12-3456-7890-abcd-ef1234567890\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.notes.list(\"abcdef12-3456-7890-abcd-ef1234567890\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.Notes.ListAutoPaging(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\", didit.TransactionsNotesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().notes().list(\"abcdef12-3456-7890-abcd-ef1234567890\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->transactions->notes->list('abcdef12-3456-7890-abcd-ef1234567890') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.notes.list(\"abcdef12-3456-7890-abcd-ef1234567890\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.Notes.ListAsync(\"abcdef12-3456-7890-abcd-ef1234567890\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "최신순으로 정렬된 메모 페이지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "거래의 메모 수: 최대 100개까지는 정확하며, 100개를 초과하면 100으로 제한됩니다. 페이지 수를 직접 계산하는 대신 `next`를 따르십시오."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "다음 페이지의 절대 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "이전 페이지의 절대 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TransactionNote"
                      }
                    }
                  }
                },
                "examples": {
                  "API, Console and rule notes": {
                    "value": {
                      "count": 3,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "c1111111-2222-4333-8444-555555555555",
                          "note": "Customer confirmed the withdrawal by phone.",
                          "actor_email": null,
                          "actor_name": null,
                          "metadata": {
                            "mentioned_emails": [
                              "analyst@example.com"
                            ]
                          },
                          "created_at": "2026-10-16T10:05:12.481203Z"
                        },
                        {
                          "uuid": "c2222222-3333-4444-8555-666666666666",
                          "note": "Status changed from IN_REVIEW to APPROVED. Reason: Source of funds verified",
                          "actor_email": "reviewer@example.com",
                          "actor_name": "Alex Reviewer",
                          "metadata": {
                            "type": "status_change",
                            "previous_status": "IN_REVIEW",
                            "new_status": "APPROVED",
                            "reason_code": "SOF_VERIFIED",
                            "reason_label": "Source of funds verified"
                          },
                          "created_at": "2026-10-15T17:22:40.103911Z"
                        },
                        {
                          "uuid": "c3333333-4444-4555-8666-777777777777",
                          "note": "Large withdrawal to a new wallet: check the source of funds.",
                          "actor_email": null,
                          "actor_name": "Rule Engine",
                          "metadata": {
                            "rule_uuid": "d1111111-2222-4333-8444-555555555555",
                            "source": "rule_action"
                          },
                          "created_at": "2026-10-15T08:42:12.004518Z"
                        }
                      ]
                    }
                  },
                  "No notes yet": {
                    "value": {
                      "count": 0,
                      "next": null,
                      "previous": null,
                      "results": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`limit` 또는 `offset`이 1000000을 초과합니다. 본문은 객체가 아닌 메시지의 JSON 배열입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "examples": {
                  "Limit too large": {
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  },
                  "Offset too large": {
                    "value": [
                      "offset must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 만료일이 지정되어 생성된 키만 만료될 수 있으며, 해당 날짜 이후에는 이를 사용한 모든 요청에 `401`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. 키가 누락된 경우 일반 메시지가 반환되며, 잘못되거나 취소되었거나 만료된 키는 `401`을 받습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without transactions read": {
                    "value": {
                      "detail": "This API key has no read 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."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 이 UUID를 가진 거래가 존재하지 않습니다(생성된 적이 없거나, 삭제되었거나, 다른 애플리케이션 소유임). UUID가 아닌 `transaction_id`는 API에 도달하지 않으며, 이 JSON 본문 대신 `404` HTML 페이지를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No Transaction matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "이 API 키로 분당 600건을 초과하는 GET 요청이 발생했습니다. `Retry-After`에 명시된 시간(초)만큼 대기한 후 다시 시도하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "현재 1분 기간이 초기화될 때까지 남은 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "이 예산에서 분당 허용되는 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "윈도우가 리셋되는 Unix 시간입니다.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "거래 메모 생성",
        "description": "모니터링 중인 거래의 검토 타임라인에 일반 텍스트 메모를 추가하여 Console 검토자가 볼 수 있도록 합니다. 메모는 맥락 정보이며 결정이 아닙니다. 거래의 `status`, `score` 및 알림은 변경되지 않고 webhook도 전송되지 않으며 아무것도 청구되지 않습니다. 거래의 `activities`에 `TRANSACTION_NOTE_ADDED` 항목이 추가됩니다.\n\nAPI 키로 생성된 메모에는 작성자가 없습니다. `actor_email` 및 `actor_name`이 `null`이므로 필요한 경우 텍스트에 작성자를 포함하십시오. `mentioned_emails`의 모든 주소는 조직의 멤버에 속해야 하며, 그렇지 않으면 전체 요청이 `400`으로 실패합니다. 멘션은 소문자로 변환되어 중복 제거 후 저장되며, 이 endpoint는 멘션된 멤버에게 알림을 보내지 않습니다.\n\n각 호출마다 새 메모가 생성되므로 시간 초과된 요청을 재시도하면 메모가 두 번 추가될 수 있습니다. 재시도하기 전에 메모 목록을 조회하십시오. 메모를 편집하거나 삭제하는 API endpoint는 없습니다. 범위가 지정된 API 키에는 `transactions: write` 권한이 필요합니다. 일부 워크플로나 승인된 세션으로 제한된 키는 이 endpoint를 호출할 수 없습니다.",
        "operationId": "create_transaction_note",
        "x-didit-sdk": {
          "resource": "transactions.notes",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "Didit 거래 UUID: `POST /v3/transactions/` 및 `GET /v3/transactions/`에서 반환된 `uuid`입니다. 자체 `txn_id`는 허용되지 않습니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "abcdef12-3456-7890-abcd-ef1234567890"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "note"
                ],
                "properties": {
                  "note": {
                    "type": "string",
                    "minLength": 1,
                    "description": "일반 텍스트 메모입니다. 앞뒤 공백은 잘라내며 빈 메모는 거부됩니다. 길이 제한은 없습니다."
                  },
                  "mentioned_emails": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "email"
                    },
                    "default": [],
                    "description": "멘션할 조직 멤버의 이메일입니다. 각 이메일은 유효한 조직 멤버의 이메일이어야 합니다."
                  }
                }
              },
              "examples": {
                "Note with a mention": {
                  "value": {
                    "note": "Customer confirmed the withdrawal by phone.",
                    "mentioned_emails": [
                      "analyst@example.com"
                    ]
                  }
                },
                "Plain note": {
                  "value": {
                    "note": "Source of funds document requested by email."
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/transactions/abcdef12-3456-7890-abcd-ef1234567890/notes/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"note\": \"Customer confirmed the withdrawal by phone.\", \"mentioned_emails\": [\"analyst@example.com\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.notes.create(\n    \"abcdef12-3456-7890-abcd-ef1234567890\",\n    note=\"Customer confirmed the withdrawal by phone.\",\n    mentioned_emails=[\"analyst@example.com\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.notes.create(\"abcdef12-3456-7890-abcd-ef1234567890\", {\n  note: \"Customer confirmed the withdrawal by phone.\",\n  mentioned_emails: [\"analyst@example.com\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Notes.Create(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\", didit.TransactionsNotesCreateParams{\n\tNote:            \"Customer confirmed the withdrawal by phone.\",\n\tMentionedEmails: didit.Some([]string{\"analyst@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;\nimport me.didit.Didit;\nimport me.didit.types.TransactionsNotesCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().notes().create(\"abcdef12-3456-7890-abcd-ef1234567890\", TransactionsNotesCreateParams.builder()\n        .note(\"Customer confirmed the withdrawal by phone.\")\n        .mentionedEmails(List.of(\"analyst@example.com\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->notes->create('abcdef12-3456-7890-abcd-ef1234567890', [\n    'note' => 'Customer confirmed the withdrawal by phone.',\n    'mentioned_emails' => ['analyst@example.com'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.notes.create(\n  \"abcdef12-3456-7890-abcd-ef1234567890\",\n  note: \"Customer confirmed the withdrawal by phone.\",\n  mentioned_emails: [\"analyst@example.com\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Notes.CreateAsync(\"abcdef12-3456-7890-abcd-ef1234567890\", new TransactionsNotesCreateParams\n{\n    Note = \"Customer confirmed the withdrawal by phone.\",\n    MentionedEmails = new string[] { \"analyst@example.com\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "메모가 생성되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionNote"
                },
                "examples": {
                  "Created": {
                    "value": {
                      "uuid": "c1111111-2222-4333-8444-555555555555",
                      "note": "Customer confirmed the withdrawal by phone.",
                      "actor_email": null,
                      "actor_name": null,
                      "metadata": {
                        "mentioned_emails": [
                          "analyst@example.com"
                        ]
                      },
                      "created_at": "2026-10-16T10:05:12.481203Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "본문이 잘못되었습니다: `note`가 누락되었거나 null이거나 비어 있음, `mentioned_emails`에 잘못된 주소가 포함됨(목록 위치별 오류 키 지정), 또는 멘션된 주소가 조직의 멤버가 아닙니다. 아무것도 생성되지 않았습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "필드 이름을 키로 하는 필드 오류입니다.",
                  "additionalProperties": {}
                },
                "examples": {
                  "Missing note": {
                    "value": {
                      "note": [
                        "This field is required."
                      ]
                    }
                  },
                  "Blank note": {
                    "value": {
                      "note": [
                        "This field may not be blank."
                      ]
                    }
                  },
                  "Invalid email": {
                    "value": {
                      "mentioned_emails": {
                        "0": [
                          "Enter a valid email address."
                        ]
                      }
                    }
                  },
                  "Not an organization member": {
                    "value": {
                      "mentioned_emails": [
                        "Mentioned users must belong to this organization and have access to this application."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 만료일이 지정되어 생성된 키만 만료될 수 있으며, 해당 날짜 이후에는 이를 사용한 모든 요청에 `401`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. 키가 누락된 경우 일반 메시지가 반환되며, 잘못되거나 취소되었거나 만료된 키는 `401`을 받습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without transactions write": {
                    "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."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 이 UUID를 가진 거래가 존재하지 않습니다(생성된 적이 없거나, 삭제되었거나, 다른 애플리케이션 소유임). UUID가 아닌 `transaction_id`는 API에 도달하지 않으며, 이 JSON 본문 대신 `404` HTML 페이지를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No Transaction matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "이 API 키로 분당 300건을 초과하는 쓰기 요청이 발생했습니다. `Retry-After`에 명시된 시간(초)만큼 대기한 후 다시 시도하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "현재 1분 기간이 초기화될 때까지 남은 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "이 예산에서 분당 허용되는 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "윈도우가 리셋되는 Unix 시간입니다.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/transactions/{transaction_id}/related/": {
      "get": {
        "summary": "관련 거래 목록 조회",
        "description": "이 거래와 동일한 인물 또는 기업이 관련된 애플리케이션 내의 다른 거래 목록을 조회합니다. 거래의 당사자 중 역할에 관계없이 이 거래의 당사자 중 하나와 동일한 `vendor_data`를 가진 당사자가 있는 경우 관련 거래로 간주됩니다. 해당 거래 자체는 반환되지 않으며, `vendor_data`가 없는 당사자는 무시됩니다. 이 거래의 당사자 중 누구도 이를 가지고 있지 않은 경우 결과는 항상 비어 있습니다.\n\n결과는 `GET /v3/transactions/`의 요약 형태를 사용하며 최신순(`txn_date`, 그 다음 `created_at`)으로 정렬됩니다. `limit` 및 `offset`으로 페이지네이션됩니다. `count`는 100까지 정확하며 그 이상은 100으로 제한되므로 `next`가 `null`이 될 때까지 따라가십시오.\n\n범위가 지정된 API 키에는 `transactions: read`가 필요합니다. 일부 워크플로나 승인된 세션으로 제한된 키는 이 endpoint를 호출할 수 없습니다. 이 목록을 완전하게 유지하려면 모든 [거래](https://docs.didit.me/ko/transaction-monitoring/transactions#주체-및-거래-상대방)에서 동일한 인물이나 기업에 대해 동일한 `vendor_data`를 전송하십시오.",
        "operationId": "list_related_transactions",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "list_related",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "Didit 거래 UUID: `POST /v3/transactions/` 및 `GET /v3/transactions/`에서 반환된 `uuid`입니다. 자체 `txn_id`는 허용되지 않습니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "abcdef12-3456-7890-abcd-ef1234567890"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "description": "페이지당 거래 수입니다. 기본값은 50입니다. 양의 정수가 아닌 값은 50으로 대체되며, 1000000을 초과하는 값은 `400`을 반환합니다."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "description": "반환할 첫 번째 거래의 0부터 시작하는 위치입니다. `next`를 따르는 것이 좋습니다. 0 이상의 정수가 아닌 값은 0으로 대체되며, 1000000을 초과하는 값은 `400`을 반환합니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/abcdef12-3456-7890-abcd-ef1234567890/related/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.list_related(\n    \"abcdef12-3456-7890-abcd-ef1234567890\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.listRelated(\"abcdef12-3456-7890-abcd-ef1234567890\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.ListRelatedAutoPaging(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\", didit.TransactionsListRelatedParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().listRelated(\"abcdef12-3456-7890-abcd-ef1234567890\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->transactions->listRelated('abcdef12-3456-7890-abcd-ef1234567890') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.list_related(\"abcdef12-3456-7890-abcd-ef1234567890\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.ListRelatedAsync(\"abcdef12-3456-7890-abcd-ef1234567890\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "최신순으로 정렬된 관련 거래 페이지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "관련 거래 수: 최대 100개까지는 정확하며, 100개를 초과하면 100으로 제한됩니다. 페이지 수를 직접 계산하는 대신 `next`를 따르십시오."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "다음 페이지의 절대 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "이전 페이지의 절대 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TransactionSummary"
                      }
                    }
                  }
                },
                "examples": {
                  "One related transaction": {
                    "value": {
                      "count": 1,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "abcdef99-3456-4890-abcd-ef1234567890",
                          "transaction_number": 4087,
                          "txn_id": "your-txn-2026-10-02-017",
                          "transaction_type": "finance",
                          "action_type": "deposit",
                          "status": "APPROVED",
                          "source": "LIVE",
                          "direction": "INBOUND",
                          "amount": "250",
                          "currency": "EUR",
                          "currency_type": "fiat",
                          "preferred_currency_amount": "270.08",
                          "preferred_currency_code": "USD",
                          "payment_details": "Card top-up",
                          "txn_date": "2026-10-02T14:10:00Z",
                          "created_at": "2026-10-02T14:10:03.512244Z",
                          "score": 12,
                          "severity": "LOW",
                          "decision_reason_code": null,
                          "decision_reason_label": null,
                          "tags": [],
                          "subject_name": "Maria Garcia",
                          "subject_vendor_data": "user-12345",
                          "subject_type": "user",
                          "subject_uuid": "e1111111-2222-4333-8444-555555555555",
                          "counterparty_name": null,
                          "counterparty_vendor_data": null,
                          "counterparty_country": null,
                          "subject_country": "ESP",
                          "assigned_to_name": null,
                          "travel_rule_status": null,
                          "application_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                          "application_name": "Production app",
                          "organization_id": "11111111-2222-3333-4444-555555555555",
                          "organization_name": "Example Org"
                        }
                      ]
                    }
                  },
                  "No party has vendor_data": {
                    "value": {
                      "count": 0,
                      "next": null,
                      "previous": null,
                      "results": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`limit` 또는 `offset`이 1000000을 초과합니다. 본문은 객체가 아닌 메시지의 JSON 배열입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "examples": {
                  "Limit too large": {
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  },
                  "Offset too large": {
                    "value": [
                      "offset must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 만료일이 지정되어 생성된 키만 만료될 수 있으며, 해당 날짜 이후에는 이를 사용한 모든 요청에 `401`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. 키가 누락된 경우 일반 메시지가 반환되며, 잘못되거나 취소되었거나 만료된 키는 `401`을 받습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without transactions read": {
                    "value": {
                      "detail": "This API key has no read 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."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 이 UUID를 가진 거래가 존재하지 않습니다(생성된 적이 없거나, 삭제되었거나, 다른 애플리케이션 소유임). UUID가 아닌 `transaction_id`는 API에 도달하지 않으며, 이 JSON 본문 대신 `404` HTML 페이지를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No Transaction matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "이 API 키로 분당 600건을 초과하는 GET 요청이 발생했습니다. `Retry-After`에 명시된 시간(초)만큼 대기한 후 다시 시도하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "현재 1분 기간이 초기화될 때까지 남은 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "이 예산에서 분당 허용되는 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "윈도우가 리셋되는 Unix 시간입니다.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/businesses/{business_session_id}/pdf/": {
      "get": {
        "summary": "기업 세션 PDF 보고서 다운로드",
        "description": "단일 기업 확인(KYB) 세션의 PDF 보고서를 렌더링합니다. 법인 등기부 데이터, 주요 인물 및 실소유자, 문서, AML 결과 및 기타 워크플로 기능뿐만 아니라 세션의 태그 및 검토 활동이 포함됩니다. 화이트 라벨 맞춤 설정을 활성화하면 보고서에 귀사의 로고와 개인정보 처리방침 URL이 표시됩니다. 본문은 JSON이 아닌 PDF 자체(`application/pdf`)입니다.\n\n세션 상태는 `Approved`, `Declined` 또는 `In Review`여야 합니다. 그 외의 모든 상태는 `403`을 반환하므로 먼저 `status.updated` [webhook](https://docs.didit.me/ko/integration/webhooks)을 기다리십시오. 보고서는 호출할 때마다 렌더링되며 비용은 청구되지 않으므로, 반복해서 가져오는 대신 파일을 저장해 두십시오. `GET /v3/session/{sessionId}/generate-pdf/`는 세션 ID만으로 동일한 종류의 보고서를 렌더링합니다.\n\nPDF 보고서는 미디어로 간주됩니다. 범위가 지정된 API 키에는 `businesses: read` 및 `media: read` 권한이 필요하며, 특정 워크플로나 승인된 세션으로 제한된 키로는 이를 호출할 수 없습니다.",
        "operationId": "get_business_session_pdf",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "generate_session_pdf",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다.",
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다. API 키가 속한 애플리케이션이어야 합니다. 다른 애플리케이션에 사용된 키는 `403`을 받습니다.",
            "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
          },
          {
            "name": "business_session_id",
            "in": "path",
            "required": true,
            "description": "세션 생성 시 반환된 기업 확인(KYB) 세션의 `session_id`입니다. 다른 애플리케이션의 세션인 경우 `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "22222222-3333-4444-5555-666666666666"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl --fail -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/businesses/22222222-3333-4444-5555-666666666666/pdf/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  --output business_report.pdf"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\ncontent = client.businesses.generate_session_pdf(\n    \"22222222-3333-4444-5555-666666666666\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst content = await didit.businesses.generateSessionPdf(\"22222222-3333-4444-5555-666666666666\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresp, err := client.Businesses.GenerateSessionPDF(ctx, \"22222222-3333-4444-5555-666666666666\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.businesses().generateSessionPdf(\"22222222-3333-4444-5555-666666666666\")\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$content = $didit->businesses->generateSessionPdf('22222222-3333-4444-5555-666666666666');\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ncontent = didit.businesses.generate_session_pdf(\"22222222-3333-4444-5555-666666666666\")\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar content = await client.Businesses.GenerateSessionPdfAsync(\"22222222-3333-4444-5555-666666666666\");\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ],
        "responses": {
          "200": {
            "description": "렌더링된 PDF로, 바이너리 `application/pdf` 형식으로 직접 반환됩니다.",
            "headers": {
              "Content-Disposition": {
                "description": "항상 `attachment; filename=business_{business_session_id}.pdf`입니다.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=business_22222222-3333-4444-5555-666666666666.pdf"
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 만료일이 지정되어 생성된 키만 만료될 수 있으며, 해당 날짜 이후에는 이를 사용한 모든 요청에 `401`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않거나 세션이 완료되지 않았습니다. `detail`을 확인하세요. `Approved`, `Declined` 또는 `In Review` 상태가 아닌 세션, API 키 누락(잘못되거나 취소되었거나 만료된 키는 `401` 수신), 해당 키의 애플리케이션이 아닌 `application_id`, `media: read` 또는 `businesses: read` 권한이 없는 스코프 제한 키, 워크플로 또는 승인된 세션으로 제한된 키, 또는 키의 IP 허용 목록 외부에서의 요청 등이 해당됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Session not finished": {
                    "value": {
                      "detail": "You can only generate a PDF for sessions in review, declined or approved."
                    }
                  },
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without media read": {
                    "value": {
                      "detail": "This API key has no read access to media."
                    }
                  },
                  "Scoped key without businesses read": {
                    "value": {
                      "detail": "This API key has no read access to companies."
                    }
                  },
                  "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."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 이 ID를 가진 기업 세션이 존재하지 않습니다(생성된 적이 없거나, 삭제되었거나, 다른 애플리케이션의 소유임). UUID가 아닌 값은 이 JSON 본문 대신 `404` HTML 페이지를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Business session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "이 API 키로 분당 600건을 초과하는 GET 요청이 발생했습니다. `Retry-After`에 명시된 시간(초)만큼 대기한 후 다시 시도하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "현재 1분 기간이 초기화될 때까지 남은 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "이 예산에서 분당 허용되는 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "윈도우가 리셋되는 Unix 시간입니다.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/transactions/{transaction_uuid}/pdf/": {
      "get": {
        "summary": "거래 PDF 보고서 다운로드",
        "description": "모니터링 대상 거래 하나를 PDF 보고서로 렌더링합니다. 개요 및 판정, 당사자 및 결제 수단, 커스텀 속성, 알림 및 규칙 실행 결과, 스크리닝 및 Travel Rule 결과, 네트워크 요약, 비용 내역, 최대 50개의 관련 거래 및 가장 최근 활동 기록 20개가 포함됩니다. 응답 본문은 JSON이 아닌 PDF 자체(`application/pdf`)입니다.\n\n보고서는 호출할 때마다 거래의 현재 데이터로부터 렌더링되므로, 상태가 변경된 후에는 다시 요청하십시오. 저장되는 데이터는 없으며 요금도 청구되지 않습니다. 렌더링에 수 초가 걸릴 수 있으므로 클라이언트 타임아웃을 넉넉하게 설정하십시오.\n\n이 endpoint는 애플리케이션 범위의 경로에 있습니다. URL에 조직 ID와 API 키가 속한 애플리케이션 ID를 입력하십시오([조직 ID 찾기](https://docs.didit.me/ko/getting-started/api-authentication#조직-id-확인하기)). PDF 보고서는 미디어로 간주됩니다. 범위가 지정된 API 키에는 `media: read` 및 `transactions: read` 권한이 필요하며, 특정 워크플로나 승인된 세션으로 제한된 키로는 호출할 수 없습니다.",
        "operationId": "get_transaction_pdf",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "generate_pdf",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다.",
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다. API 키가 속한 애플리케이션이어야 합니다. 다른 애플리케이션에 사용된 키는 `403`을 받습니다.",
            "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
          },
          {
            "name": "transaction_uuid",
            "in": "path",
            "required": true,
            "description": "Didit 거래 UUID: `POST /v3/transactions/` 및 `GET /v3/transactions/`에서 반환된 `uuid`입니다. 자체 `txn_id`는 허용되지 않습니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "abcdef12-3456-7890-abcd-ef1234567890"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl --fail -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/transactions/abcdef12-3456-7890-abcd-ef1234567890/pdf/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  --output transaction_report.pdf"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\ncontent = client.transactions.generate_pdf(\n    \"abcdef12-3456-7890-abcd-ef1234567890\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst content = await didit.transactions.generatePdf(\"abcdef12-3456-7890-abcd-ef1234567890\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresp, err := client.Transactions.GeneratePDF(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.transactions().generatePdf(\"abcdef12-3456-7890-abcd-ef1234567890\")\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$content = $didit->transactions->generatePdf('abcdef12-3456-7890-abcd-ef1234567890');\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ncontent = didit.transactions.generate_pdf(\"abcdef12-3456-7890-abcd-ef1234567890\")\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar content = await client.Transactions.GeneratePdfAsync(\"abcdef12-3456-7890-abcd-ef1234567890\");\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ],
        "responses": {
          "200": {
            "description": "렌더링된 PDF로, 바이너리 `application/pdf` 형식으로 직접 반환됩니다.",
            "headers": {
              "Content-Disposition": {
                "description": "항상 `attachment; filename=transaction_{transaction_uuid}.pdf`입니다.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=transaction_abcdef12-3456-7890-abcd-ef1234567890.pdf"
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 만료일이 지정되어 생성된 키만 만료될 수 있으며, 해당 날짜 이후에는 이를 사용한 모든 요청에 `401`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. `detail`을 확인하십시오. API 키 누락(잘못되었거나 폐기되었거나 만료된 키는 `401` 수신), 해당 키의 애플리케이션이 아닌 `application_id`, `media: read` 또는 `transactions: read` 권한이 없는 범위 지정 키, 워크플로 또는 승인된 세션으로 제한된 키, 또는 키의 IP 목록 외부에서의 요청 등이 해당됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without media read": {
                    "value": {
                      "detail": "This API key has no read access to media."
                    }
                  },
                  "Scoped key without transactions read": {
                    "value": {
                      "detail": "This API key has no read 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."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "애플리케이션에 이 UUID를 가진 거래가 존재하지 않습니다(생성된 적이 없거나, 삭제되었거나, 다른 애플리케이션 소유임). UUID가 아닌 `transaction_uuid`는 API에 도달하지 않으며, 이 JSON 본문 대신 `404` HTML 페이지를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No Transaction matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "이 API 키로 분당 600건을 초과하는 GET 요청이 발생했습니다. `Retry-After`에 명시된 시간(초)만큼 대기한 후 다시 시도하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "현재 1분 기간이 초기화될 때까지 남은 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "이 예산에서 분당 허용되는 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "윈도우가 리셋되는 Unix 시간입니다.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/analytics/": {
      "get": {
        "summary": "애플리케이션 분석 조회",
        "description": "지정된 날짜 범위 동안 Business Console [분석 대시보드](https://docs.didit.me/ko/console/analytics)의 기반 데이터를 조회합니다. `scope` 및 `widget_keys`가 없으면 응답은 사용자 인증(KYC) 요약(`ApplicationAnalyticsSummary`)입니다: 일일 세션 수, 상태별 합계, 전환율, 동일한 길이의 이전 기간 수치, 위치, 인구 통계, 기기, 워크플로 퍼널, 활성 인증 시간, 재제출, 경고 및 시계열 데이터가 포함됩니다. `scope` 또는 `widget_keys`가 있으면 하나의 대시보드 탭 위젯(`ApplicationAnalyticsWidgetResponse`)이 반환됩니다: `kyc`, `kyb`, `transactions` 또는 `home`.\n\n세션 수는 세션 생성 날짜(UTC) 기준이며 각 세션의 현재 상태를 반영합니다. 백그라운드에서 갱신되는 일일 롤업 데이터를 바탕으로 하므로 가장 최근 활동이 표시되는 데 약간의 시간이 걸릴 수 있습니다. 유효하지 않은 워크플로 ID 및 버전은 거부되지 않고 무시됩니다. 비용은 청구되지 않습니다.\n\n전체 액세스 API 키만 이 endpoint를 호출할 수 있습니다. 어떤 권한을 보유하든 범위가 지정된 모든 키에는 `403`이 반환되며, 다른 애플리케이션의 키도 마찬가지입니다. [API 키](https://docs.didit.me/ko/console/api-keys)를 참고하세요.",
        "operationId": "get_application_analytics",
        "x-didit-sdk": {
          "resource": "analytics",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Analytics"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다.",
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다. API 키가 속한 애플리케이션이어야 합니다. 다른 애플리케이션에 사용된 키는 `403`을 받습니다.",
            "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
          },
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-10-01"
            },
            "description": "조회 기간의 시작일(UTC)로, `YYYY-MM-DD` 형식(포함)입니다. `end_date`와 함께 전송해야 합니다. 둘 중 하나라도 누락되면 둘 다 무시되고 오늘 기준 30일 전부터 오늘까지로 조회 기간이 설정됩니다."
          },
          {
            "name": "end_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-10-15"
            },
            "description": "범위의 마지막 날(`YYYY-MM-DD`, 해당 일자 포함, UTC)입니다. 미래 날짜는 오늘로 간주됩니다. 범위는 730일을 초과할 수 없습니다."
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "home",
                "kyc",
                "kyb",
                "transactions"
              ]
            },
            "description": "위젯을 반환할 대시보드 탭입니다(대소문자 구분 없음). KYC 요약의 경우 `widget_keys`와 함께 생략합니다. `widget_keys`만 전송하면 `kyc`로 간주됩니다. `home`은 모든 KYC, KYB 또는 거래 위젯을 허용하며 애플리케이션에 저장된 홈 레이아웃을 기본값으로 사용합니다."
          },
          {
            "name": "widget_keys",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "tx_count_total,tx_count_daily"
            },
            "description": "쉼표로 구분된 위젯 키 목록으로, 이 순서대로 반환됩니다. 스코프에서 허용하지 않는 키는 제외되며, 유효한 키가 남지 않으면 해당 스코프의 기본값이 제공됩니다. KYC: `kyc_sessions_volume`, `kyc_warning_insights`, `kyc_id_locations`, `kyc_ip_locations`, `kyc_workflow_funnel`, `kyc_average_verification_time`, `kyc_conversion_rate`, `kyc_conversion_by_country`, `kyc_resubmission_insights`, `kyc_original_status_distribution`, `kyc_database_validation_coverage`, `kyc_database_validation_latency`, `kyc_demographics`, `kyc_device_details`. KYB: `kyb_sessions_volume`, `kyb_workflow_funnel`, `kyb_average_verification_time`, `kyb_ip_locations`, `kyb_business_country_distribution`, `kyb_warning_insights`, `kyb_conversion_rate`, `kyb_conversion_by_country`, `kyb_industry_breakdown`, `kyb_resubmission_insights`, `kyb_original_status_distribution`, `kyb_registry_coverage`, `kyb_registry_data_completeness`, `kyb_device_details`. Transactions: `tx_count_total`, `tx_count_daily`, `tx_volume_total_preferred_currency`, `tx_volume_daily_preferred_currency`, `tx_average_amount`, `tx_average_amount_daily`, `tx_transaction_category_breakdown`, `tx_action_type_breakdown`, `tx_status_volume_trend`, `tx_user_ip_or_country_distribution`, `tx_tag_breakdown`, `tx_top_rules_triggered`, `tx_team_member_performance`, `tx_score_histogram`."
          },
          {
            "name": "workflow_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "33333333-4444-5555-6666-777777777777"
            },
            "description": "쉼표로 구분된 워크플로 ID 목록입니다. KYC 요약 및 KYC, KYB 위젯을 해당 워크플로로 제한합니다. UUID가 아닌 값은 무시되며, 유효한 값이 없으면 필터가 적용되지 않습니다. 요약에서는 `workflow_id`도 사용할 수 있습니다."
          },
          {
            "name": "versions",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "3,4"
            },
            "description": "쉼표로 구분된 워크플로 버전 번호 목록입니다. `workflow_ids`와 함께 사용할 때만 적용되며, 정수가 아닌 값은 무시됩니다. 별칭으로 `version`도 사용할 수 있습니다."
          },
          {
            "name": "branch_path_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "default"
            },
            "description": "쉼표로 구분된 분기 경로 ID. `workflow_ids`와 함께 사용할 때만 적용되며 KYC 수치에만 해당합니다. 현재 수치는 `default`(모든 경로 합산)에 대해서만 기록되므로 다른 값을 지정하면 빈 수치가 반환됩니다. `branch_path_id`는 별칭으로 허용됩니다."
          },
          {
            "name": "tag",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "거래 위젯 전용: 쉼표로 구분된 태그 UUID 또는 태그 이름입니다."
          },
          {
            "name": "transaction_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "finance"
            },
            "description": "거래 위젯 전용: 쉼표로 구분된 거래 카테고리입니다."
          },
          {
            "name": "action_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "withdrawal"
            },
            "description": "거래 위젯 전용: 쉼표로 구분된 작업 유형(대소문자 구분 없음)."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/analytics/?start_date=2026-10-01&end_date=2026-10-15' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.analytics.retrieve()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.analytics.retrieve();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Analytics.Retrieve(ctx, didit.AnalyticsRetrieveParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.analytics().retrieve();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->analytics->retrieve();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.analytics.retrieve\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Analytics.RetrieveAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "`scope` 또는 `widget_keys`가 전송된 경우 KYC 요약 또는 요청된 위젯입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ApplicationAnalyticsSummary"
                    },
                    {
                      "$ref": "#/components/schemas/ApplicationAnalyticsWidgetResponse"
                    }
                  ]
                },
                "examples": {
                  "KYC summary": {
                    "value": {
                      "grouping_mode": "day",
                      "data_points": [
                        {
                          "rounded_date": "2026-10-14",
                          "total": 12,
                          "approved": 8,
                          "declined": 1,
                          "canceled": 1,
                          "pending": 2,
                          "in_review": 1,
                          "expired": 1,
                          "abandoned": 0,
                          "in_progress": 1,
                          "not_started": 0,
                          "manually_approved": 1,
                          "manually_declined": 0
                        },
                        {
                          "rounded_date": "2026-10-15",
                          "total": 10,
                          "approved": 6,
                          "declined": 2,
                          "canceled": 0,
                          "pending": 2,
                          "in_review": 2,
                          "expired": 0,
                          "abandoned": 0,
                          "in_progress": 0,
                          "not_started": 0,
                          "manually_approved": 0,
                          "manually_declined": 1
                        }
                      ],
                      "request_breakdown": {
                        "total_approved": 14,
                        "total_in_review": 3,
                        "total_declined": 3,
                        "total_canceled": 1,
                        "total_pending": 4,
                        "total_expired": 1,
                        "total_abandoned": 0,
                        "total_in_progress": 1,
                        "total_not_started": 0,
                        "total_manually_approved": 1,
                        "total_manually_declined": 1
                      },
                      "conversion_rate": 70.0,
                      "location_stats": {
                        "countries": [
                          {
                            "session_count": 15,
                            "country": "Spain",
                            "country_code": "ES"
                          },
                          {
                            "session_count": 7,
                            "country": "Portugal",
                            "country_code": "PT"
                          }
                        ],
                        "ip_countries": [
                          {
                            "session_count": 15,
                            "country": "Spain",
                            "country_code": "ES"
                          },
                          {
                            "session_count": 7,
                            "country": "Portugal",
                            "country_code": "PT"
                          }
                        ],
                        "id_countries": [
                          {
                            "country": "Spain",
                            "country_code": "ES",
                            "session_count": 14
                          },
                          {
                            "country": "Portugal",
                            "country_code": "PT",
                            "session_count": 6
                          }
                        ],
                        "conversion_by_country": [
                          {
                            "country": "Spain",
                            "country_code": "ES",
                            "finished": 13,
                            "approved": 10
                          },
                          {
                            "country": "Portugal",
                            "country_code": "PT",
                            "finished": 6,
                            "approved": 4
                          }
                        ],
                        "cities": [
                          {
                            "session_count": 9,
                            "location": "Madrid, Spain",
                            "latitude": 40.4168,
                            "longitude": -3.7038
                          }
                        ]
                      },
                      "demographic_stats": {
                        "age_distribution": {
                          "under_18": 0,
                          "18_24": 5,
                          "25_34": 8,
                          "35_44": 4,
                          "45_64": 2,
                          "65_plus": 1
                        },
                        "gender_distribution": {
                          "M": 11,
                          "F": 9
                        }
                      },
                      "device_details": {
                        "device_models": [
                          {
                            "device": "Apple",
                            "count": 12
                          },
                          {
                            "device": "Android",
                            "count": 10
                          }
                        ],
                        "browsers": [
                          {
                            "browser": "Safari",
                            "count": 12
                          },
                          {
                            "browser": "Chrome",
                            "count": 10
                          }
                        ],
                        "operating_systems": [
                          {
                            "os": "iOS",
                            "count": 12
                          },
                          {
                            "os": "Android",
                            "count": 10
                          }
                        ]
                      },
                      "workflow_funnel_stats": {
                        "33333333-4444-5555-6666-777777777777": {
                          "total": 22,
                          "steps": {
                            "OCR": {
                              "reached": 21
                            },
                            "LIVENESS": {
                              "reached": 19
                            },
                            "FACE_MATCH": {
                              "reached": 19
                            },
                            "AML": {
                              "reached": 18
                            }
                          }
                        }
                      },
                      "verification_time_stats": {
                        "overall_avg_seconds": 64.0,
                        "overall_count": 18,
                        "per_feature": {
                          "OCR": {
                            "avg_seconds": 41.2,
                            "total_seconds": 741.6,
                            "count": 18
                          },
                          "LIVENESS": {
                            "avg_seconds": 22.8,
                            "total_seconds": 410.4,
                            "count": 18
                          }
                        },
                        "per_sub_step": {
                          "OCR": {
                            "front_id_photo": {
                              "avg_seconds": 18.3,
                              "total_seconds": 329.4,
                              "count": 18
                            }
                          }
                        }
                      },
                      "resubmission_stats": {
                        "first_pass": 17,
                        "second": 2,
                        "third_plus": 1,
                        "abandoned": 0
                      },
                      "warning_stats": {
                        "ID_VERIFICATION": {
                          "total": 21,
                          "risks": {
                            "DOCUMENT_EXPIRED": {
                              "error": 1,
                              "warning": 0,
                              "information": 0
                            }
                          }
                        },
                        "LIVENESS": {
                          "total": 19,
                          "risks": {
                            "LOW_LIVENESS_SCORE": {
                              "error": 0,
                              "warning": 2,
                              "information": 0
                            }
                          }
                        }
                      },
                      "original_status_stats": {
                        "approved": 13,
                        "in_review": 5,
                        "declined": 2
                      },
                      "demographic_time_series": [
                        {
                          "date": "2026-10-14",
                          "age_distribution": {
                            "under_18": 0,
                            "18_24": 3,
                            "25_34": 4,
                            "35_44": 2,
                            "45_64": 1,
                            "65_plus": 0
                          },
                          "gender_distribution": {
                            "M": 6,
                            "F": 4
                          }
                        },
                        {
                          "date": "2026-10-15",
                          "age_distribution": {
                            "under_18": 0,
                            "18_24": 2,
                            "25_34": 4,
                            "35_44": 2,
                            "45_64": 1,
                            "65_plus": 1
                          },
                          "gender_distribution": {
                            "M": 5,
                            "F": 5
                          }
                        }
                      ],
                      "device_time_series": [
                        {
                          "date": "2026-10-14",
                          "devices": {
                            "Apple": 7,
                            "Android": 5
                          },
                          "browsers": {
                            "Safari": 7,
                            "Chrome": 5
                          },
                          "operating_systems": {
                            "iOS": 7,
                            "Android": 5
                          }
                        },
                        {
                          "date": "2026-10-15",
                          "devices": {
                            "Apple": 5,
                            "Android": 5
                          },
                          "browsers": {
                            "Safari": 5,
                            "Chrome": 5
                          },
                          "operating_systems": {
                            "iOS": 5,
                            "Android": 5
                          }
                        }
                      ],
                      "verification_time_time_series": [
                        {
                          "date": "2026-10-14",
                          "overall_avg": 66.1,
                          "per_feature": {
                            "OCR": 42.0,
                            "LIVENESS": 24.1
                          }
                        },
                        {
                          "date": "2026-10-15",
                          "overall_avg": 61.5,
                          "per_feature": {
                            "OCR": 40.2,
                            "LIVENESS": 21.3
                          }
                        }
                      ],
                      "resubmission_time_series": [
                        {
                          "date": "2026-10-14",
                          "first_pass": 9,
                          "second": 1,
                          "third_plus": 0,
                          "abandoned": 0
                        },
                        {
                          "date": "2026-10-15",
                          "first_pass": 8,
                          "second": 1,
                          "third_plus": 1,
                          "abandoned": 0
                        }
                      ],
                      "original_status_time_series": [
                        {
                          "date": "2026-10-14",
                          "approved": 7,
                          "in_review": 3,
                          "declined": 1
                        },
                        {
                          "date": "2026-10-15",
                          "approved": 6,
                          "in_review": 2,
                          "declined": 1
                        }
                      ],
                      "previous_data_points": [
                        {
                          "rounded_date": "2026-10-12",
                          "total": 9,
                          "approved": 6,
                          "declined": 1,
                          "canceled": 1,
                          "pending": 1
                        },
                        {
                          "rounded_date": "2026-10-13",
                          "total": 11,
                          "approved": 7,
                          "declined": 2,
                          "canceled": 0,
                          "pending": 2
                        }
                      ],
                      "previous_request_breakdown": {
                        "total_approved": 13,
                        "total_in_review": 2,
                        "total_declined": 3,
                        "total_canceled": 1,
                        "total_pending": 3
                      }
                    }
                  },
                  "Transaction widgets": {
                    "value": {
                      "scope": "transactions",
                      "available_widget_keys": [
                        "tx_count_total",
                        "tx_count_daily",
                        "tx_volume_total_preferred_currency",
                        "tx_volume_daily_preferred_currency",
                        "tx_average_amount",
                        "tx_average_amount_daily",
                        "tx_transaction_category_breakdown",
                        "tx_action_type_breakdown",
                        "tx_status_volume_trend",
                        "tx_user_ip_or_country_distribution",
                        "tx_tag_breakdown",
                        "tx_top_rules_triggered",
                        "tx_team_member_performance",
                        "tx_score_histogram"
                      ],
                      "requested_widget_keys": [
                        "tx_count_total",
                        "tx_count_daily"
                      ],
                      "widgets": {
                        "tx_count_total": {
                          "kind": "metric",
                          "title": "Transaction count",
                          "value": 42
                        },
                        "tx_count_daily": {
                          "kind": "time_series",
                          "title": "Transaction count",
                          "items": [
                            {
                              "date": "2026-10-14",
                              "value": 20
                            },
                            {
                              "date": "2026-10-15",
                              "value": 22
                            }
                          ],
                          "previous_items": [
                            {
                              "date": "2026-10-12",
                              "value": 18
                            },
                            {
                              "date": "2026-10-13",
                              "value": 15
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "날짜 범위 또는 적용 범위가 유효하지 않습니다. 본문은 문제가 발생한 파라미터를 키로 하고 문자열 메시지를 값으로 갖는 객체입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  }
                },
                "examples": {
                  "Bad date format": {
                    "value": {
                      "start_date": "Invalid date format. Use YYYY-MM-DD (e.g., 2024-01-15)."
                    }
                  },
                  "Start after end": {
                    "value": {
                      "start_date": "Start date must be before or equal to end date."
                    }
                  },
                  "Range too long": {
                    "value": {
                      "date_range": "Date range cannot exceed 730 days (2 years)."
                    }
                  },
                  "Unknown scope": {
                    "value": {
                      "scope": "Unsupported analytics scope."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 만료일이 지정되어 생성된 키만 만료될 수 있으며, 해당 날짜 이후에는 이를 사용한 모든 요청에 `401`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. `detail`을 확인하십시오. API 키 누락(잘못되었거나 폐기되었거나 만료된 키는 `401` 수신), 다른 애플리케이션의 키, 모든 범위 지정 키 또는 키의 IP 목록 외부에서의 요청 등이 해당됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key": {
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "이 API 키로 분당 600건을 초과하는 GET 요청이 발생했습니다. `Retry-After`에 명시된 시간(초)만큼 대기한 후 다시 시도하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "현재 1분 기간이 초기화될 때까지 남은 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "이 예산에서 분당 허용되는 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "윈도우가 리셋되는 Unix 시간입니다.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/analytics/today/": {
      "get": {
        "summary": "오늘의 시간별 인증 건수 가져오기",
        "operationId": "get_application_analytics_today",
        "x-didit-sdk": {
          "resource": "analytics",
          "method": "retrieve_today",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Analytics"
        ],
        "description": "`tz`의 현지 자정부터 생성된 현지 시간별 오늘의 사용자 인증(KYC) 세션을 일주일 전 같은 요일의 동일한 시간대와 비교하여 집계하고, 현재 각 세션의 결과(승인됨, 검토 중, 거부됨)별로 분류합니다. 이는 Business Console 홈의 볼륨 카드입니다.\n\n`total`은 오늘 현재까지의 합계입니다. `previous_total_so_far`는 비교 대상 날짜를 동일한 현지 시간까지만 집계하므로 두 날짜의 동일한 시간 구간을 비교합니다. 오늘 아직 지나지 않은 시간대는 `0`입니다. 서머타임 등으로 인해 시간이 변경되는 날은 23시간 또는 25시간이 됩니다. 누락된 시간은 `0`으로 유지되고 반복되는 시간은 둘 다 포함합니다.",
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다.",
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다. API 키가 속한 애플리케이션이어야 합니다. 다른 애플리케이션에 사용된 키는 `403`을 받습니다.",
            "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "UTC",
              "example": "Europe/Madrid"
            },
            "description": "오늘이 시작되는 자정의 기준 IANA 표준 시간대(예: `Europe/Madrid` 또는 `America/Mexico_City`)입니다. UTC의 경우 생략합니다."
          }
        ],
        "responses": {
          "200": {
            "description": "현지 시간별 오늘의 인증 건수, 비교 대상 날짜의 인증 건수 및 오늘의 결과입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApplicationAnalyticsToday"
                },
                "examples": {
                  "Madrid, 14:00": {
                    "value": {
                      "time_zone": "Europe/Madrid",
                      "date": "2026-10-30",
                      "current_hour": 14,
                      "previous_date": "2026-10-23",
                      "hours": [
                        3,
                        1,
                        0,
                        0,
                        1,
                        2,
                        4,
                        9,
                        14,
                        18,
                        21,
                        19,
                        22,
                        24,
                        27,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0
                      ],
                      "previous_hours": [
                        2,
                        1,
                        1,
                        0,
                        1,
                        3,
                        5,
                        8,
                        12,
                        16,
                        19,
                        18,
                        20,
                        22,
                        24,
                        26,
                        23,
                        19,
                        15,
                        12,
                        9,
                        7,
                        5,
                        3
                      ],
                      "total": 165,
                      "previous_total_so_far": 151,
                      "outcomes": {
                        "approved": 139,
                        "in_review": 6,
                        "declined": 18
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "알 수 없는 표준시간대입니다. 본문은 메시지 목록과 함께 파라미터별로 구성됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Unknown time zone": {
                    "value": {
                      "tz": [
                        "Unknown time zone: Europe/Atlantis."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 만료일이 지정되어 생성된 키만 만료될 수 있으며, 해당 날짜 이후에는 이를 사용한 모든 요청에 `401`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. `detail`을 확인하십시오. 누락되었거나 유효하지 않은 API 키(`401`이 반환되지 않음), 다른 애플리케이션의 키, 모든 범위 지정 키 또는 키의 IP 목록 외부에서의 요청 등이 해당됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key": {
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "이 API 키로 분당 600건을 초과하는 GET 요청이 발생했습니다. `Retry-After`에 명시된 시간(초)만큼 대기한 후 다시 시도하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "현재 1분 기간이 초기화될 때까지 남은 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "이 예산에서 분당 허용되는 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "윈도우가 리셋되는 Unix 시간입니다.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/analytics/today/?tz=Europe%2FMadrid' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/webhooks/": {
      "get": {
        "summary": "세션 webhook 전송 목록 조회",
        "description": "하나의 사용자(KYC) 또는 기업(KYB) 인증 세션에 대해 Didit이 기록한 모든 webhook 전송 내역을 최신순으로 일반 JSON 배열(페이지네이션 없음)로 조회합니다. 각 항목은 하나의 대상에 대한 한 번의 시도를 나타냅니다. 최초 전송, 각 자동 [재시도](https://docs.didit.me/ko/integration/webhooks#재시도-정책) 및 각 재전송은 고유한 `uuid`를 가진 별도의 항목이며, 재시도 및 재전송 시에도 payload의 `event_id`는 유지됩니다. `request_header`와 `request_body`는 JSON 텍스트이므로 서명과 payload를 읽으려면 이를 파싱하십시오. 전송 기록은 약 30일 동안 보관되므로, 빈 배열은 해당 세션에 대해 아직 webhook이 전송되지 않았거나 모든 전송 내역이 30일보다 오래되었음을 의미합니다. 스코프가 지정된 API 키에는 `sessions: read` 및 `decisions: read` 권한이 필요합니다.",
        "operationId": "get_v3_session_webhooks",
        "x-didit-sdk": {
          "resource": "sessions.webhooks",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "사용자(KYC) 또는 기업(KYB) 인증 세션의 UUID(`POST /v3/session/`에서 반환된 `session_id`)입니다. 서버는 두 세션 유형에 대해 이를 확인합니다.\n\n**유효한 UUID여야 합니다.** 라우트는 올바른 형식의 UUID만 일치시키므로, 잘못된 형식의 값은 애플리케이션 코드가 실행되기 전에 URL 라우터에 의해 거부되어 아래에 표시된 JSON `{\"detail\": ...}` 응답 형식 대신 `404` **HTML** 페이지가 반환됩니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "22222222-3333-4444-5555-666666666666"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/22222222-3333-4444-5555-666666666666/webhooks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.webhooks.list(\n    \"22222222-3333-4444-5555-666666666666\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.webhooks.list(\"22222222-3333-4444-5555-666666666666\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Webhooks.List(ctx, \"22222222-3333-4444-5555-666666666666\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().webhooks().list(\"22222222-3333-4444-5555-666666666666\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->webhooks->list('22222222-3333-4444-5555-666666666666');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.webhooks.list(\"22222222-3333-4444-5555-666666666666\").each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Webhooks.ListAsync(\"22222222-3333-4444-5555-666666666666\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "세션에 기록된 모든 전송 내역(최신순)입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SessionWebhookDelivery"
                  }
                },
                "examples": {
                  "Failed delivery and its successful retry": {
                    "value": [
                      {
                        "uuid": "66666666-7777-8888-9999-000000000002",
                        "session_id": "22222222-3333-4444-5555-666666666666",
                        "request_url": "https://yourapp.com/webhooks/didit",
                        "response_status": 200,
                        "status": "In Progress",
                        "webhook_type": "status.updated",
                        "request_header": "{\"Content-Type\": \"application/json\", \"X-Signature\": \"9188851d160b5b3aacfc946e4dde1f061b7e568662518942c927ddaf507f533d\", \"X-Signature-V2\": \"381236af514d3fb538579365ac5a24f2464ce1b8224c6e770c60d8201c43ecc5\", \"X-Signature-Simple\": \"4740131dc38f29e78a8508371979be74967d5307464494bd3148a03b4d6c8716\", \"X-Timestamp\": \"1792056139\", \"User-Agent\": \"DiditWebhook/2.0 +https://didit.me\"}",
                        "request_body": "{\"application_id\":\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\"created_at\":1792056057,\"environment\":\"live\",\"event_id\":\"33333333-4444-5555-6666-777777777777\",\"sandbox_scenario\":null,\"session_id\":\"22222222-3333-4444-5555-666666666666\",\"status\":\"In Progress\",\"timestamp\":1792056139,\"vendor_data\":\"user-123\",\"webhook_type\":\"status.updated\",\"workflow_id\":\"44444444-5555-6666-7777-888888888888\",\"workflow_version\":3}",
                        "created_at": "2026-10-15T09:22:19.104233Z"
                      },
                      {
                        "uuid": "66666666-7777-8888-9999-000000000001",
                        "session_id": "22222222-3333-4444-5555-666666666666",
                        "request_url": "https://yourapp.com/webhooks/didit",
                        "response_status": 503,
                        "status": "In Progress",
                        "webhook_type": "status.updated",
                        "request_header": "{\"Content-Type\": \"application/json\", \"X-Signature\": \"a5e02a03404e1337a0198e6be15d34abbd053c658a0e51e5d0e78554213ef29b\", \"X-Signature-V2\": \"927e7cb770c94ce745939bff73f04aa200015f3bc64795ba46c2aaf78a6cedc5\", \"X-Signature-Simple\": \"e37b0d4c716c72bb5ae7127b9cc455d28ab4686e9e22312b4ec2327409a73302\", \"X-Timestamp\": \"1792056078\", \"User-Agent\": \"DiditWebhook/2.0 +https://didit.me\"}",
                        "request_body": "{\"application_id\":\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\"created_at\":1792056057,\"environment\":\"live\",\"event_id\":\"33333333-4444-5555-6666-777777777777\",\"sandbox_scenario\":null,\"session_id\":\"22222222-3333-4444-5555-666666666666\",\"status\":\"In Progress\",\"timestamp\":1792056078,\"vendor_data\":\"user-123\",\"webhook_type\":\"status.updated\",\"workflow_id\":\"44444444-5555-6666-7777-888888888888\",\"workflow_version\":3}",
                        "created_at": "2026-10-15T09:21:18.412345Z"
                      }
                    ]
                  },
                  "No webhook sent yet": {
                    "value": []
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 생성 시 설정된 만료일이 지났습니다. 잘못되었거나 취소된 키도 `401`을 수신하며, 누락된 키는 `403`을 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. `x-api-key`가 없거나 유효하지 않거나 폐기된 키는 `Authentication credentials were not provided or are invalid.`를 수신합니다. 다른 애플리케이션의 키는 `You do not have permission to perform this action.`을 수신합니다. 이 endpoint에 필요한 접근 권한이 없는 범위 지정 키는 누락된 권한을 명시하는 메시지를 수신하며, IP 허용 목록 외부에서 사용된 키는 `This API key can't be used from this IP address.`를 수신합니다. 알 수 없는 `sessionId`는 자격 증명을 확인하기 전에 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Key of another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without sessions read": {
                    "value": {
                      "detail": "This API key has no read access to sessions."
                    }
                  },
                  "Scoped key without decisions read": {
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나 삭제되었거나(자격 증명을 확인하기 전에 `Not found.` 반환), 범위가 지정된 키의 워크플로 또는 상태 제한 범위를 벗어났습니다(`Session not found.`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside the key's limits": {
                    "value": {
                      "detail": "Session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: 이 API 키의 현재 1분 시간 창에서 600개를 초과하는 GET 요청이 발생했습니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요.",
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "1분 동안 허용되는 요청 수(600)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "현재 윈도우가 리셋되는 Unix 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "초과된 예산의 이름입니다.",
                "schema": {
                  "type": "string",
                  "example": "generic-get"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/webhook/{webhook_uuid}": {
      "get": {
        "summary": "세션 webhook 전송 내역 가져오기",
        "description": "인증 세션의 단일 webhook 전송을 조회합니다: 전송된 대상 URL, endpoint가 반환한 HTTP 상태, Didit이 전송한 정확한 헤더 및 JSON 본문이 포함됩니다. `request_header` 및 `request_body`는 JSON 텍스트입니다. [서명 검증](https://docs.didit.me/ko/integration/webhooks#서명-검증)을 확인하려면 전송 대상의 비밀(또는 레거시 webhook URL로 전송된 경우 애플리케이션 수준 비밀)을 사용하여 파싱된 본문에서 `X-Signature-V2`를 다시 계산하십시오. 경로 끝에 후행 슬래시가 없어야 합니다. 슬래시가 있으면 `404`가 반환됩니다. 범위가 지정된 API 키에는 `sessions: read` 및 `decisions: read` 권한이 필요합니다.",
        "operationId": "get_v3_session_webhook",
        "x-didit-sdk": {
          "resource": "sessions.webhooks",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "사용자(KYC) 또는 기업(KYB) 인증 세션의 UUID(`POST /v3/session/`에서 반환된 `session_id`)입니다. 서버는 두 세션 유형에 대해 이를 확인합니다.\n\n**유효한 UUID여야 합니다.** 라우트는 올바른 형식의 UUID만 일치시키므로, 잘못된 형식의 값은 애플리케이션 코드가 실행되기 전에 URL 라우터에 의해 거부되어 아래에 표시된 JSON `{\"detail\": ...}` 응답 형식 대신 `404` **HTML** 페이지가 반환됩니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "22222222-3333-4444-5555-666666666666"
          },
          {
            "name": "webhook_uuid",
            "in": "path",
            "required": true,
            "description": "전송의 UUID입니다(`GET /v3/session/{sessionId}/webhooks/`에서 반환된 항목의 `uuid`). 경로의 세션에 속해 있어야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "66666666-7777-8888-9999-000000000001"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/22222222-3333-4444-5555-666666666666/webhook/66666666-7777-8888-9999-000000000001' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.webhooks.retrieve(\n    \"22222222-3333-4444-5555-666666666666\",\n    \"66666666-7777-8888-9999-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.webhooks.retrieve(\n  \"22222222-3333-4444-5555-666666666666\",\n  \"66666666-7777-8888-9999-000000000001\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Webhooks.Retrieve(ctx, \"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().webhooks().retrieve(\"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->webhooks->retrieve('22222222-3333-4444-5555-666666666666', '66666666-7777-8888-9999-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.webhooks.retrieve(\n  \"22222222-3333-4444-5555-666666666666\",\n  \"66666666-7777-8888-9999-000000000001\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Webhooks.RetrieveAsync(\"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "요청 헤더 및 본문이 포함된 전송입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionWebhookDelivery"
                },
                "examples": {
                  "Connection failure": {
                    "value": {
                      "uuid": "66666666-7777-8888-9999-000000000001",
                      "session_id": "22222222-3333-4444-5555-666666666666",
                      "request_url": "https://yourapp.com/webhooks/didit",
                      "response_status": 503,
                      "status": "In Progress",
                      "webhook_type": "status.updated",
                      "request_header": "{\"Content-Type\": \"application/json\", \"X-Signature\": \"a5e02a03404e1337a0198e6be15d34abbd053c658a0e51e5d0e78554213ef29b\", \"X-Signature-V2\": \"927e7cb770c94ce745939bff73f04aa200015f3bc64795ba46c2aaf78a6cedc5\", \"X-Signature-Simple\": \"e37b0d4c716c72bb5ae7127b9cc455d28ab4686e9e22312b4ec2327409a73302\", \"X-Timestamp\": \"1792056078\", \"User-Agent\": \"DiditWebhook/2.0 +https://didit.me\"}",
                      "request_body": "{\"application_id\":\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\"created_at\":1792056057,\"environment\":\"live\",\"event_id\":\"33333333-4444-5555-6666-777777777777\",\"sandbox_scenario\":null,\"session_id\":\"22222222-3333-4444-5555-666666666666\",\"status\":\"In Progress\",\"timestamp\":1792056078,\"vendor_data\":\"user-123\",\"webhook_type\":\"status.updated\",\"workflow_id\":\"44444444-5555-6666-7777-888888888888\",\"workflow_version\":3}",
                      "created_at": "2026-10-15T09:21:18.412345Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 생성 시 설정된 만료일이 지났습니다. 잘못되었거나 취소된 키도 `401`을 수신하며, 누락된 키는 `403`을 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. `x-api-key`가 없거나 유효하지 않거나 폐기된 키는 `Authentication credentials were not provided or are invalid.`를 수신합니다. 다른 애플리케이션의 키는 `You do not have permission to perform this action.`을 수신합니다. 이 endpoint에 필요한 접근 권한이 없는 범위 지정 키는 누락된 권한을 명시하는 메시지를 수신하며, IP 허용 목록 외부에서 사용된 키는 `This API key can't be used from this IP address.`를 수신합니다. 알 수 없는 `sessionId`는 자격 증명을 확인하기 전에 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Key of another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without sessions read": {
                    "value": {
                      "detail": "This API key has no read access to sessions."
                    }
                  },
                  "Scoped key without decisions read": {
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나 삭제되었거나(자격 증명을 확인하기 전에 `Not found.` 반환), 범위가 지정된 키의 워크플로 또는 상태 제한 범위를 벗어났습니다(`Session not found.`). 존재하지 않거나 다른 세션에 속해 있거나 더 이상 사용할 수 없는 전송의 경우 `No WebhookLog matches the given query.`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside the key's limits": {
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "Delivery not in this session": {
                    "value": {
                      "detail": "No WebhookLog matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: 이 API 키의 현재 1분 시간 창에서 600개를 초과하는 GET 요청이 발생했습니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요.",
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "1분 동안 허용되는 요청 수(600)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "현재 윈도우가 리셋되는 Unix 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "초과된 예산의 이름입니다.",
                "schema": {
                  "type": "string",
                  "example": "generic-get"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/webhook/{webhook_uuid}/resend": {
      "post": {
        "summary": "세션 webhook 전송 재전송",
        "description": "기록된 세션 webhook을 처음에 전송되었던 URL로 다시 전송합니다. 동일한 payload와 `event_id`, 그리고 새로운 `timestamp`, `X-Timestamp` 헤더 및 서명이 포함됩니다. Didit은 전송이 속한 대상의 현재 비밀(또는 레거시 webhook URL로의 전송인 경우 애플리케이션 수준 비밀)로 서명하고, 귀하의 endpoint를 최대 5초 동안 대기하며, 시도를 새 전송으로 기록하고 귀하의 endpoint가 응답한 내용과 관계없이 `200`으로 반환합니다. `response_status`를 확인하십시오. 재전송은 자동으로 재시도되지 않으며 모든 호출은 다시 전송되므로 endpoint가 `event_id`에 대해 멱등성을 갖도록 만드십시오. 경로에는 후행 슬래시가 없으며 요청에는 본문이 없습니다. 범위가 지정된 API 키에는 `webhooks: write` 및 `decisions: read`가 필요합니다.",
        "operationId": "post_v3_session_webhook_resend",
        "x-didit-sdk": {
          "resource": "sessions.webhooks",
          "method": "resend",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "사용자(KYC) 또는 기업(KYB) 인증 세션의 UUID(`POST /v3/session/`에서 반환된 `session_id`)입니다. 서버는 두 세션 유형에 대해 이를 확인합니다.\n\n**유효한 UUID여야 합니다.** 라우트는 올바른 형식의 UUID만 일치시키므로, 잘못된 형식의 값은 애플리케이션 코드가 실행되기 전에 URL 라우터에 의해 거부되어 아래에 표시된 JSON `{\"detail\": ...}` 응답 형식 대신 `404` **HTML** 페이지가 반환됩니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "22222222-3333-4444-5555-666666666666"
          },
          {
            "name": "webhook_uuid",
            "in": "path",
            "required": true,
            "description": "다시 전송할 전송의 UUID입니다(`GET /v3/session/{sessionId}/webhooks/`에서 반환된 항목의 `uuid`). 경로의 세션에 속해 있어야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "66666666-7777-8888-9999-000000000001"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/session/22222222-3333-4444-5555-666666666666/webhook/66666666-7777-8888-9999-000000000001/resend' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.webhooks.resend(\n    \"22222222-3333-4444-5555-666666666666\",\n    \"66666666-7777-8888-9999-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.webhooks.resend(\n  \"22222222-3333-4444-5555-666666666666\",\n  \"66666666-7777-8888-9999-000000000001\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Webhooks.Resend(ctx, \"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().webhooks().resend(\"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->webhooks->resend('22222222-3333-4444-5555-666666666666', '66666666-7777-8888-9999-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.webhooks.resend(\n  \"22222222-3333-4444-5555-666666666666\",\n  \"66666666-7777-8888-9999-000000000001\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Webhooks.ResendAsync(\"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "이미 시도된 새 전송입니다. `response_status`는 이번에 endpoint가 반환한 내용입니다. 원래 전송은 변경되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionWebhookDelivery"
                },
                "examples": {
                  "Accepted on resend": {
                    "value": {
                      "uuid": "66666666-7777-8888-9999-000000000004",
                      "session_id": "22222222-3333-4444-5555-666666666666",
                      "request_url": "https://yourapp.com/webhooks/didit",
                      "response_status": 200,
                      "status": "In Progress",
                      "webhook_type": "status.updated",
                      "request_header": "{\"Content-Type\": \"application/json\", \"X-Signature\": \"b8eb1e376517ee0cad8ba98ff7f8fd35fc72eca231000963a96a335f82328835\", \"X-Signature-V2\": \"9efd2ce9ed1303e1d05273ef9608a59363ed9789a05253db4748b3e8e50cb109\", \"X-Signature-Simple\": \"bf3a9dc04b2c20ab539203b0cd5cca2a10f630bf62d8feb6d68d82af80f64774\", \"X-Timestamp\": \"1792159542\", \"User-Agent\": \"DiditWebhook/2.0 +https://didit.me\"}",
                      "request_body": "{\"application_id\":\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\"created_at\":1792056057,\"environment\":\"live\",\"event_id\":\"33333333-4444-5555-6666-777777777777\",\"sandbox_scenario\":null,\"session_id\":\"22222222-3333-4444-5555-666666666666\",\"status\":\"In Progress\",\"timestamp\":1792159542,\"vendor_data\":\"user-123\",\"webhook_type\":\"status.updated\",\"workflow_id\":\"44444444-5555-6666-7777-888888888888\",\"workflow_version\":3}",
                      "created_at": "2026-10-16T14:05:42.330981Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "전송을 재전송할 수 없습니다. `code`에 따라 분기합니다. `webhook_url_missing`은 전송에 기록된 URL이 없어 아무것도 전송되지 않음을 의미하고, `webhook_resend_error`는 저장된 전송에 다시 서명할 수 없거나 시도를 완료할 수 없음을 의미합니다. `webhook_resend_error`가 발생하면 `detail`은 `Error processing webhook resend:`로 시작하며 그 뒤에 변경될 수 있는 진단 텍스트가 이어집니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    },
                    "code": {
                      "type": "string",
                      "description": "기계 판독 가능한 고정 오류 코드입니다. `detail`이 아닌 이 값을 기준으로 분기 처리하십시오."
                    }
                  }
                },
                "examples": {
                  "No recorded URL": {
                    "value": {
                      "detail": "The webhook delivery does not have a request URL configured",
                      "code": "webhook_url_missing"
                    }
                  },
                  "Resend failed": {
                    "value": {
                      "detail": "Error processing webhook resend: Invalid webhook data format",
                      "code": "webhook_resend_error"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 만료되었습니다. 생성 시 설정된 만료일이 지났습니다. 잘못되었거나 취소된 키도 `401`을 수신하며, 누락된 키는 `403`을 수신합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "요청이 허용되지 않습니다. `x-api-key`가 없거나 유효하지 않거나 폐기된 키는 `Authentication credentials were not provided or are invalid.`를 수신합니다. 다른 애플리케이션의 키는 `You do not have permission to perform this action.`을 수신합니다. 이 endpoint에 필요한 접근 권한이 없는 범위 지정 키는 누락된 권한을 명시하는 메시지를 수신하며, IP 허용 목록 외부에서 사용된 키는 `This API key can't be used from this IP address.`를 수신합니다. 알 수 없는 `sessionId`는 자격 증명을 확인하기 전에 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Key of another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks write": {
                    "value": {
                      "detail": "This API key has no write access to webhooks."
                    }
                  },
                  "Scoped key without decisions read": {
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나 삭제되었거나(자격 증명을 확인하기 전에 `Not found.` 반환), 범위가 지정된 키의 워크플로 또는 상태 제한 범위를 벗어났습니다(`Session not found.`). 존재하지 않거나 다른 세션에 속해 있거나 더 이상 사용할 수 없는 전송의 경우 `Webhook log not found`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside the key's limits": {
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "Delivery not in this session": {
                    "value": {
                      "detail": "Webhook log not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: 이 API 키의 현재 1분 시간 창에서 300개를 초과하는 쓰기 요청(POST, PATCH, PUT, DELETE)이 발생했습니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요.",
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "1분 동안 허용되는 요청 수(300)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "현재 윈도우에 남은 요청 수입니다.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "현재 윈도우가 리셋되는 Unix 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "초과된 예산의 이름입니다.",
                "schema": {
                  "type": "string",
                  "example": "generic-write"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/events/": {
      "get": {
        "summary": "세션 이벤트 목록 조회",
        "description": "단일 인증 세션의 이벤트 타임라인을 `sent_at` 기준 최신순으로 조회합니다. 사용자가 본 화면, 버튼 및 업로드, 실패한 시도, 상태 및 기능 단계 변경 사항, 워크플로 라우팅 추적이 포함됩니다. 사용자 인증(KYC) 및 기업 확인(KYB) 세션 ID 모두 지원됩니다. 이벤트는 비동기적으로 저장되므로 새 이벤트가 표시되는 데 몇 초 정도 걸릴 수 있습니다. 결과는 `limit` 및 `offset`으로 페이지네이션되며, `next`가 `null`이 될 때까지 따라가면 됩니다. 범위가 지정된 API 키에는 `sessions: read` 및 `decisions: read` 권한이 필요하며, `media: read` 권한이 없으면 `file_url`이 `null`로 반환됩니다. 라우팅 이벤트에 대한 설명은 [세션 조회](https://docs.didit.me/ko/sessions-api/retrieve-session)에서 확인할 수 있습니다.",
        "operationId": "get_v3_session_events",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list_events",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "인증 세션의 UUID(`POST /v3/session/`에서 반환된 `session_id`)입니다. 사용자 인증(KYC) 및 기업 확인(KYB) 세션 ID를 모두 지원하며, 서버는 두 세션 유형 전체에서 ID를 확인합니다. 올바른 형식의 UUID여야 합니다. 형식이 잘못된 값은 경로와 일치하지 않아 HTML `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "페이지당 최대 이벤트 수입니다. 기본값은 50입니다. 1 미만의 값이나 숫자가 아닌 값은 50으로 대체되며, 1,000,000을 초과하는 값은 `400`을 반환합니다.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000,
              "example": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "반환되는 첫 번째 결과 전에 건너뛸 결과 수입니다. 기본값은 0입니다. 음수 또는 숫자가 아닌 값은 0으로 대체되며, 1,000,000을 초과하는 값은 `400`을 반환합니다. `next` 및 `previous` URL을 따르는 것을 권장합니다.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000,
              "example": 0
            }
          },
          {
            "name": "ordering",
            "in": "query",
            "required": false,
            "description": "선택 사항인 정렬 재정의입니다. 기본 순서는 `-sent_at`입니다. 오름차순으로 정렬하려면 결과 필드 이름(예: `sent_at`, `created_at`, `event_type`, `feature_step` 또는 `step`)을 전달하고, 내림차순으로 정렬하려면 앞에 `-`를 붙이며, 여러 필드는 쉼표로 구분합니다. 알 수 없는 필드는 무시됩니다.",
            "schema": {
              "type": "string",
              "example": "sent_at"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/events/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.list_events(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.listEvents(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.ListEventsAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsListEventsParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().listEvents(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->sessions->listEvents('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.list_events(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.ListEventsAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "최신순으로 정렬된 세션 이벤트 페이지 하나입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "해당 세션의 총 이벤트 수입니다."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "다음 페이지의 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "이전 페이지의 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SessionEvent"
                      }
                    }
                  }
                },
                "examples": {
                  "Completed session": {
                    "value": {
                      "count": 3,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "aaaaaaaa-1111-2222-3333-444444444444",
                          "event_type": "SESSION_STATUS_CHANGED",
                          "created_at": "2026-09-14T10:02:13.904512Z",
                          "component": null,
                          "feature_step": null,
                          "step": null,
                          "details": {
                            "old_status": "In Progress",
                            "current_status": "Approved"
                          },
                          "ip_address": null,
                          "user_agent": null,
                          "device_info": null,
                          "file_url": null,
                          "sent_at": 1789380131482
                        },
                        {
                          "uuid": "bbbbbbbb-1111-2222-3333-444444444444",
                          "event_type": "FEATURE_STEP_CHANGED",
                          "created_at": "2026-09-14T10:01:49.210377Z",
                          "component": null,
                          "feature_step": null,
                          "step": null,
                          "details": {
                            "old_feature_step": "OCR",
                            "current_feature_step": "LIVENESS"
                          },
                          "ip_address": null,
                          "user_agent": null,
                          "device_info": null,
                          "file_url": null,
                          "sent_at": 1789380107103
                        },
                        {
                          "uuid": "cccccccc-1111-2222-3333-444444444444",
                          "event_type": "STEP_RENDERED",
                          "created_at": "2026-09-14T10:01:00.581930Z",
                          "component": "DocumentCapture",
                          "feature_step": "OCR",
                          "step": "DOCUMENT_CAPTURE_FRONT",
                          "details": {},
                          "ip_address": "203.0.113.24",
                          "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.5 Mobile/15E148 Safari/604.1",
                          "device_info": {
                            "device_model": "iPhone"
                          },
                          "file_url": null,
                          "sent_at": 1789380058776
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`limit` 또는 `offset`이 1,000,000을 초과합니다. 본문은 메시지 1개가 포함된 JSON 배열입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Limit too large": {
                    "summary": "limit=2000000",
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  },
                  "Offset too large": {
                    "summary": "offset=2000000",
                    "value": [
                      "offset must not exceed 1000000."
                    ]
                  }
                },
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without sessions read": {
                    "summary": "스코프 지정 키에 sessions: read 권한이 없음",
                    "value": {
                      "detail": "This API key has no read access to sessions."
                    }
                  },
                  "Scoped key without decisions read": {
                    "summary": "스코프 지정 키에 decisions: read 권한이 없음",
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나, 삭제되었거나, 범위가 지정된 키의 워크플로 또는 승인 전용 제한 범위를 벗어났습니다. 세션 조회가 자격 증명 확인보다 먼저 실행되므로, 유효한 키가 없더라도 알 수 없는 `sessionId`에 대해 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "이 ID를 가진 세션이 존재하지 않거나 삭제되었습니다",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "세션이 범위가 지정된 키의 워크플로 또는 승인 전용 제한 범위를 벗어났습니다",
                    "value": {
                      "detail": "Session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: API 키당 분당 600개의 GET 요청. 재시도하기 전에 `Retry-After`초 동안 대기하세요. `X-RateLimit-*` 헤더에 남은 한도가 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "현재 분에 할당된 예산이 소진되었습니다",
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/aml-screening-history/": {
      "get": {
        "summary": "AML 스크리닝 이력 조회",
        "description": "세션의 AML 검사에서 완료된 모든 지속적인 모니터링 재스크리닝 목록을 `completed_at` 기준 최신순으로 조회합니다. 변경 사항이 없는 실행 건도 포함됩니다. 알림, 활동 항목, webhook은 결과가 변경될 때만 트리거되므로, 이 기록은 이상이 없는 대상자도 계속 스크리닝되고 있었음을 증명하는 증거가 됩니다. KYC 및 KYB 세션 ID에 대해 작동하며, 세션에서 둘 이상의 AML 단계를 실행한 경우 `node_id`를 전달하십시오. 지속적인 모니터링 재스크리닝만 나열되며(최초 스크리닝은 세션 결정의 일부임), 이 기록이 존재하기 전의 실행 건은 재구성되지 않으므로 지속적인 모니터링이 없는 세션은 빈 목록을 반환합니다. `count`는 최대 100까지 정확하며 그 이상은 100으로 제한되므로 `null`이 될 때까지 `next`를 따르십시오. 한 번에 한 달(달력 기준) 단위로 조회하려면 `month`를 전달하십시오. 스코프가 지정된 API 키에는 `decisions: read` 권한이 필요합니다. [지속적인 AML 모니터링](https://docs.didit.me/ko/core-technology/aml-screening/continuous-monitoring-aml-screening)을 참고하십시오.",
        "operationId": "get_v3_session_aml_screening_history",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list_aml_screening_history",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "인증 세션의 UUID(`POST /v3/session/`에서 반환된 `session_id`)입니다. 사용자 인증(KYC) 및 기업 확인(KYB) 세션 ID를 모두 지원하며, 서버는 두 세션 유형 전체에서 ID를 확인합니다. 올바른 형식의 UUID여야 합니다. 형식이 잘못된 값은 경로와 일치하지 않아 HTML `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "AML 확인의 워크플로 그래프 노드 ID입니다. 세션에서 둘 이상의 AML 단계를 실행한 경우에만 필요하며, 지정하지 않으면 가장 최근의 AML 확인이 사용됩니다. 알 수 없는 노드는 `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "example": "feature_aml_1"
            }
          },
          {
            "name": "month",
            "in": "query",
            "required": false,
            "description": "`YYYY-MM` 형식의 UTC 달력 월입니다. 해당 월에 완료된 스크리닝만 반환됩니다. 지정하지 않으면 모든 월이 반환됩니다. 형식이 잘못된 월은 `400`을 반환합니다.",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-(0[1-9]|1[0-2])$",
              "example": "2026-09"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "페이지당 최대 스크리닝 실행 수입니다. 기본값은 50입니다. 1 미만의 값이나 숫자가 아닌 값은 50으로 대체되며, 1,000,000을 초과하는 값은 `400`을 반환합니다.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000,
              "example": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "반환되는 첫 번째 결과 전에 건너뛸 결과 수입니다. 기본값은 0입니다. 음수 또는 숫자가 아닌 값은 0으로 대체되며, 1,000,000을 초과하는 값은 `400`을 반환합니다. `next` 및 `previous` URL을 따르는 것을 권장합니다.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000,
              "example": 0
            }
          },
          {
            "name": "ordering",
            "in": "query",
            "required": false,
            "description": "선택 사항인 정렬 재정의입니다. 기본 순서는 `-completed_at`입니다. 오름차순으로 정렬하려면 결과 필드 이름(예: `completed_at`, `started_at`, `outcome` 또는 `score`)을 전달하고, 내림차순으로 정렬하려면 앞에 `-`를 붙이며, 여러 필드는 쉼표로 구분합니다. 알 수 없는 필드는 무시됩니다.",
            "schema": {
              "type": "string",
              "example": "completed_at"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/aml-screening-history/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.list_aml_screening_history(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.listAmlScreeningHistory(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.ListAMLScreeningHistoryAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsListAMLScreeningHistoryParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().listAmlScreeningHistory(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->sessions->listAmlScreeningHistory('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.list_aml_screening_history(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.ListAmlScreeningHistoryAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "최신순으로 정렬된 스크리닝 실행 페이지 하나입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "maximum": 100,
                      "description": "실행 횟수로, 최대 100회까지는 정확하며 100회를 초과하면 100으로 제한됩니다."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "다음 페이지의 URL이며, 마지막 페이지에서는 `null`입니다."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "이전 페이지의 URL이며, 첫 번째 페이지에서는 `null`입니다."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AMLScreeningRun"
                      }
                    }
                  }
                },
                "examples": {
                  "Monitored subject": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "dddddddd-1111-2222-3333-444444444444",
                          "run_id": "aaaaaaaa-1111-2222-3333-444444444444",
                          "completed_at": "2026-09-14T04:12:33.481207Z",
                          "started_at": "2026-09-14T04:00:01.002311Z",
                          "outcome": "NO_CHANGE",
                          "trigger": "ONGOING_MONITORING",
                          "provider": "aml_data_source",
                          "status": "Approved",
                          "score": 0.0,
                          "total_hits": 0,
                          "new_hits": 0,
                          "entities_screened": 1,
                          "dataset_freshness": {
                            "captured_at": "2026-09-14T03:58:02.114820+00:00",
                            "provider": "aml_data_source",
                            "catalog_version": "2026-09-13",
                            "sources": {
                              "sanctions": {
                                "last_updated_at": "2026-09-13T21:10:00+00:00",
                                "oldest_updated_at": "2026-09-11T06:00:00+00:00",
                                "dataset_count": 120,
                                "dated_dataset_count": 120
                              },
                              "pep": {
                                "last_updated_at": "2026-09-13T08:00:00+00:00",
                                "oldest_updated_at": null,
                                "dataset_count": 45,
                                "dated_dataset_count": 44
                              },
                              "warnings": {
                                "last_updated_at": "2026-09-12T18:45:00+00:00",
                                "oldest_updated_at": "2026-09-01T00:00:00+00:00",
                                "dataset_count": 30,
                                "dated_dataset_count": 30
                              }
                            }
                          }
                        },
                        {
                          "uuid": "eeeeeeee-1111-2222-3333-444444444444",
                          "run_id": "bbbbbbbb-1111-2222-3333-444444444444",
                          "completed_at": "2026-09-13T04:11:58.020914Z",
                          "started_at": "2026-09-13T04:00:00.871022Z",
                          "outcome": "FAILED",
                          "trigger": "ONGOING_MONITORING",
                          "provider": "aml_data_source",
                          "status": "Approved",
                          "score": 0.0,
                          "total_hits": 0,
                          "new_hits": null,
                          "entities_screened": 0,
                          "dataset_freshness": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`limit` 또는 `offset`이 1,000,000을 초과하거나(메시지 1개가 포함된 JSON 배열), `month`가 `YYYY-MM` 달력 월이 아닙니다(`month`를 키로 하는 객체).",
            "content": {
              "application/json": {
                "examples": {
                  "Limit too large": {
                    "summary": "limit=2000000",
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  },
                  "Offset too large": {
                    "summary": "offset=2000000",
                    "value": [
                      "offset must not exceed 1000000."
                    ]
                  },
                  "Malformed month": {
                    "summary": "month=2026-13",
                    "value": {
                      "month": [
                        "Not a calendar month. Use YYYY-MM."
                      ]
                    }
                  }
                },
                "schema": {
                  "oneOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "month": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions read": {
                    "summary": "스코프 지정 키에 decisions: read 권한이 없음",
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나, 삭제되었거나, 범위가 지정된 키의 제한 범위를 벗어났거나, (해당 `node_id`에 대한) AML 검사가 없습니다. 세션 조회가 자격 증명 확인보다 먼저 실행되므로, 유효한 키가 없더라도 알 수 없는 `sessionId`에 대해 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "이 ID를 가진 세션이 존재하지 않거나 삭제되었습니다",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "세션이 범위가 지정된 키의 제한 범위를 벗어났습니다(방금 삭제된 세션에 대해서도 반환됨)",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "No AML check": {
                    "summary": "세션에서 AML 단계를 실행한 적이 없습니다",
                    "value": {
                      "detail": "The session does not have an AML check."
                    }
                  },
                  "No AML check for node": {
                    "summary": "node_id가 세션의 AML 검사와 일치하지 않음",
                    "value": {
                      "detail": "The session does not have an AML check for node 'feature_aml_2'."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: API 키당 분당 600개의 GET 요청. 재시도하기 전에 `Retry-After`초 동안 대기하세요. `X-RateLimit-*` 헤더에 남은 한도가 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "현재 분에 할당된 예산이 소진되었습니다",
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/aml-screening-history/export/": {
      "get": {
        "summary": "AML 스크리닝 내역을 CSV로 내보내기",
        "description": "`GET /v3/session/{sessionId}/aml-screening-history/`와 동일한 지속적인 모니터링 이력을 CSV 파일로 다운로드합니다. 완료된 재스크리닝당 한 줄씩 최신순으로 정렬되어 감사자에게 즉시 제출할 수 있습니다. 파일은 페이지네이션 없이 전체가 스트리밍되며 헤더 줄로 시작합니다. 빈 셀은 알 수 없음을 의미하고, 데이터 세트 날짜는 추정되지 않으며, 스프레드시트 수식을 시작할 수 있는 값 앞에는 아포스트로피가 붙습니다. KYC 및 KYB 세션 ID에 모두 작동합니다. 세션에서 둘 이상의 AML 단계를 실행한 경우 `node_id`를 전달하세요. 1개 역월을 내보내려면 `month`를 전달하세요. 오류는 CSV가 아닌 JSON으로 반환됩니다. 범위가 지정된 API 키에는 `decisions: read` 및 `media: read`가 필요합니다. 응답이 파일이므로 `media: read`가 없는 키는 `403`을 받습니다.",
        "operationId": "get_v3_session_aml_screening_history_export",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "export_aml_screening_history",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "인증 세션의 UUID(`POST /v3/session/`에서 반환된 `session_id`)입니다. 사용자 인증(KYC) 및 기업 확인(KYB) 세션 ID를 모두 지원하며, 서버는 두 세션 유형 전체에서 ID를 확인합니다. 올바른 형식의 UUID여야 합니다. 형식이 잘못된 값은 경로와 일치하지 않아 HTML `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "AML 확인의 워크플로 그래프 노드 ID입니다. 세션에서 둘 이상의 AML 단계를 실행한 경우에만 필요하며, 지정하지 않으면 가장 최근의 AML 확인이 사용됩니다. 알 수 없는 노드는 `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "example": "feature_aml_1"
            }
          },
          {
            "name": "month",
            "in": "query",
            "required": false,
            "description": "`YYYY-MM` 형식의 UTC 달력 월입니다. 해당 월에 완료된 스크리닝만 반환됩니다. 지정하지 않으면 모든 월이 반환됩니다. 형식이 잘못된 월은 `400`을 반환합니다.",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-(0[1-9]|1[0-2])$",
              "example": "2026-09"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/aml-screening-history/export/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -o aml-screening-history.csv"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.export_aml_screening_history(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.csv\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.exportAmlScreeningHistory(\"11111111-2222-3333-4444-555555555555\");\nawait writeFile(\"download.csv\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.ExportAMLScreeningHistory(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsExportAMLScreeningHistoryParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.csv\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().exportAmlScreeningHistory(\"11111111-2222-3333-4444-555555555555\")\n        .writeTo(Path.of(\"download.csv\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->sessions->exportAmlScreeningHistory('11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.csv');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.export_aml_screening_history(\"11111111-2222-3333-4444-555555555555\")\nFile.binwrite(\"download.csv\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.ExportAmlScreeningHistoryAsync(\"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.csv\");"
          }
        ],
        "responses": {
          "200": {
            "description": "CRLF 줄 바꿈과 함께 `text/csv`로 스트리밍되는 CSV 파일입니다. 컬럼 순서: `screened_at`(재스크리닝 완료 시점), `outcome`(`NO_CHANGE`, `CHANGED` 또는 `FAILED`), `provider`(AML 데이터 소스의 불투명 식별자, 이를 기준으로 분기하지 마세요), `aml_status`, `aml_score`, `total_hits`, `datasets_captured_at`, `datasets_sanctions_last_updated_at`, `datasets_pep_last_updated_at`, `datasets_warnings_last_updated_at`, `datasets_adverse_media_last_updated_at`, `datasets_catalog_version`, `run_id`(모니터링 실행 ID), `entities_screened`(실행 실패 시 `0`, 정상 실행 시 `1`), `new_hits`(알 수 없는 경우 비어 있음). 날짜는 UTC 오프셋이 포함된 ISO 8601 형식입니다. 재스크리닝 이력이 없는 세션은 헤더 행만 반환합니다.",
            "headers": {
              "Content-Disposition": {
                "description": "`attachment; filename=\"aml-screening-history-{sessionId}.csv\"`, 또는 `month`가 전달된 경우 `aml-screening-history-{sessionId}-{month}.csv`입니다.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=\"aml-screening-history-11111111-2222-3333-4444-555555555555.csv\""
                }
              }
            },
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                },
                "example": "screened_at,outcome,provider,aml_status,aml_score,total_hits,datasets_captured_at,datasets_sanctions_last_updated_at,datasets_pep_last_updated_at,datasets_warnings_last_updated_at,datasets_adverse_media_last_updated_at,datasets_catalog_version,run_id,entities_screened,new_hits\r\n2026-09-14T04:12:33.481207+00:00,NO_CHANGE,aml_data_source,Approved,0.0,0,2026-09-14T03:58:02.114820+00:00,2026-09-13T21:10:00+00:00,2026-09-13T08:00:00+00:00,2026-09-12T18:45:00+00:00,,2026-09-13,aaaaaaaa-1111-2222-3333-444444444444,1,0\r\n2026-09-13T04:11:58.020914+00:00,FAILED,aml_data_source,Approved,0.0,0,,,,,,,bbbbbbbb-1111-2222-3333-444444444444,0,\r\n"
              }
            }
          },
          "400": {
            "description": "`month`가 `YYYY-MM` 달력 월이 아닙니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "month": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "Malformed month": {
                    "summary": "month=2026-13",
                    "value": {
                      "month": [
                        "Not a calendar month. Use YYYY-MM."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions read": {
                    "summary": "스코프 지정 키에 decisions: read 권한이 없음",
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "Scoped key without media read": {
                    "summary": "스코프 지정 키에 media: read 권한이 없음(응답이 파일임)",
                    "value": {
                      "detail": "This API key has no read access to media."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나, 삭제되었거나, 범위가 지정된 키의 제한 범위를 벗어났거나, (해당 `node_id`에 대한) AML 검사가 없습니다. 세션 조회가 자격 증명 확인보다 먼저 실행되므로, 유효한 키가 없더라도 알 수 없는 `sessionId`에 대해 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "이 ID를 가진 세션이 존재하지 않거나 삭제되었습니다",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "세션이 범위가 지정된 키의 제한 범위를 벗어났습니다(방금 삭제된 세션에 대해서도 반환됨)",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "No AML check": {
                    "summary": "세션에서 AML 단계를 실행한 적이 없습니다",
                    "value": {
                      "detail": "The session does not have an AML check."
                    }
                  },
                  "No AML check for node": {
                    "summary": "node_id가 세션의 AML 검사와 일치하지 않음",
                    "value": {
                      "detail": "The session does not have an AML check for node 'feature_aml_2'."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한 초과: API 키당 분당 600개의 GET 요청. 재시도하기 전에 `Retry-After`초 동안 대기하세요. `X-RateLimit-*` 헤더에 남은 한도가 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "현재 분에 할당된 예산이 소진되었습니다",
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/add-images/": {
      "patch": {
        "summary": "세션에 이미지 추가",
        "description": "완료된 사용자 인증(KYC) 세션의 신분증 인증(`model_type=kyc`) 또는 주소 증명(`model_type=poa`) 결과에 추가 이미지 또는 PDF 1개를 첨부합니다(예: 흐름 외부에서 수집된 증빙 자료). 세션은 `Approved`, `Declined`, `In Review` 또는 `Kyc Expired` 상태여야 하며 `model_type`에 지정된 결과를 포함해야 합니다. 기업 확인(KYB) 세션은 지원되지 않습니다. 각 호출은 파일 1개를 추가하고(해당 단계가 2회 이상 실행된 경우 가장 최근 결과에 추가), 기존 파일을 유지하며, 세션 활동 로그에 `FILE_ADDED` 항목을 기록합니다. 업로드 시 webhook은 전송되지 않으며 세션 상태도 변경되지 않습니다. 파일은 업로드 시 압축되며 세션 결정의 `extra_files`로 반환됩니다. 이 endpoint는 API 키당 분당 10개의 요청으로 제한됩니다. 스코프가 지정된 API 키에는 `sessions: write` 권한이 필요하며, `media: read`가 없으면 `extra_files` 링크를 `null`로 수신합니다.",
        "operationId": "patch_v3_session_add_images",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "add_images",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "파일을 추가할 사용자 인증(KYC) 세션의 UUID입니다(`POST /v3/session/`에서 반환된 `session_id`). 기업 확인(KYB) 세션 ID는 `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file",
                  "model_type"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "이미지 또는 PDF입니다. 허용되는 확장자: `jpg`, `jpeg`, `png`, `webp`, `tiff`, `pdf`. 업로드 시 최대 15 MB이며, 이후 파일이 압축되고 압축 후에도 2 MB(2,097,152바이트)를 초과하면 `400`으로 거부됩니다. 빈 파일은 거부됩니다."
                  },
                  "model_type": {
                    "type": "string",
                    "enum": [
                      "kyc",
                      "poa"
                    ],
                    "description": "`kyc`는 신분증 인증 결과에 파일을 추가하고, `poa`는 주소 증명 결과에 파일을 추가합니다.",
                    "example": "kyc"
                  },
                  "file_password": {
                    "type": "string",
                    "description": "암호화된 PDF의 비밀번호입니다. 비밀번호가 없거나 틀리면 암호화된 PDF는 `400`을 반환합니다."
                  }
                }
              },
              "example": {
                "file": "(binary)",
                "model_type": "kyc"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/add-images/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'file=@./back-of-id.jpg' \\\n  -F 'model_type=kyc'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.add_images(\n    \"11111111-2222-3333-4444-555555555555\",\n    file=open(\"image.jpg\", \"rb\"),\n    model_type=\"kyc\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.addImages(\"11111111-2222-3333-4444-555555555555\", {\n  file: await fileFromPath(\"image.jpg\"),\n  model_type: \"kyc\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.AddImages(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsAddImagesParams{\n\tFile:      didit.FileFromPath(\"image.jpg\"),\n\tModelType: \"kyc\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.SessionsAddImagesParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().addImages(\"11111111-2222-3333-4444-555555555555\", SessionsAddImagesParams.builder()\n        .file(Path.of(\"image.jpg\"))\n        .modelType(SessionsAddImagesParams.ModelType.of(\"kyc\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->addImages('11111111-2222-3333-4444-555555555555', [\n    'file' => File::fromPath('image.jpg'),\n    'model_type' => 'kyc',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.add_images(\n  \"11111111-2222-3333-4444-555555555555\",\n  file: Pathname(\"image.jpg\"),\n  model_type: \"kyc\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.AddImagesAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsAddImagesParams\n{\n    File = FileUpload.FromPath(\"image.jpg\"),\n    ModelType = \"kyc\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "파일이 추가되었습니다. 새 파일을 포함하여 해당 결과의 모든 추가 파일을 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "extra_files"
                  ],
                  "properties": {
                    "extra_files": {
                      "type": "array",
                      "description": "`model_type`에 지정된 결과의 모든 추가 파일로 연결되는 유효 기간이 짧은 사전 서명된 링크 목록(오래된 순)입니다. `media: read` 권한이 없는 범위 지정 API 키의 경우 각 링크는 `null`입니다. 나중에 세션 결정에서 새로운 링크를 확인하세요.",
                      "items": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                      }
                    }
                  }
                },
                "example": {
                  "extra_files": [
                    "https://media.example.com/session/11111111-2222-3333-4444-555555555555/kyc-extra-files/66666666-7777-8888-9999-000000000000.jpg?expires=1789383731&signature=abc123"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류입니다. 필드 오류는 `{\"<field>\": [\"<message>\"]}`로 전달되고, 암호화된 PDF 오류는 `{\"detail\": \"...\"}`로 전달됩니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing file": {
                    "summary": "양식에 파일 파트가 없습니다",
                    "value": {
                      "file": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Missing model_type": {
                    "summary": "model_type이 누락됨",
                    "value": {
                      "model_type": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid model_type": {
                    "summary": "model_type이 kyc 또는 poa가 아닙니다.",
                    "value": {
                      "model_type": [
                        "\"passport\" is not a valid choice."
                      ]
                    }
                  },
                  "File too large": {
                    "summary": "15MB 초과 업로드",
                    "value": {
                      "file": [
                        "File size should not exceed 15 MB"
                      ]
                    }
                  },
                  "Too large after compression": {
                    "summary": "압축 후에도 여전히 2MB 초과",
                    "value": {
                      "file": [
                        "File size is too big. Max allowed size is 2097152 bytes."
                      ]
                    }
                  },
                  "Encrypted PDF": {
                    "summary": "file_password가 없는 암호화된 PDF",
                    "value": {
                      "detail": "The PDF is encrypted. Please upload a decrypted PDF or a photo instead."
                    }
                  },
                  "Wrong PDF password": {
                    "summary": "file_password로 PDF를 열 수 없습니다",
                    "value": {
                      "detail": "The PDF password is incorrect. Please provide the correct password."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without sessions write": {
                    "summary": "스코프 지정 키에 sessions: write 권한이 없음",
                    "value": {
                      "detail": "This API key has no write access to sessions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나, 삭제되었거나, 범위가 지정된 키의 제한 범위를 벗어났습니다. 또는 KYB 세션이거나 `Approved`, `Declined`, `In Review`, `Kyc Expired` 상태가 아니거나, 요청된 `model_type`의 결과가 없습니다(파일 유효성 검사 전에 확인됨). 세션 조회가 자격 증명 확인보다 먼저 실행되므로, 유효한 키가 없더라도 알 수 없는 `sessionId`에 대해 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "이 ID를 가진 세션이 존재하지 않거나 삭제되었습니다",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "세션이 범위가 지정된 키의 워크플로 또는 승인 전용 제한 범위를 벗어났습니다",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "Not eligible": {
                    "summary": "세션이 아직 완료되지 않았거나 KYB 세션 ID입니다",
                    "value": {
                      "detail": "No Session matches the given query."
                    }
                  },
                  "No ID verification": {
                    "summary": "신분증 인증이 없는 세션에서 model_type=kyc 지정됨",
                    "value": {
                      "detail": "The session does not have KYC data."
                    }
                  },
                  "No Proof of Address": {
                    "summary": "주소 증명이 없는 세션에서 model_type=poa 지정됨",
                    "value": {
                      "detail": "The session does not have POA data."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. API 키당 분당 10회의 이미지 추가 요청으로 제한됩니다(거부된 요청도 포함). 분당 300회의 쓰기 요청 공유 한도도 적용됩니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요. `X-RateLimit-*` 헤더에 한도 정보가 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "현재 분에 할당된 예산이 소진되었습니다",
                    "value": {
                      "detail": "Session add-images rate limit exceeded. You can make up to 10 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/DocumentProcessingBusy"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/update-aml-status/": {
      "patch": {
        "summary": "AML 검사 상태 업데이트",
        "description": "팀에서 모든 일치 항목을 해결한 후의 `Approved`와 같이, 세션의 AML 스크리닝 검사 전체 상태(세션 결정의 `aml_screenings[]` 항목의 `status`)를 설정합니다. KYC 및 KYB 세션 ID에 사용할 수 있습니다. 세션에서 둘 이상의 AML 단계를 실행한 경우 `node_id`(쿼리 파라미터 또는 본문 필드)를 전달해야 하며, 그렇지 않으면 가장 최근의 AML 검사가 업데이트됩니다. 상태가 실제로 변경되면 `AML_STATUS_UPDATED` 활동 항목이 기록되고 `data.updated` [webhook](https://docs.didit.me/ko/integration/webhooks)이 전송됩니다. 현재 상태를 그대로 전송하면 `200`을 반환하고 아무것도 변경하지 않습니다. 세션 상태는 다시 계산되지 않습니다. 세션 결정에는 `PATCH /v3/session/{sessionId}/update-status/`를, 단일 일치 항목에는 `PATCH /v3/session/{sessionId}/update-aml-hit-status/`를 사용하세요. 범위가 지정된 API 키에는 `decisions: write` 권한이 필요합니다.",
        "operationId": "patch_v3_session_update_aml_status",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_aml_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "인증 세션의 UUID(`POST /v3/session/`에서 반환된 `session_id`)입니다. 사용자 인증(KYC) 및 기업 확인(KYB) 세션 ID를 모두 지원하며, 서버는 두 세션 유형 전체에서 ID를 확인합니다. 올바른 형식의 UUID여야 합니다. 형식이 잘못된 값은 경로와 일치하지 않아 HTML `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "업데이트할 AML 확인의 워크플로 그래프 노드 ID입니다. 세션에서 둘 이상의 AML 단계를 실행한 경우에만 필요합니다. 본문의 `node_id`보다 우선합니다.",
            "schema": {
              "type": "string",
              "example": "feature_aml_1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "status"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "Not Finished",
                      "Approved",
                      "Declined",
                      "In Review",
                      "Resub Requested"
                    ],
                    "description": "AML 검사의 새 상태입니다.",
                    "example": "Approved"
                  },
                  "node_id": {
                    "type": "string",
                    "description": "쿼리 파라미터 대신 사용할 수 있는 AML 확인의 워크플로 그래프 노드 ID입니다.",
                    "example": "feature_aml_1"
                  }
                }
              },
              "example": {
                "status": "Approved"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-aml-status/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"status\": \"Approved\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_aml_status(\n    \"11111111-2222-3333-4444-555555555555\",\n    status=\"Approved\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateAmlStatus(\"11111111-2222-3333-4444-555555555555\", {\n  status: \"Approved\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateAMLStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateAMLStatusParams{\n\tStatus: \"Approved\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateAmlStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateAmlStatus(\"11111111-2222-3333-4444-555555555555\", SessionsUpdateAmlStatusParams.builder()\n        .status(SessionsUpdateAmlStatusParams.Status.of(\"Approved\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateAmlStatus('11111111-2222-3333-4444-555555555555', [\n    'status' => 'Approved',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_aml_status(\n  \"11111111-2222-3333-4444-555555555555\",\n  status: \"Approved\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateAmlStatusAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdateAmlStatusParams\n{\n    Status = \"Approved\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "설정된 AML 검사 상태입니다(이미 이 값을 가지고 있던 경우 변경되지 않음).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "message",
                    "status",
                    "previous_status"
                  ],
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "항상 `AML status updated successfully`입니다."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "Not Finished",
                        "Approved",
                        "Declined",
                        "In Review",
                        "Resub Requested"
                      ],
                      "description": "현재 AML 검사의 상태입니다."
                    },
                    "previous_status": {
                      "type": "string",
                      "enum": [
                        "Not Finished",
                        "Approved",
                        "Declined",
                        "In Review",
                        "Resub Requested"
                      ],
                      "description": "호출 전 상태입니다. 변경 사항이 없는 경우 `status`와 같습니다."
                    }
                  }
                },
                "example": {
                  "message": "AML status updated successfully",
                  "status": "Approved",
                  "previous_status": "In Review"
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류: `status`가 누락되었거나 허용된 값 중 하나가 아닙니다. AML 확인 조회가 먼저 실행되므로 AML 확인이 없는 세션은 잘못된 본문이더라도 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing status": {
                    "summary": "빈 body 또는 상태 없음",
                    "value": {
                      "status": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid status": {
                    "summary": "status가 enum에 없습니다",
                    "value": {
                      "status": [
                        "\"Cleared\" is not a valid choice."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "스코프 지정 키에 decisions: write 권한이 없음",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나, 삭제되었거나, 범위가 지정된 키의 제한 범위를 벗어났거나, (해당 `node_id`에 대한) AML 검사가 없습니다. 세션 조회가 자격 증명 확인보다 먼저 실행되므로, 유효한 키가 없더라도 알 수 없는 `sessionId`에 대해 `404`를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "이 ID를 가진 세션이 존재하지 않거나 삭제되었습니다",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "세션이 범위가 지정된 키의 제한 범위를 벗어났습니다(방금 삭제된 세션에 대해서도 반환됨)",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "No AML check": {
                    "summary": "세션에서 AML 단계를 실행한 적이 없습니다",
                    "value": {
                      "detail": "The session does not have an AML check."
                    }
                  },
                  "No AML check for node": {
                    "summary": "node_id가 세션의 AML 검사와 일치하지 않음",
                    "value": {
                      "detail": "The session does not have an AML check for node 'feature_aml_2'."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. API 키당 분당 300회의 쓰기(POST, PATCH, DELETE) 요청으로 제한됩니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요. `X-RateLimit-*` 헤더에 한도 정보가 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "현재 분에 할당된 예산이 소진되었습니다",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/status/": {
      "get": {
        "summary": "서비스 상태 가져오기(공개, 인증 불필요)",
        "description": "각 Didit 서비스의 상태(`operational`, `degraded` 또는 `down`), 전체 상태(가장 심각한 상태), 그리고 진행 중이거나 지난 7일 이내에 해결된 인시던트를 반환합니다. 상태 위젯을 구동하거나 연동 환경에서 Didit의 상태를 확인하는 데 사용하십시오.\n\n공개: 인증 헤더를 전송하지 마십시오. 응답에는 조직 데이터가 포함되지 않으며 모든 호출자에게 동일합니다. 응답은 30초 동안 캐시되므로 30초에 한 번 이하로 폴링하십시오.",
        "operationId": "get_v3_status",
        "tags": [
          "Status"
        ],
        "security": [
          {}
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "현재 서비스 상태입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceStatusFeed"
                },
                "examples": {
                  "One service degraded": {
                    "summary": "진행 중인 장애 1건 및 이번 주에 해결된 장애 1건",
                    "value": {
                      "status": "degraded",
                      "updated_at": "2026-10-13T09:41:07.512345Z",
                      "services": [
                        {
                          "key": "service_id_verification",
                          "name": "ID verification",
                          "status": "operational"
                        },
                        {
                          "key": "service_liveness_face_match",
                          "name": "Liveness and face match",
                          "status": "operational"
                        },
                        {
                          "key": "service_aml_screening",
                          "name": "AML screening",
                          "status": "operational"
                        },
                        {
                          "key": "service_kyb_registries",
                          "name": "KYB registries",
                          "status": "operational"
                        },
                        {
                          "key": "service_database_validation",
                          "name": "Database validation",
                          "status": "degraded"
                        },
                        {
                          "key": "service_phone_delivery",
                          "name": "Phone verification delivery",
                          "status": "operational"
                        },
                        {
                          "key": "service_email_delivery",
                          "name": "Email verification delivery",
                          "status": "operational"
                        },
                        {
                          "key": "service_transaction_monitoring",
                          "name": "Transaction monitoring",
                          "status": "operational"
                        }
                      ],
                      "incidents": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "service": "service_database_validation",
                          "service_name": "Database validation",
                          "state": "degraded",
                          "status": "ongoing",
                          "title": "Database validation is degraded in Brazil.",
                          "body": "Checks against Brazil (CPF) may be slow or fail since 08:55 UTC.",
                          "affected": "Brazil (CPF)",
                          "country_name": "Brazil",
                          "started_at": "2026-10-13T08:55:00Z",
                          "resolved_at": null,
                          "duration_minutes": null
                        },
                        {
                          "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                          "service": "service_aml_screening",
                          "service_name": "AML screening",
                          "state": "down",
                          "status": "resolved",
                          "title": "AML screening is back to normal.",
                          "body": "Recovered at 14:32 UTC after 17 minutes.",
                          "affected": "",
                          "country_name": "",
                          "started_at": "2026-10-11T14:15:00Z",
                          "resolved_at": "2026-10-11T14:32:00Z",
                          "duration_minutes": 17
                        }
                      ]
                    }
                  },
                  "All operational": {
                    "summary": "지난 7일간 인시던트 없음",
                    "value": {
                      "status": "operational",
                      "updated_at": "2026-10-13T09:41:07.512345Z",
                      "services": [
                        {
                          "key": "service_id_verification",
                          "name": "ID verification",
                          "status": "operational"
                        },
                        {
                          "key": "service_liveness_face_match",
                          "name": "Liveness and face match",
                          "status": "operational"
                        },
                        {
                          "key": "service_aml_screening",
                          "name": "AML screening",
                          "status": "operational"
                        },
                        {
                          "key": "service_kyb_registries",
                          "name": "KYB registries",
                          "status": "operational"
                        },
                        {
                          "key": "service_database_validation",
                          "name": "Database validation",
                          "status": "operational"
                        },
                        {
                          "key": "service_phone_delivery",
                          "name": "Phone verification delivery",
                          "status": "operational"
                        },
                        {
                          "key": "service_email_delivery",
                          "name": "Email verification delivery",
                          "status": "operational"
                        },
                        {
                          "key": "service_transaction_monitoring",
                          "name": "Transaction monitoring",
                          "status": "operational"
                        }
                      ],
                      "incidents": []
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "동일한 IP 주소(또는 전달한 경우 동일한 API 키)에서 1분 동안 600건을 초과하는 GET 요청이 발생했습니다. 다시 시도하기 전에 `Retry-After`를 준수하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "detail"
                  ],
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -fsS https://verification.didit.me/v3/status/"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import requests\n\nresp = requests.get('https://verification.didit.me/v3/status/', timeout=5)\nresp.raise_for_status()\nfeed = resp.json()\nprint(feed['status'])\nfor service in feed['services']:\n    if service['status'] != 'operational':\n        print(service['key'], service['status'])"
          },
          {
            "lang": "javascript",
            "label": "JavaScript",
            "source": "const feed = await fetch('https://verification.didit.me/v3/status/').then((r) => r.json());\nconsole.log(feed.status);\nconst affected = feed.services.filter((s) => s.status !== 'operational');\nconsole.log(affected.map((s) => `${s.key}: ${s.status}`));"
          }
        ],
        "x-didit-sdk": {
          "resource": "system",
          "method": "retrieve_status",
          "auth": "public",
          "server": false
        }
      }
    },
    "/v3/organization/bank-verification-pricing/": {
      "get": {
        "summary": "은행 인증 가격 조회 (공개, 인증 불필요)",
        "description": "모든 국가의 각 Bank Verification 방식(잔액 및 거래 내역 추가 기능이 포함된 은행 로그인, 계좌 확인)에 대한 정가를 반환합니다. 해당 국가에서 현재 제공되지 않는 방식은 가격 없이 이용 불가능으로 표시됩니다. 워크플로를 구축하기 전에 은행 단계를 견적하거나 자체 제품에 은행 가격을 표시하는 데 사용하십시오.\n\n공개: 인증 헤더를 전송하지 마십시오. 응답에는 조직 데이터가 포함되지 않으며 모든 호출자에게 동일합니다. 1시간 동안 공개적으로 캐시되며 `ETag`가 포함되어 있으므로, 변경 사항이 없을 때 `304 Not Modified`를 수신하려면 `If-None-Match`를 전송하십시오.\n\n방식은 Didit이 현재 프로덕션 환경에서 제공하는 경우에만 `available`이며, 그 외 모든 곳에서는 `price_usd`가 `null`이므로 구매할 수 없는 가격은 피드에 절대 표시되지 않습니다. `available: false`는 승인된 가격이 없는 국가, 해당 국가에서 지원하지 않는 방식, 아직 활성화되지 않은 경로를 포함합니다.\n\n이 가격은 요금제 할인이 적용되기 전의 정가입니다. 요금제 할인은 전체 은행 가격에 적용되며, 협상된 가격 또는 계약 가격이 조직의 정가를 대체합니다.",
        "operationId": "get_v3_bank_verification_pricing",
        "tags": [
          "Pricing"
        ],
        "security": [
          {}
        ],
        "parameters": [],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -fsS https://verification.didit.me/v3/organization/bank-verification-pricing/"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# This call needs no API key.\nclient = Didit()\n\nresult = client.pricing.bank_verification()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// This call needs no API key.\nconst didit = new Didit();\n\nconst result = await didit.pricing.bankVerification();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// This call needs no API key.\nclient := didit.NewClient()\n\nresult, err := client.Pricing.BankVerification(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// This call needs no API key.\nDidit client = new Didit();\n\nvar result = client.pricing().bankVerification();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// This call needs no API key.\n$didit = new DiditClient();\n\n$result = $didit->pricing->bankVerification();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# This call needs no API key.\ndidit = Didit::Client.new\n\nresult = didit.pricing.bank_verification\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// This call needs no API key.\nusing var client = new DiditClient();\n\nvar result = await client.Pricing.BankVerificationAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-sdk": {
          "resource": "pricing",
          "method": "bank_verification",
          "auth": "none",
          "server": true
        },
        "responses": {
          "200": {
            "description": "국가별 은행 인증 정가입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankVerificationPricing"
                },
                "examples": {
                  "Two countries": {
                    "summary": "두 방법이 모두 지원되는 국가 1개, 둘 다 지원되지 않는 국가 1개",
                    "value": {
                      "currency": "USD",
                      "statement_upload": {
                        "price_usd": "0.0000",
                        "included_after_charged_bank_attempt": true,
                        "standalone_available": false
                      },
                      "own_provider_fee_usd": "0.0200",
                      "countries": {
                        "GBR": {
                          "name": "United Kingdom",
                          "methods": {
                            "open_banking": {
                              "available": true,
                              "market": "UK and EEA",
                              "price_usd": "0.7900",
                              "add_ons": {
                                "balance": "0.3500",
                                "transactions": "1.3000"
                              }
                            },
                            "account_lookup": {
                              "available": true,
                              "price_usd": "0.4000"
                            }
                          }
                        },
                        "CAN": {
                          "name": "Canada",
                          "methods": {
                            "open_banking": {
                              "available": false,
                              "market": null,
                              "price_usd": null,
                              "add_ons": {}
                            },
                            "account_lookup": {
                              "available": false,
                              "price_usd": null
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "304": {
            "description": "수정되지 않음: `If-None-Match`로 보낸 `ETag`가 여전히 일치합니다. 본문이 없습니다."
          }
        }
      }
    },
    "/v3/session/{sessionId}/simulate/": {
      "post": {
        "summary": "샌드박스 세션 상태 시뮬레이션",
        "description": "플로우를 실행하지 않고도 백엔드에서 사후에 샌드박스 세션에 최종 상태를 강제로 적용합니다. 샌드박스 애플리케이션 전용이며, 프로덕션 세션은 `404`를 반환합니다. 사용자 인증(KYC) 및 기업 확인(KYB) 세션에서 작동합니다.\n\n`new_status`를 설정하거나 `scenario` 또는 `risk`가 이를 제공하도록 하십시오. `risk`(또는 시나리오의 매직 값이 전달하는 첫 번째 위험)는 해당 경고를 세션에 추가합니다. 변경 사항은 세션 활동 기록에 기록됩니다.\n\n`send_webhooks`(기본값 `true`)는 실제 상태 변경 시 전송되는 것과 정확히 동일한 webhook을 전송합니다. `false`로 설정하면 상태는 여전히 변경되고 콘솔도 실시간으로 업데이트되지만, webhook이 기록되거나 전송되지 않으며, 누락된 webhook 복구 기능이 해당 결정을 재전송하지 않습니다. 다음 상태 변경 시에는 평소와 같이 webhook이 전송됩니다. 응답에는 적용된 값이 그대로 반환됩니다.\n\n`write:sessions` 권한이 필요합니다. 범위가 지정된 API 키에는 세션에 대한 쓰기 권한이 필요합니다. 알 수 없는 `session_id`는 `404`를 반환하고, 다른 애플리케이션의 세션은 `403`을 반환하며, 둘 다 본문을 읽기 전에 반환됩니다. 프로덕션 세션은 본문이 검증된 후에만 `404`를 반환합니다. 세션 자체의 토큰을 사용하여 호스팅 플로우에서 시뮬레이션하려면 `POST /v3/session/{sessionId}/sandbox/simulate/`를 사용하십시오. 시나리오 카탈로그는 [Sandbox & Test Data](/ko/integration/sandbox-testing)를 참조하십시오.",
        "operationId": "post_v3_session_simulate",
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "샌드박스 인증 세션의 UUID입니다. 사용자(KYC) 및 기업(KYB) 세션 ID를 모두 지원합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SandboxSimulateRequest"
              },
              "examples": {
                "Scenario Without Webhooks": {
                  "summary": "webhook을 전송하지 않고 시나리오를 통해 거부",
                  "value": {
                    "scenario": "decline_aml_hit",
                    "send_webhooks": false
                  }
                },
                "Status Only": {
                  "summary": "승인하고 일반 webhook 전송",
                  "value": {
                    "new_status": "Approved"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "상태가 변경되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxSimulateResponse"
                },
                "examples": {
                  "Simulated": {
                    "summary": "시나리오를 통해 거부됨, webhook 전송되지 않음",
                    "value": {
                      "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "previous_status": "In Progress",
                      "status": "Declined",
                      "scenario": "decline_aml_hit",
                      "risk": "POSSIBLE_MATCH_FOUND",
                      "send_webhooks": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류: 알 수 없는 시나리오 또는 위험, `scenario`와 `risk` 모두 제공하지 않을 때 `new_status` 부재, 이 endpoint가 설정하지 않는 상태, 또는 세션에 이미 요청된 상태가 있는 경우(단순 JSON 배열)입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown Scenario": {
                    "summary": "시나리오가 카탈로그에 없습니다",
                    "value": {
                      "scenario": [
                        "Unknown sandbox scenario: 'not-a-scenario'."
                      ]
                    }
                  },
                  "Unknown Risk": {
                    "summary": "risk가 카탈로그에 없습니다.",
                    "value": {
                      "risk": [
                        "Unknown sandbox risk case: 'NOT_A_RISK'."
                      ]
                    }
                  },
                  "Missing new_status": {
                    "summary": "new_status, 시나리오 또는 위험 없음",
                    "value": {
                      "new_status": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid new_status": {
                    "summary": "시뮬레이션에서 설정하지 않는 상태",
                    "value": {
                      "new_status": [
                        "\"Resubmitted\" is not a valid choice."
                      ]
                    }
                  },
                  "Same Status": {
                    "summary": "세션이 이미 이 상태입니다",
                    "value": [
                      "The new status is the same as the current status."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "만료일이 지난 스코프 지정 API 키",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나, 호출자에게 `write:sessions` 권한이 없거나, 범위 지정 API 키에 이 endpoint가 필요로 하는 접근 권한이 없거나, `session_id`가 다른 애플리케이션에 속해 있습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "호출자에게 write:sessions 권한이 없습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped Key Without Access": {
                    "summary": "이 접근 권한이 없는 스코프 지정 API 키",
                    "value": {
                      "detail": "This API key has no write access to sessions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 `session_id`를 가진 세션이 존재하지 않거나, 프로덕션(비샌드박스) 세션입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "알 수 없거나 프로덕션 환경의 세션",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/simulate/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"scenario\": \"decline_aml_hit\", \"send_webhooks\": false}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.simulate(\n    \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    scenario=\"decline_aml_hit\",\n    send_webhooks=False,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.simulate(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  scenario: \"decline_aml_hit\",\n  send_webhooks: false,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Simulate(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", didit.SandboxSimulateRequest{\n\tScenario:     didit.String(\"decline_aml_hit\"),\n\tSendWebhooks: didit.Bool(false),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SandboxSimulateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().simulate(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", SandboxSimulateRequest.builder()\n        .scenario(\"decline_aml_hit\")\n        .sendWebhooks(false)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->simulate('3fa85f64-5717-4562-b3fc-2c963f66afa6', [\n    'scenario' => 'decline_aml_hit',\n    'send_webhooks' => false,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.simulate(\n  \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  scenario: \"decline_aml_hit\",\n  send_webhooks: false\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.SimulateAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", new SandboxSimulateRequest\n{\n    Scenario = \"decline_aml_hit\",\n    SendWebhooks = false,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "simulate",
          "auth": "api_key",
          "server": true
        }
      }
    },
    "/v3/session/{sessionId}/sandbox/simulate/": {
      "post": {
        "summary": "클라이언트에서 샌드박스 세션 상태 시뮬레이션",
        "description": "API 키 대신 세션 자체의 `Session-Token`([Create Session](/ko/sessions-api/create-session)의 `session_token`으로 반환됨)으로 인증되어 테스트 하네스나 호스팅 플로우가 클라이언트에서 호출할 수 있는 `POST /v3/session/{sessionId}/simulate/`와 동일한 시뮬레이션입니다. 본문, 응답 및 `send_webhooks`는 해당 endpoint에서와 동일하게 동작합니다.\n\n라이브(비샌드박스) 애플리케이션의 `Session-Token`이거나 경로의 `sessionId`와 일치하지 않는 경우 `404`가 반환됩니다. [Sandbox & Test Data](/ko/integration/sandbox-testing)를 참고하세요.",
        "operationId": "post_v3_session_sandbox_simulate",
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "SessionTokenAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "샌드박스 인증 세션의 UUID입니다. 인증에 사용된 Session-Token에 인코딩된 세션과 일치해야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SandboxSimulateRequest"
              },
              "examples": {
                "Scenario Without Webhooks": {
                  "summary": "webhook을 전송하지 않고 시나리오를 통해 거부",
                  "value": {
                    "scenario": "decline_aml_hit",
                    "send_webhooks": false
                  }
                },
                "Status Only": {
                  "summary": "승인하고 일반 webhook 전송",
                  "value": {
                    "new_status": "Approved"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "상태가 변경되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxSimulateResponse"
                },
                "examples": {
                  "Simulated": {
                    "summary": "시나리오를 통해 거부됨, webhook 전송되지 않음",
                    "value": {
                      "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "previous_status": "In Progress",
                      "status": "Declined",
                      "scenario": "decline_aml_hit",
                      "risk": "POSSIBLE_MATCH_FOUND",
                      "send_webhooks": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류: 알 수 없는 시나리오 또는 위험, `scenario`와 `risk` 모두 제공하지 않을 때 `new_status` 부재, 이 endpoint가 설정하지 않는 상태, 또는 세션에 이미 요청된 상태가 있는 경우(단순 JSON 배열)입니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown Scenario": {
                    "summary": "시나리오가 카탈로그에 없습니다",
                    "value": {
                      "scenario": [
                        "Unknown sandbox scenario: 'not-a-scenario'."
                      ]
                    }
                  },
                  "Unknown Risk": {
                    "summary": "risk가 카탈로그에 없습니다.",
                    "value": {
                      "risk": [
                        "Unknown sandbox risk case: 'NOT_A_RISK'."
                      ]
                    }
                  },
                  "Missing new_status": {
                    "summary": "new_status, 시나리오 또는 위험 없음",
                    "value": {
                      "new_status": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid new_status": {
                    "summary": "시뮬레이션에서 설정하지 않는 상태",
                    "value": {
                      "new_status": [
                        "\"Resubmitted\" is not a valid choice."
                      ]
                    }
                  },
                  "Same Status": {
                    "summary": "세션이 이미 이 상태입니다",
                    "value": [
                      "The new status is the same as the current status."
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "`Session-Token` 헤더가 없거나 유효하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Session Token": {
                    "summary": "Session-Token이 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`Session-Token`이 프로덕션(비샌드박스) 애플리케이션에 속해 있거나, 경로의 `sessionId`와 일치하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "진행 중인 세션이거나, session_id / token이 일치하지 않음",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/sandbox/simulate/ \\\n  -H 'Session-Token: YOUR_SESSION_TOKEN' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"new_status\": \"Approved\", \"send_webhooks\": false}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import requests\n\nresponse = requests.post(\n    \"https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/sandbox/simulate/\",\n    headers={\"Session-Token\": \"YOUR_SESSION_TOKEN\"},\n    json={\"new_status\": \"Approved\", \"send_webhooks\": False},\n)\nresponse.raise_for_status()\nprint(response.json())"
          }
        ],
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "simulate_sandbox",
          "auth": "device_token",
          "server": false
        }
      }
    },
    "/v3/session/{sessionId}/features/overrides/": {
      "get": {
        "summary": "세션의 검사 재정의 목록 조회",
        "description": "사용자 인증(KYC) 또는 기업 확인(KYB) 세션의 개별 기능(단계) 상태에 대한 모든 재정의 내역(페이지 매김 없이 최신순)입니다. 적용된 항목, 사용자가 절차를 완료하기를 대기 중인 항목(`pending_until_flow_finishes`), 취소된 항목이 포함되며, 각각 요청자, 사유, 사용자가 절차를 진행 중일 때 적용되었는지 여부(`forced`)가 표시됩니다.\n\n`person_in_flow`는 `defer_until_flow_finishes: true`로 설정된 새 재정의가 대기할지 여부를 나타냅니다. `flow_finished_at`은 사용자가 마지막으로 절차를 완료한 시점이며, 아직 절차를 진행 중이거나(재제출 포함) 완료하기 전에 세션이 닫힌 경우 `null`입니다.\n\n`read:sessions` 권한이 필요하며, 범위가 지정된 API 키는 결정에 대한 읽기 권한이 필요합니다.",
        "operationId": "get_v3_session_feature_overrides",
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "인증 세션의 UUID입니다. 사용자(KYC) 및 기업(KYB) 세션 ID를 모두 지원합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "세션의 검사 재정의 내역이며 최신순으로 정렬됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "session_id",
                    "person_in_flow",
                    "flow_finished_at",
                    "overrides"
                  ],
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid",
                      "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                    },
                    "person_in_flow": {
                      "type": "boolean",
                      "description": "해당 인물이 여전히 플로우에 있어 `defer_until_flow_finishes: true`가 설정된 새 재정의가 대기 상태가 되는지 여부입니다.",
                      "example": true
                    },
                    "flow_finished_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "사용자가 플로우를 마지막으로 완료한 시점입니다. 사용자가 여전히 플로우 내에 있거나(재제출 포함), 사용자가 완료하기 전에 세션이 종료된 경우(중단됨, 만료됨, 플로우 도중 결정됨)에는 `null`입니다.",
                      "example": null
                    },
                    "overrides": {
                      "type": "array",
                      "description": "세션의 모든 재정의 내역(최신순)입니다.",
                      "items": {
                        "$ref": "#/components/schemas/FeatureStatusOverride"
                      }
                    }
                  }
                },
                "examples": {
                  "Overrides": {
                    "summary": "대기 중인 재정의 1건, 적용된 재정의 1건",
                    "value": {
                      "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "person_in_flow": true,
                      "flow_finished_at": null,
                      "overrides": [
                        {
                          "id": "9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3",
                          "node_id": "feature_liveness_1",
                          "feature_type": "",
                          "feature_model": "Face",
                          "previous_status": "Declined",
                          "new_status": "Approved",
                          "state": "pending_until_flow_finishes",
                          "forced": false,
                          "reason": "Liveness retried with a reviewer present.",
                          "requested_by": {
                            "email": "reviewer@example.com",
                            "name": "Alex Reviewer",
                            "type": "CONSOLE_USER"
                          },
                          "requested_at": "2026-10-13T09:15:00Z",
                          "applied_at": null,
                          "cancelled_at": null,
                          "cancel_reason": null
                        },
                        {
                          "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                          "node_id": "feature_ocr_1",
                          "feature_type": "",
                          "feature_model": "KYC",
                          "previous_status": "In Review",
                          "new_status": "Approved",
                          "state": "applied",
                          "forced": true,
                          "reason": "Document manually verified by compliance.",
                          "requested_by": {
                            "email": "reviewer@example.com",
                            "name": "Alex Reviewer",
                            "type": "CONSOLE_USER"
                          },
                          "requested_at": "2026-10-13T09:15:00Z",
                          "applied_at": "2026-10-13T09:15:00Z",
                          "cancelled_at": null,
                          "cancel_reason": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "만료일이 지난 스코프 지정 API 키",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나, 호출자에게 `read:sessions` 권한이 없거나, 범위 지정 API 키에 이 endpoint가 필요로 하는 접근 권한이 없거나, `session_id`가 다른 애플리케이션에 속해 있습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "호출자에게 read:sessions 권한이 없습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped Key Without Access": {
                    "summary": "이 접근 권한이 없는 스코프 지정 API 키",
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 `session_id`를 가진 KYC 또는 KYB 세션이 존재하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "알 수 없는 session_id",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET \\\n  https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/features/overrides/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.list_feature_overrides(\n    \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.listFeatureOverrides(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ListFeatureOverrides(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().listFeatureOverrides(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->listFeatureOverrides('3fa85f64-5717-4562-b3fc-2c963f66afa6');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.list_feature_overrides(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ListFeatureOverridesAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list_feature_overrides",
          "auth": "api_key",
          "server": true
        }
      }
    },
    "/v3/session/{sessionId}/features/overrides/{overrideId}/cancel/": {
      "post": {
        "summary": "흐름이 완료되기를 대기 중인 검사 재정의 취소",
        "description": "아직 `pending_until_flow_finishes` 상태인 기능(단계) 상태의 재정의를 취소하여 적용되지 않도록 합니다. 검사는 기존 상태를 유지하고, 취소 내역은 세션 활동에 `FEATURE_OVERRIDE_CANCELLED`로 기록되며, webhook은 전송되지 않습니다. 응답은 `state: cancelled` 및 `cancel_reason: cancelled_by_reviewer`가 포함된 재정의 객체입니다.\n\n이미 적용되었거나 취소된 재정의는 `feature_override_not_pending` 코드와 함께 `409`를 반환합니다. 재정의 ID는 `GET /v3/session/{sessionId}/features/overrides/` 또는 기능 상태 업데이트 시 반환되는 `override`에서 확인할 수 있습니다.\n\n`write:sessions` 권한이 필요하며, 범위가 지정된 API 키에는 결정에 대한 쓰기 권한이 필요합니다.",
        "operationId": "post_v3_session_feature_override_cancel",
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "인증 세션의 UUID입니다. 사용자(KYC) 및 기업(KYB) 세션 ID를 모두 지원합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            }
          },
          {
            "in": "path",
            "name": "overrideId",
            "required": true,
            "description": "취소할 오버라이드의 `id`입니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "오버라이드가 취소되었으며 앞으로 절대 적용되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeatureStatusOverride"
                },
                "examples": {
                  "Cancelled": {
                    "summary": "취소된 재정의",
                    "value": {
                      "id": "9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3",
                      "node_id": "feature_liveness_1",
                      "feature_type": "",
                      "feature_model": "Face",
                      "previous_status": "Declined",
                      "new_status": "Approved",
                      "state": "cancelled",
                      "forced": false,
                      "reason": "Liveness retried with a reviewer present.",
                      "requested_by": {
                        "email": "reviewer@example.com",
                        "name": "Alex Reviewer",
                        "type": "CONSOLE_USER"
                      },
                      "requested_at": "2026-10-13T09:15:00Z",
                      "applied_at": null,
                      "cancelled_at": "2026-10-13T09:20:00Z",
                      "cancel_reason": "cancelled_by_reviewer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "만료일이 지난 스코프 지정 API 키",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나, 호출자에게 `write:sessions` 권한이 없거나, 범위 지정 API 키에 이 endpoint가 필요로 하는 접근 권한이 없거나, `session_id`가 다른 애플리케이션에 속해 있습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "호출자에게 write:sessions 권한이 없습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped Key Without Access": {
                    "summary": "이 접근 권한이 없는 스코프 지정 API 키",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 `session_id`를 가진 KYC 또는 KYB 세션이 존재하지 않거나, 세션에 이 `overrideId`를 가진 오버라이드가 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "알 수 없는 session_id",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Override Not Found": {
                    "summary": "세션에 이 id를 가진 재정의가 없습니다",
                    "value": {
                      "detail": "Override not found."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "오버라이드가 이미 적용되었거나 취소되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Pending": {
                    "summary": "대기 중인 오버라이드만 취소할 수 있습니다",
                    "value": {
                      "detail": "This override is no longer pending: it already applied or was cancelled.",
                      "code": "feature_override_not_pending"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/features/overrides/9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3/cancel/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.cancel_feature_override(\n    \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.cancelFeatureOverride(\n  \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.CancelFeatureOverride(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().cancelFeatureOverride(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->cancelFeatureOverride('3fa85f64-5717-4562-b3fc-2c963f66afa6', '9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.cancel_feature_override(\n  \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.CancelFeatureOverrideAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "cancel_feature_override",
          "auth": "api_key",
          "server": true
        }
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/tags/add/": {
      "post": {
        "summary": "네트워크에 태그 추가",
        "description": "귀하의 애플리케이션 태그 중 하나를 네트워크에 추가합니다. `tags`에 해당 네트워크에 있는 귀하의 애플리케이션 태그가 나열된 네트워크 상세 정보를 반환하며, 태그가 추가되었을 때는 `201`을, 이미 네트워크에 있었을 때는 `200`을 반환합니다. 다른 애플리케이션에 속해 있거나 존재하지 않는 태그는 404 `Tag not found.`를 반환합니다. 전체 액세스 API 키가 필요하거나, 콘솔 멤버의 경우 `write:networks` 권한이 필요합니다.",
        "operationId": "add_network_tag",
        "tags": [
          "Networks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            },
            "description": "네트워크 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NetworkTagRequest"
              },
              "example": {
                "tag_uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/3fa85f64-5717-4562-b3fc-2c963f66afa6/tags/add/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"tag_uuid\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.add_tag(\n    \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    tag_uuid=\"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.addTag(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  tag_uuid: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.AddTag(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", didit.NetworkTagRequest{\n\tTagUUID: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.NetworkTagRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().addTag(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", NetworkTagRequest.builder()\n        .tagUuid(\"7c9e6679-7425-40de-944b-e07fc1f90ae7\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->addTag('3fa85f64-5717-4562-b3fc-2c963f66afa6', [\n    'tag_uuid' => '7c9e6679-7425-40de-944b-e07fc1f90ae7',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.add_tag(\n  \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  tag_uuid: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.AddTagAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", new NetworkTagRequest\n{\n    TagUuid = \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "태그가 추가되었습니다. 네트워크 세부 정보를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkDetailResponse"
                },
                "example": {
                  "uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "network_id": "N-0042",
                  "name": null,
                  "status": "in_review",
                  "risk": {
                    "score": 82,
                    "band": "high",
                    "bar": 0.82
                  },
                  "pattern_types": [
                    "exact_same_device",
                    "same_email"
                  ],
                  "signal_types": [
                    "device",
                    "email"
                  ],
                  "member_counts": {
                    "total": 3,
                    "users": 3,
                    "businesses": 0,
                    "transaction_parties": 0
                  },
                  "member_status": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "not_completed": 1
                  },
                  "signal_coverage": {
                    "device": {
                      "signals": 1,
                      "subjects": 3,
                      "coverage": 1.0
                    },
                    "email": {
                      "signals": 1,
                      "subjects": 2,
                      "coverage": 0.6667
                    }
                  },
                  "first_activity_at": "2026-10-01T09:12:44Z",
                  "last_activity_at": "2026-10-12T16:03:10Z",
                  "stats": {
                    "members": {
                      "total": 3,
                      "users": 3,
                      "businesses": 0,
                      "transaction_parties": 0
                    },
                    "member_status": {
                      "approved": 1,
                      "declined": 1,
                      "in_review": 0,
                      "not_completed": 1
                    },
                    "signals": {
                      "total": 2,
                      "by_type": {
                        "device": {
                          "signals": 1,
                          "subjects": 3,
                          "coverage": 1.0
                        },
                        "email": {
                          "signals": 1,
                          "subjects": 2,
                          "coverage": 0.6667
                        }
                      }
                    }
                  },
                  "fraud_tags": [],
                  "risk_signals": {
                    "residential_proxy_reuse": {
                      "detected": false,
                      "signal_count": 0,
                      "max_subject_count": 0
                    },
                    "email_intelligence": {
                      "enriched_signal_count": 1,
                      "high_risk_count": 0,
                      "social_profile_count": 0
                    },
                    "phone_intelligence": {
                      "enriched_signal_count": 0,
                      "high_risk_count": 0
                    }
                  },
                  "reviewed_at": "2026-10-12T16:30:00Z",
                  "reviewed_by": "reviewer@example.com",
                  "review_reason": "Shared device across three new accounts.",
                  "notes_count": 0,
                  "sharing_mode": "global",
                  "cross_org_available": true,
                  "cross_org_unavailable_reason": null,
                  "tags": [
                    {
                      "uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "name": "SUSPICIOUS",
                      "color": "#6366F1",
                      "source": "custom",
                      "added_by": null,
                      "added_at": "2026-10-13T08:15:00Z"
                    }
                  ],
                  "outcomes": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "total": 3
                  },
                  "patterns": [
                    {
                      "type": "background",
                      "score": 0.8125,
                      "members": 3,
                      "reason": null,
                      "computed_at": "2026-10-13T08:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "200": {
            "description": "태그가 이미 네트워크에 존재하여 그대로 유지됩니다. 네트워크 세부 정보를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkDetailResponse"
                },
                "example": {
                  "uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "network_id": "N-0042",
                  "name": null,
                  "status": "in_review",
                  "risk": {
                    "score": 82,
                    "band": "high",
                    "bar": 0.82
                  },
                  "pattern_types": [
                    "exact_same_device",
                    "same_email"
                  ],
                  "signal_types": [
                    "device",
                    "email"
                  ],
                  "member_counts": {
                    "total": 3,
                    "users": 3,
                    "businesses": 0,
                    "transaction_parties": 0
                  },
                  "member_status": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "not_completed": 1
                  },
                  "signal_coverage": {
                    "device": {
                      "signals": 1,
                      "subjects": 3,
                      "coverage": 1.0
                    },
                    "email": {
                      "signals": 1,
                      "subjects": 2,
                      "coverage": 0.6667
                    }
                  },
                  "first_activity_at": "2026-10-01T09:12:44Z",
                  "last_activity_at": "2026-10-12T16:03:10Z",
                  "stats": {
                    "members": {
                      "total": 3,
                      "users": 3,
                      "businesses": 0,
                      "transaction_parties": 0
                    },
                    "member_status": {
                      "approved": 1,
                      "declined": 1,
                      "in_review": 0,
                      "not_completed": 1
                    },
                    "signals": {
                      "total": 2,
                      "by_type": {
                        "device": {
                          "signals": 1,
                          "subjects": 3,
                          "coverage": 1.0
                        },
                        "email": {
                          "signals": 1,
                          "subjects": 2,
                          "coverage": 0.6667
                        }
                      }
                    }
                  },
                  "fraud_tags": [],
                  "risk_signals": {
                    "residential_proxy_reuse": {
                      "detected": false,
                      "signal_count": 0,
                      "max_subject_count": 0
                    },
                    "email_intelligence": {
                      "enriched_signal_count": 1,
                      "high_risk_count": 0,
                      "social_profile_count": 0
                    },
                    "phone_intelligence": {
                      "enriched_signal_count": 0,
                      "high_risk_count": 0
                    }
                  },
                  "reviewed_at": "2026-10-12T16:30:00Z",
                  "reviewed_by": "reviewer@example.com",
                  "review_reason": "Shared device across three new accounts.",
                  "notes_count": 0,
                  "sharing_mode": "global",
                  "cross_org_available": true,
                  "cross_org_unavailable_reason": null,
                  "tags": [
                    {
                      "uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "name": "SUSPICIOUS",
                      "color": "#6366F1",
                      "source": "custom",
                      "added_by": null,
                      "added_at": "2026-10-13T08:15:00Z"
                    }
                  ],
                  "outcomes": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "total": 3
                  },
                  "patterns": [
                    {
                      "type": "background",
                      "score": 0.8125,
                      "members": 3,
                      "reason": null,
                      "computed_at": "2026-10-13T08:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 본문: `tag_uuid`가 누락되었거나 UUID가 아닙니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tag_uuid": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "Missing tag_uuid": {
                    "summary": "tag_uuid가 누락되었습니다",
                    "value": {
                      "tag_uuid": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid tag_uuid": {
                    "summary": "유효하지 않은 tag_uuid",
                    "value": {
                      "tag_uuid": [
                        "Must be a valid UUID."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "자격 증명이 누락되었거나 유효하지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "코드화된 오류에 표시됩니다(예: `networks_not_entitled`)."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "자격 증명이 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 다른 애플리케이션에 속해 있거나 접근 권한이 제한된 키입니다. Networks 엔드포인트에는 전체 접근 권한 키가 필요합니다. 콘솔 멤버 토큰에는 `write:networks` 권한이 필요합니다. 조직에 Networks가 활성화되어 있지 않은 경우 `code: networks_not_entitled`와 함께 반환되기도 합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "코드화된 오류에 표시됩니다(예: `networks_not_entitled`)."
                    }
                  }
                },
                "examples": {
                  "Networks not enabled": {
                    "summary": "네트워크가 활성화되지 않았습니다",
                    "value": {
                      "detail": "Networks is disabled for this organization. Contact Didit support if you believe this is an error.",
                      "code": "networks_not_entitled"
                    }
                  },
                  "Restricted API key": {
                    "summary": "제한된 API 키",
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "No permission": {
                    "summary": "권한 없음",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "찾을 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "코드화된 오류에 표시됩니다(예: `networks_not_entitled`)."
                    }
                  }
                },
                "examples": {
                  "Network not found": {
                    "summary": "네트워크를 찾을 수 없습니다",
                    "value": {
                      "detail": "Network not found."
                    }
                  },
                  "Tag not found": {
                    "summary": "태그를 찾을 수 없음",
                    "value": {
                      "detail": "Tag not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "networks",
          "method": "add_tag",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        }
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/tags/remove/": {
      "post": {
        "summary": "네트워크에서 태그 삭제",
        "description": "네트워크에서 애플리케이션의 태그 중 하나를 제거합니다. 네트워크 상세 정보를 반환합니다. 태그가 네트워크에 없거나 애플리케이션에 속하지 않은 경우 404를 반환합니다. 전체 액세스 API 키 또는 콘솔 멤버의 `write:networks` 권한이 필요합니다.",
        "operationId": "remove_network_tag",
        "tags": [
          "Networks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            },
            "description": "네트워크 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NetworkTagRequest"
              },
              "example": {
                "tag_uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/3fa85f64-5717-4562-b3fc-2c963f66afa6/tags/remove/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"tag_uuid\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.remove_tag(\n    \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    tag_uuid=\"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.removeTag(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  tag_uuid: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.RemoveTag(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", didit.NetworkTagRequest{\n\tTagUUID: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.NetworkTagRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().removeTag(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", NetworkTagRequest.builder()\n        .tagUuid(\"7c9e6679-7425-40de-944b-e07fc1f90ae7\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->removeTag('3fa85f64-5717-4562-b3fc-2c963f66afa6', [\n    'tag_uuid' => '7c9e6679-7425-40de-944b-e07fc1f90ae7',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.remove_tag(\n  \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  tag_uuid: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RemoveTagAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", new NetworkTagRequest\n{\n    TagUuid = \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "태그가 네트워크에서 제거되었습니다. 네트워크 세부 정보를 반환합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkDetailResponse"
                },
                "example": {
                  "uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "network_id": "N-0042",
                  "name": null,
                  "status": "in_review",
                  "risk": {
                    "score": 82,
                    "band": "high",
                    "bar": 0.82
                  },
                  "pattern_types": [
                    "exact_same_device",
                    "same_email"
                  ],
                  "signal_types": [
                    "device",
                    "email"
                  ],
                  "member_counts": {
                    "total": 3,
                    "users": 3,
                    "businesses": 0,
                    "transaction_parties": 0
                  },
                  "member_status": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "not_completed": 1
                  },
                  "signal_coverage": {
                    "device": {
                      "signals": 1,
                      "subjects": 3,
                      "coverage": 1.0
                    },
                    "email": {
                      "signals": 1,
                      "subjects": 2,
                      "coverage": 0.6667
                    }
                  },
                  "first_activity_at": "2026-10-01T09:12:44Z",
                  "last_activity_at": "2026-10-12T16:03:10Z",
                  "stats": {
                    "members": {
                      "total": 3,
                      "users": 3,
                      "businesses": 0,
                      "transaction_parties": 0
                    },
                    "member_status": {
                      "approved": 1,
                      "declined": 1,
                      "in_review": 0,
                      "not_completed": 1
                    },
                    "signals": {
                      "total": 2,
                      "by_type": {
                        "device": {
                          "signals": 1,
                          "subjects": 3,
                          "coverage": 1.0
                        },
                        "email": {
                          "signals": 1,
                          "subjects": 2,
                          "coverage": 0.6667
                        }
                      }
                    }
                  },
                  "fraud_tags": [],
                  "risk_signals": {
                    "residential_proxy_reuse": {
                      "detected": false,
                      "signal_count": 0,
                      "max_subject_count": 0
                    },
                    "email_intelligence": {
                      "enriched_signal_count": 1,
                      "high_risk_count": 0,
                      "social_profile_count": 0
                    },
                    "phone_intelligence": {
                      "enriched_signal_count": 0,
                      "high_risk_count": 0
                    }
                  },
                  "reviewed_at": "2026-10-12T16:30:00Z",
                  "reviewed_by": "reviewer@example.com",
                  "review_reason": "Shared device across three new accounts.",
                  "notes_count": 0,
                  "sharing_mode": "global",
                  "cross_org_available": true,
                  "cross_org_unavailable_reason": null,
                  "tags": [],
                  "outcomes": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "total": 3
                  },
                  "patterns": [
                    {
                      "type": "background",
                      "score": 0.8125,
                      "members": 3,
                      "reason": null,
                      "computed_at": "2026-10-13T08:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 본문: `tag_uuid`가 누락되었거나 UUID가 아닙니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tag_uuid": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "Missing tag_uuid": {
                    "summary": "tag_uuid가 누락되었습니다",
                    "value": {
                      "tag_uuid": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid tag_uuid": {
                    "summary": "유효하지 않은 tag_uuid",
                    "value": {
                      "tag_uuid": [
                        "Must be a valid UUID."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "자격 증명이 누락되었거나 유효하지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "코드화된 오류에 표시됩니다(예: `networks_not_entitled`)."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "자격 증명이 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 다른 애플리케이션에 속해 있거나 접근 권한이 제한된 키입니다. Networks 엔드포인트에는 전체 접근 권한 키가 필요합니다. 콘솔 멤버 토큰에는 `write:networks` 권한이 필요합니다. 조직에 Networks가 활성화되어 있지 않은 경우 `code: networks_not_entitled`와 함께 반환되기도 합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "코드화된 오류에 표시됩니다(예: `networks_not_entitled`)."
                    }
                  }
                },
                "examples": {
                  "Networks not enabled": {
                    "summary": "네트워크가 활성화되지 않았습니다",
                    "value": {
                      "detail": "Networks is disabled for this organization. Contact Didit support if you believe this is an error.",
                      "code": "networks_not_entitled"
                    }
                  },
                  "Restricted API key": {
                    "summary": "제한된 API 키",
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "No permission": {
                    "summary": "권한 없음",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "찾을 수 없습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "코드화된 오류에 표시됩니다(예: `networks_not_entitled`)."
                    }
                  }
                },
                "examples": {
                  "Network not found": {
                    "summary": "네트워크를 찾을 수 없습니다",
                    "value": {
                      "detail": "Network not found."
                    }
                  },
                  "Tag not found": {
                    "summary": "태그를 찾을 수 없음",
                    "value": {
                      "detail": "Tag not found."
                    }
                  },
                  "Tag not on the network": {
                    "summary": "네트워크에 없는 태그입니다",
                    "value": {
                      "detail": "This tag is not on the network."
                    }
                  }
                }
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "networks",
          "method": "remove_tag",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        }
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/requests/{request_uuid}/remind/": {
      "post": {
        "summary": "고객에게 요청을 다시 알림",
        "description": "대기 중인 고객 요청의 이메일을 동일한 인증된 수취인에게 동일한 내용으로 다시 전송합니다. 요청 알림은 최대 24시간에 한 번씩 보낼 수 있습니다. 알림을 보내도 다른 것은 변경되지 않습니다. 요청은 기한을 유지하고 케이스는 상태를 유지합니다. 각 알림은 작업이 `reminded`인 CUSTOMER_REQUEST 이벤트로 케이스에 기록됩니다. 응답의 `delivery_status`는 이 알림 전송이 어떻게 끝났는지를 나타냅니다. SENT, SIMULATED(이메일이 전송되지 않음) 또는 UNKNOWN(이메일이 수락되었을 수 있음. 자동으로 다시 전송되지 않음)입니다. `next_reminder_at`은 이 요청에 다시 알림을 보낼 수 있는 시간입니다. 고객에게 더 이상 답변할 요청이 없는 경우 `reason`과 함께 409를 반환하고, 지난 24시간 이내에 요청 알림이 전송된 경우 `retry_at` 및 `Retry-After` 헤더와 함께 429를 반환합니다. `write:cases`가 필요합니다.",
        "operationId": "organization_application_cases_requests_remind_create",
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "description": "조직 UUID입니다."
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "description": "애플리케이션 UUID입니다."
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "description": "케이스 UUID."
          },
          {
            "in": "path",
            "name": "request_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "description": "케이스의 요청 목록에 있는 고객 요청 UUID입니다."
          }
        ],
        "tags": [
          "Case Management"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/requests/3fa85f64-5717-4562-b3fc-2c963f66afa6/remind/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.remind(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.remind(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.Remind(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().remind(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->requests->remind('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.remind(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.RemindAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "리마인더가 기록되었으며 해당 이메일이 전송되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "request",
                    "reminded_at",
                    "delivery_status",
                    "next_reminder_at"
                  ],
                  "properties": {
                    "request": {
                      "$ref": "#/components/schemas/CustomerMessagingCaseRequest"
                    },
                    "reminded_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "이 리마인더가 기록된 시점입니다."
                    },
                    "delivery_status": {
                      "type": "string",
                      "enum": [
                        "SENT",
                        "SIMULATED",
                        "UNKNOWN"
                      ],
                      "description": "이 알림의 전송이 종료된 방식입니다. SIMULATED: 이메일이 전송되지 않았습니다. UNKNOWN: 이메일이 접수되었을 수 있으며, 자동으로 다시 전송되지 않습니다."
                    },
                    "next_reminder_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "이 요청에 대해 다시 리마인더를 보낼 수 있는 시점입니다(`reminded_at`에 24시간을 더한 시간)."
                    }
                  }
                },
                "example": {
                  "request": {
                    "uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "purpose": "confirm_details",
                    "language": "en",
                    "recipient": "customer@example.com",
                    "expires_at": "2026-10-20T09:00:00Z",
                    "actor_email": "reviewer@example.com",
                    "delivery_status": "SENT",
                    "delivered_at": "2026-10-13T09:00:04Z",
                    "cancelled_at": null,
                    "responded_at": null,
                    "response": null,
                    "has_attachment": false,
                    "created_at": "2026-10-13T09:00:00Z"
                  },
                  "reminded_at": "2026-10-14T10:30:00Z",
                  "delivery_status": "SENT",
                  "next_reminder_at": "2026-10-15T10:30:00Z"
                }
              }
            }
          },
          "400": {
            "description": "케이스에 승인 대기 중인 해결안이 있습니다. 본문은 문자열 목록입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "example": [
                  "Customer messages require an active case without a pending resolution."
                ]
              }
            }
          },
          "403": {
            "description": "호출자에게 필요한 케이스 권한이 없습니다."
          },
          "404": {
            "description": "이 호출자에게는 요청 또는 케이스를 사용할 수 없습니다."
          },
          "409": {
            "description": "요청이 더 이상 고객의 응답을 기다리지 않으므로 고객에게 알림을 보낼 내용이 없습니다. `reason`에 이유가 명시됩니다: `answered`(고객이 응답함), `cancelled`, `expired`, `closed`(요청 발송 후 케이스가 해결됨, 이후 다시 열렸더라도 해당), `not_actionable`(검토 진행 중 업데이트로 아무것도 요청하지 않음), `not_delivered`(첫 번째 이메일이 발송되지 않음), 또는 `contact_unavailable`(인증된 이메일을 더 이상 사용할 수 없음).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "case_request_not_waiting"
                      ]
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "answered",
                        "cancelled",
                        "expired",
                        "closed",
                        "not_actionable",
                        "not_delivered",
                        "contact_unavailable"
                      ]
                    }
                  }
                },
                "example": {
                  "detail": "This request no longer waits on the customer, so there is nothing to remind them of.",
                  "code": "case_request_not_waiting",
                  "reason": "answered"
                }
              }
            }
          },
          "429": {
            "description": "지난 24시간 동안 요청에 대해 이미 알림이 전송되었습니다. `retry_at`과 `Retry-After` 헤더에 언제 다시 알림을 보낼 수 있는지가 표시됩니다.",
            "headers": {
              "Retry-After": {
                "description": "이 요청에 대해 다시 알림을 보낼 수 있을 때까지 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 3600
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "case_request_reminder_too_soon"
                      ]
                    },
                    "retry_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "detail": "This request was already reminded in the last 24 hours.",
                  "code": "case_request_reminder_too_soon",
                  "retry_at": "2026-10-15T10:30:00Z"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "remind",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        }
      }
    },
    "/v3/session/{sessionId}/decision-email-preview/": {
      "post": {
        "summary": "세션의 결정 이메일 미리보기",
        "description": "세션을 변경하거나 아무것도 전송하지 않고, `send_email: true`로 세션을 `Approved` 또는 `Declined`로 설정할 때 해당 사용자가 받게 될 이메일을 렌더링합니다. 응답에는 실제로 전송되는 제목과 HTML, 수신자, 발신자, 언어 및 변경을 확정할 때 이메일이 실제로 전송되는지 여부(`will_be_sent`, `not_sent_reason`)가 정확히 표시됩니다.\n\n수신자는 해당 사용자의 자체 주소입니다. 즉, 플로우의 이메일 인증 단계에서 검증한 주소이거나, 세션 생성 시 `contact_details`에 입력된 주소입니다. 발신자는 화이트 라벨이 적용되는 경우 애플리케이션의 인증된 발신자 도메인(`sender_kind: customer`)이고, 그렇지 않은 경우 Didit의 발신자(`sender_kind: didit`)입니다.\n\n미리 본 내용 그대로 전송하려면 동일한 `new_status`, `send_email: true`, `recipient`로 설정된 `email_address`, `language`로 설정된 `email_language`, `preview_token`으로 설정된 `email_preview_token`을 사용하여 [세션 상태 업데이트](/ko/sessions-api/update-status)을 호출합니다. 영수증은 15분 후에 만료됩니다. 미리보기 이후 수신자, 언어, 세션 상태, 발신자 또는 이메일이 변경된 경우 업데이트는 아무것도 변경되기 전에 `409`를 반환합니다. 이 경우 다시 미리보기를 수행하고 새 영수증으로 확인하십시오.\n\n`Approved`, `Declined`, `In Review`, `Kyc Expired`, `Abandoned` 또는 `Resubmitted` 상태의 사용자 인증(KYC) 및 기업 확인(KYB) 세션에서 작동합니다. 상태 확인은 본문 유효성 검사 전에 실행됩니다. `write:sessions` 권한이 필요하며, 범위가 지정된 API 키에는 결정에 대한 쓰기 권한이 필요합니다. 응답은 `Cache-Control: no-store`를 사용하므로 민감한 인증 콘텐츠로 취급해야 합니다.",
        "operationId": "post_v3_session_decision_email_preview",
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "인증 세션의 UUID입니다. 사용자(KYC) 및 기업(KYB) 세션 ID를 모두 지원합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "new_status"
                ],
                "properties": {
                  "new_status": {
                    "type": "string",
                    "enum": [
                      "Approved",
                      "Declined"
                    ],
                    "description": "이메일을 미리 보려는 결정입니다.",
                    "example": "Approved"
                  },
                  "email_language": {
                    "type": "string",
                    "default": "en",
                    "description": "이메일 언어로, Update Session Status와 기본값이 동일합니다. 제공되지 않는 언어는 영어로 대체되며, 응답의 `language`에 사용된 언어가 표시됩니다.",
                    "example": "en"
                  }
                }
              },
              "examples": {
                "Approved": {
                  "summary": "영어 'Approved' 이메일 미리보기",
                  "value": {
                    "new_status": "Approved"
                  }
                },
                "Declined in Spanish": {
                  "summary": "스페인어 'Declined' 이메일 미리보기",
                  "value": {
                    "new_status": "Declined",
                    "email_language": "es"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "미리보기 전용입니다. 세션은 변경되지 않으며 이메일도 전송되지 않습니다.",
            "headers": {
              "Cache-Control": {
                "description": "항상 `no-store`입니다. 미리보기에는 인증 콘텐츠가 포함되어 있으므로 캐시해서는 안 됩니다.",
                "schema": {
                  "type": "string",
                  "example": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "recipient",
                    "recipient_source",
                    "sender",
                    "sender_name",
                    "sender_email",
                    "sender_kind",
                    "subject",
                    "html",
                    "text",
                    "language",
                    "will_be_sent",
                    "not_sent_reason",
                    "preview_token"
                  ],
                  "properties": {
                    "recipient": {
                      "type": "string",
                      "description": "이메일이 전송되는 주소입니다. 사용자의 주소를 알 수 없는 경우 빈 문자열입니다: 이 경우 이메일을 전송할 수 없으며 `preview_token`도 비어 있습니다. 확인할 때 `email_address`로 전달하십시오.",
                      "example": "person@example.com"
                    },
                    "recipient_source": {
                      "type": "string",
                      "enum": [
                        "email_verification",
                        "contact_details",
                        ""
                      ],
                      "description": "`recipient`의 출처입니다. `email_verification`: 플로우의 이메일 인증 단계에서 사용자가 인증한 주소입니다. `contact_details`: 세션 생성 시 `contact_details`에 제공된 주소입니다. 주소가 없는 경우 빈 문자열입니다.",
                      "example": "email_verification"
                    },
                    "sender": {
                      "type": "string",
                      "description": "이메일 발송에 사용되는 `From` 헤더입니다.",
                      "example": "Example App <no-reply@mail.example.com>"
                    },
                    "sender_name": {
                      "type": "string",
                      "description": "`sender`의 표시 이름 부분입니다.",
                      "example": "Example App"
                    },
                    "sender_email": {
                      "type": "string",
                      "format": "email",
                      "description": "`sender`의 주소 부분입니다.",
                      "example": "no-reply@mail.example.com"
                    },
                    "sender_kind": {
                      "type": "string",
                      "enum": [
                        "customer",
                        "didit"
                      ],
                      "description": "`customer`: 이메일이 애플리케이션의 인증된 발신자 도메인(화이트 라벨)에서 발송됩니다. `didit`: Didit의 자체 발신자에서 발송됩니다.",
                      "example": "customer"
                    },
                    "subject": {
                      "type": "string",
                      "description": "전송된 그대로의 제목 라인입니다.",
                      "example": "Your verification has been approved in Example App"
                    },
                    "html": {
                      "type": "string",
                      "description": "전송된 그대로의 이메일 HTML이며, 로고는 data URL로 임베드되어 있습니다. 애플리케이션 DOM에 직접 렌더링하지 말고 반드시 샌드박스 처리된 프레임에서 렌더링하세요.",
                      "example": "<!DOCTYPE html><html><body>...</body></html>"
                    },
                    "text": {
                      "type": "string",
                      "description": "간결한 미리보기를 제공하기 위해 수신자의 메시지 스레드에 보관되는 일반 텍스트 형태의 이메일 내용입니다(HTML은 수신자가 받는 이메일 그대로 유지됨).",
                      "example": "Verification Approved\n\nYour identity has been successfully verified with Acme Pay. No further action is needed on your part."
                    },
                    "language": {
                      "type": "string",
                      "description": "이메일이 작성된 언어입니다. 요청한 `email_language`가 제공되지 않는 경우 영어(`en`)로 설정됩니다.",
                      "example": "en"
                    },
                    "will_be_sent": {
                      "type": "boolean",
                      "description": "`send_email: true`로 변경 사항을 확인할 때 이 이메일을 발송할지 여부입니다. `not_sent_reason`이 설정된 경우 `false`입니다.",
                      "example": true
                    },
                    "not_sent_reason": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "status_unchanged",
                        "notification_emails_disabled",
                        "no_recipient",
                        "sandbox",
                        null
                      ],
                      "description": "확인 시 이메일이 전송되지 않는 이유 또는 전송될 예정인 경우 `null`입니다. `status_unchanged`: 세션이 이미 이 상태이므로 업데이트로 인해 변경되거나 전송되는 항목이 없습니다. `notification_emails_disabled`: `contact_details.send_notification_emails: true` 없이 세션이 생성되었으므로 `contact_details`에 지정된 주소로 결정 이메일이 전송되지 않습니다. `no_recipient`: 사용자의 알려진 주소가 없습니다. `sandbox`: 수신자가 샌드박스 이메일 전송에 동의하지 않은 샌드박스 세션이므로 전송이 시뮬레이션만 됩니다.",
                      "example": null
                    },
                    "preview_token": {
                      "type": "string",
                      "description": "해당 이메일에 대한 서명된 영수증으로, 15분 동안 유효합니다. [세션 상태 업데이트](/ko/sessions-api/update-status)에 `email_preview_token`으로 전달하십시오. 수신자가 없는 경우 빈 문자열입니다.",
                      "example": "eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000"
                    }
                  }
                },
                "examples": {
                  "Will Be Sent": {
                    "summary": "승인 완료 이메일은 플로우에서 인증된 주소로 전송됩니다",
                    "value": {
                      "recipient": "person@example.com",
                      "recipient_source": "email_verification",
                      "sender": "Example App <no-reply@mail.example.com>",
                      "sender_name": "Example App",
                      "sender_email": "no-reply@mail.example.com",
                      "sender_kind": "customer",
                      "subject": "Your verification has been approved in Example App",
                      "html": "<!DOCTYPE html><html><body>...</body></html>",
                      "language": "en",
                      "will_be_sent": true,
                      "not_sent_reason": null,
                      "preview_token": "eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000"
                    }
                  },
                  "No Recipient": {
                    "summary": "해당 인물에 대해 알려진 주소가 없습니다",
                    "value": {
                      "recipient": "",
                      "recipient_source": "",
                      "sender": "Example App <no-reply@mail.example.com>",
                      "sender_name": "Example App",
                      "sender_email": "no-reply@mail.example.com",
                      "sender_kind": "customer",
                      "subject": "Your verification has been declined in Example App",
                      "html": "<!DOCTYPE html><html><body>...</body></html>",
                      "language": "en",
                      "will_be_sent": false,
                      "not_sent_reason": "no_recipient",
                      "preview_token": ""
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "세션이 이 endpoint에서 허용하는 상태가 아니거나(`{\"detail\": ...}`), 본문이 올바르지 않습니다(`{\"<field>\": [\"<message>\"]}`).",
            "content": {
              "application/json": {
                "examples": {
                  "Wrong Current Status": {
                    "summary": "세션이 이 endpoint에서 허용하는 상태가 아닙니다",
                    "value": {
                      "detail": "Only sessions with status Approved, Declined, In Review, Kyc Expired, Abandoned, Resubmitted can be updated. Current status: In Progress"
                    }
                  },
                  "Invalid new_status": {
                    "summary": "new_status가 Approved 또는 Declined가 아닙니다.",
                    "value": {
                      "new_status": [
                        "\"Resubmitted\" is not a valid choice."
                      ]
                    }
                  },
                  "Missing new_status": {
                    "summary": "필수 필드가 누락됨",
                    "value": {
                      "new_status": [
                        "This field is required."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "만료일이 지난 스코프 지정 API 키",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "자격 증명이 누락되었거나, 호출자에게 `write:sessions` 권한이 없거나, 범위 지정 API 키에 이 endpoint가 필요로 하는 접근 권한이 없거나, `session_id`가 다른 애플리케이션에 속해 있습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key가 누락되었거나 유효하지 않음",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "호출자에게 write:sessions 권한이 없습니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped Key Without Access": {
                    "summary": "이 접근 권한이 없는 스코프 지정 API 키",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 `session_id`를 가진 KYC 또는 KYB 세션이 존재하지 않습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "알 수 없는 session_id",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/decision-email-preview/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"new_status\": \"Approved\", \"email_language\": \"en\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.preview_decision_email(\n    \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    new_status=\"Approved\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.previewDecisionEmail(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  new_status: \"Approved\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.PreviewDecisionEmail(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", didit.SessionsPreviewDecisionEmailParams{\n\tNewStatus: \"Approved\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsPreviewDecisionEmailParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().previewDecisionEmail(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", SessionsPreviewDecisionEmailParams.builder()\n        .newStatus(SessionsPreviewDecisionEmailParams.NewStatus.of(\"Approved\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->previewDecisionEmail('3fa85f64-5717-4562-b3fc-2c963f66afa6', [\n    'new_status' => 'Approved',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.preview_decision_email(\n  \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  new_status: \"Approved\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.PreviewDecisionEmailAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", new SessionsPreviewDecisionEmailParams\n{\n    NewStatus = \"Approved\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "preview_decision_email",
          "auth": "api_key",
          "server": true
        }
      }
    },
    "/v3/travel-rule/join/{token}/": {
      "get": {
        "summary": "무료 가입 초대 조회",
        "description": "공개, 비인증. 가입 링크가 유효한 동안 해당 가입 링크에 연결된 초대를 표시합니다: 요청자, 초대가 전송된 주소 및 사전 입력될 디렉터리 값. token이 인증 역할을 합니다.",
        "operationId": "getTravelRuleJoinInvitation",
        "x-didit-sdk": {
          "resource": "travel_rule.join",
          "method": "get_invitation",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "가입 링크의 초대 token입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl https://verification.didit.me/v3/travel-rule/join/{token}/"
          }
        ],
        "responses": {
          "200": {
            "description": "초대입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleJoinInvitation"
                }
              }
            }
          },
          "404": {
            "description": "이 링크를 가진 초대장이 없습니다."
          },
          "410": {
            "description": "초대가 더 이상 유효하지 않습니다. 만료되었거나, 이미 사용되었거나, 철회되었습니다."
          }
        }
      },
      "post": {
        "summary": "무료 Travel Rule 계정 등록",
        "description": "공개, 비인증. 요청을 수신한 거래 상대방 VASP를 위한 무료 Travel Rule 계정을 생성합니다. 이메일은 초대가 전송된 주소여야 합니다. 해당 주소로 6자리 코드가 이메일로 발송되며, 완료하려면 이를 verify endpoint로 전송하십시오. 가입 시도는 주소 및 IP당 속도 제한이 적용됩니다.",
        "operationId": "registerTravelRuleJoin",
        "x-didit-sdk": {
          "resource": "travel_rule.join",
          "method": "register",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "가입 링크의 초대 token입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleJoinRegisterRequest"
              },
              "example": {
                "email": "compliance@example.com",
                "password": "a-long-passphrase"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/join/{token}/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"email\": \"compliance@example.com\", \"password\": \"a-long-passphrase\"}'"
          }
        ],
        "responses": {
          "202": {
            "description": "계정이 생성되었으며 코드가 이메일로 전송되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "거래 상대방에게 이메일에서 인증 코드를 확인하라고 알립니다."
                    },
                    "email": {
                      "type": "string",
                      "format": "email",
                      "description": "코드가 전송된 주소입니다."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "초대받은 이메일 주소가 아니거나 비밀번호 또는 주소가 거부되었습니다."
          },
          "404": {
            "description": "이 링크를 가진 초대장이 없습니다."
          },
          "410": {
            "description": "초대가 더 이상 유효하지 않습니다. 만료되었거나, 이미 사용되었거나, 철회되었습니다."
          },
          "429": {
            "description": "참여 시도가 너무 많습니다. `X-RateLimit-*` 헤더에 소진된 예산이 표시됩니다."
          }
        }
      }
    },
    "/v3/travel-rule/join/{token}/verify/": {
      "post": {
        "summary": "무료 Travel Rule 계정 인증",
        "description": "공개, 비인증. 이메일로 수신한 코드를 사용하고, 무료 조직을 생성하며, 해당 애플리케이션이 워크스페이스 endpoint에서 사용하는 자격 증명으로 응답합니다. Travel Rule 데이터 수신은 무료입니다.",
        "operationId": "verifyTravelRuleJoin",
        "x-didit-sdk": {
          "resource": "travel_rule.join",
          "method": "verify",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "가입 링크의 초대 token입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleJoinVerifyRequest"
              },
              "example": {
                "email": "compliance@example.com",
                "code": "123456"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/join/{token}/verify/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"email\": \"compliance@example.com\", \"code\": \"123456\"}'"
          }
        ],
        "responses": {
          "201": {
            "description": "조직 및 애플리케이션 자격 증명입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleJoinCredentials"
                }
              }
            }
          },
          "400": {
            "description": "코드 또는 이메일이 거부되었습니다."
          },
          "404": {
            "description": "이 링크를 가진 초대장이 없습니다."
          },
          "410": {
            "description": "초대가 더 이상 유효하지 않습니다. 만료되었거나, 이미 사용되었거나, 철회되었습니다."
          },
          "429": {
            "description": "참여 시도가 너무 많습니다. `X-RateLimit-*` 헤더에 소진된 예산이 표시됩니다."
          }
        }
      }
    },
    "/v3/travel-rule/workspace/": {
      "get": {
        "summary": "무료 Travel Rule 워크스페이스 가져오기",
        "description": "무료로 가입한 애플리케이션의 무료 워크스페이스 정보를 조회합니다: 디렉터리 소유권 주장, 도메인 증명, 결제 및 Didit 네트워크 목록.",
        "operationId": "getTravelRuleWorkspace",
        "x-didit-sdk": {
          "resource": "travel_rule.workspace",
          "method": "get",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/workspace/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.get()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.get();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.Get(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().get();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->workspace->get();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.get\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.GetAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "워크스페이스입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWorkspace"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션은 무료 요금제에 가입하지 않았으므로 무료 워크스페이스가 없습니다."
          }
        }
      }
    },
    "/v3/travel-rule/workspace/claim/": {
      "post": {
        "summary": "디렉터리 항목 소유권 주장",
        "description": "이 워크스페이스에 해당하는 디렉터리 항목의 소유권을 주장합니다. 업무 이메일이 항목에 나열된 도메인에 속하는 경우 소유권 주장이 입증되어 즉시 적용됩니다. VASP 프로필과 Travel Rule 설정이 항목으로부터 채워지고 Travel Rule이 활성화되므로 다음 대상에 대한 전송은 Didit 네트워크를 통해 라우팅됩니다. 그렇지 않은 경우 소유권 주장은 검토 대기(`pending_review`) 상태가 됩니다.",
        "operationId": "claimTravelRuleWorkspace",
        "x-didit-sdk": {
          "resource": "travel_rule.workspace",
          "method": "claim",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleWorkspaceClaimRequest"
              },
              "example": {
                "vasp_id": "0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/claim/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"vasp_id\": \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.claim(\n    vasp_id=\"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.claim({\n  vasp_id: \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.Claim(ctx, didit.TravelRuleWorkspaceClaimRequest{\n\tVASPID: \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWorkspaceClaimRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().claim(TravelRuleWorkspaceClaimRequest.builder()\n        .vaspId(\"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->workspace->claim([\n    'vasp_id' => '0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.claim(vasp_id: \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.ClaimAsync(new TravelRuleWorkspaceClaimRequest\n{\n    VaspId = \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "청구 상태가 포함된 워크스페이스입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWorkspace"
                }
              }
            }
          },
          "400": {
            "description": "이 id를 가진 디렉터리 항목이 없습니다."
          },
          "404": {
            "description": "이 애플리케이션은 무료 요금제에 가입하지 않았으므로 무료 워크스페이스가 없습니다."
          }
        }
      }
    },
    "/v3/travel-rule/workspace/domain/code/": {
      "post": {
        "summary": "도메인 인증 코드 이메일 발송",
        "description": "이메일 도메인을 제어하고 있음을 증명하기 위해 워크스페이스의 업무용 주소로 일회용 코드를 이메일로 전송합니다. 속도 제한이 적용되며, 코드당 허용되는 잘못된 시도 횟수가 제한되어 있습니다. 또한 DNS 대안을 위한 TXT 레코드도 반환합니다.",
        "operationId": "sendTravelRuleWorkspaceDomainCode",
        "x-didit-sdk": {
          "resource": "travel_rule.workspace",
          "method": "send_domain_code",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/domain/code/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.send_domain_code()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.sendDomainCode();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.SendDomainCode(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().sendDomainCode();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->workspace->sendDomainCode();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.send_domain_code\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.SendDomainCodeAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "도메인, 해당 상태 및 TXT 레코드입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWorkspaceDomainCodeResponse"
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션은 무료 요금제에 가입하지 않았으므로 무료 워크스페이스가 없습니다."
          }
        }
      }
    },
    "/v3/travel-rule/workspace/domain/confirm/": {
      "post": {
        "summary": "도메인 인증 코드 확인",
        "description": "이메일로 전송된 코드를 사용 처리하고 이메일 도메인을 인증 완료로 표시합니다.",
        "operationId": "confirmTravelRuleWorkspaceDomain",
        "x-didit-sdk": {
          "resource": "travel_rule.workspace",
          "method": "confirm_domain",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleWorkspaceDomainConfirmRequest"
              },
              "example": {
                "code": "123456"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/domain/confirm/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"code\": \"123456\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.confirm_domain(\n    code=\"123456\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.confirmDomain({\n  code: \"123456\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.ConfirmDomain(ctx, didit.TravelRuleWorkspaceDomainConfirmRequest{\n\tCode: \"123456\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWorkspaceDomainConfirmRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().confirmDomain(TravelRuleWorkspaceDomainConfirmRequest.builder()\n        .code(\"123456\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->workspace->confirmDomain([\n    'code' => '123456',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.confirm_domain(code: \"123456\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.ConfirmDomainAsync(new TravelRuleWorkspaceDomainConfirmRequest\n{\n    Code = \"123456\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "워크스페이스입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWorkspace"
                }
              }
            }
          },
          "400": {
            "description": "코드가 잘못되었거나 만료되었거나 이미 사용되었습니다."
          },
          "404": {
            "description": "이 애플리케이션은 무료 요금제에 가입하지 않았으므로 무료 워크스페이스가 없습니다."
          }
        }
      }
    },
    "/v3/travel-rule/workspace/domain/dns/": {
      "post": {
        "summary": "TXT 레코드를 통해 도메인을 검증합니다",
        "description": "코드 endpoint에서 반환된 `didit-tr-verify.<domain>` TXT 레코드를 확인하고 일치하면 도메인을 확인됨으로 표시합니다. 이메일로 전송된 코드 또는 TXT 레코드 중 하나의 증명만으로 충분합니다.",
        "operationId": "verifyTravelRuleWorkspaceDomainDns",
        "x-didit-sdk": {
          "resource": "travel_rule.workspace",
          "method": "verify_domain_dns",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/domain/dns/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.verify_domain_dns()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.verifyDomainDns();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.VerifyDomainDNS(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().verifyDomainDns();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->workspace->verifyDomainDns();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.verify_domain_dns\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.VerifyDomainDnsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "워크스페이스입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWorkspace"
                }
              }
            }
          },
          "400": {
            "description": "TXT 레코드를 찾을 수 없거나 일치하지 않습니다."
          },
          "404": {
            "description": "이 애플리케이션은 무료 요금제에 가입하지 않았으므로 무료 워크스페이스가 없습니다."
          }
        }
      }
    },
    "/v3/travel-rule/workspace/billing/": {
      "post": {
        "summary": "아웃바운드 결제 활성화",
        "description": "워크스페이스에 대해 아웃바운드 Travel Rule 결제를 켭니다. 수신은 무료로 유지됩니다. 이는 API를 통해 다시 끌 수 없으므로 Didit 지원팀에 문의하십시오.",
        "operationId": "enableTravelRuleWorkspaceBilling",
        "x-didit-sdk": {
          "resource": "travel_rule.workspace",
          "method": "enable_billing",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleWorkspaceBillingRequest"
              },
              "example": {
                "enabled": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/billing/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"enabled\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.enable_billing(\n    enabled=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.enableBilling({\n  enabled: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.EnableBilling(ctx, didit.TravelRuleWorkspaceBillingRequest{\n\tEnabled: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWorkspaceBillingRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().enableBilling(TravelRuleWorkspaceBillingRequest.builder()\n        .enabled(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->workspace->enableBilling([\n    'enabled' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.enable_billing(enabled: true)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.EnableBillingAsync(new TravelRuleWorkspaceBillingRequest\n{\n    Enabled = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "`billing_enabled`가 true인 워크스페이스입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWorkspace"
                }
              }
            }
          },
          "400": {
            "description": "`enabled`가 false였습니다."
          },
          "404": {
            "description": "이 애플리케이션은 무료 요금제에 가입하지 않았으므로 무료 워크스페이스가 없습니다."
          }
        }
      }
    },
    "/v3/investigator/summary/": {
      "get": {
        "operationId": "investigator_summary",
        "summary": "조사관 요약",
        "description": "단계, 대기열 수, 오늘 준비 및 결정된 보고서, 30일 계약, 가격 및 각 대기열의 자율성 수준입니다. 제한된 키에는 `decisions` 스코프(읽기)가 필요하며, 거래 알림에는 `transactions`도 필요합니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "stage": {
                      "type": "string"
                    },
                    "last_report_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "prepared_today": {
                      "type": "integer"
                    },
                    "ready_to_accept": {
                      "type": "integer"
                    },
                    "open": {
                      "type": "integer"
                    },
                    "decided_today": {
                      "type": "integer"
                    },
                    "automation_rate_month": {
                      "type": "number",
                      "nullable": true
                    },
                    "preparing": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "scope",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "identity",
                "transactions"
              ],
              "default": "all"
            },
            "description": "`identity`(세션 및 거래 규칙으로 열리지 않은 케이스) 또는 `transactions`(거래 알림 및 거래 규칙으로 열린 케이스)입니다."
          },
          {
            "in": "query",
            "name": "timezone",
            "schema": {
              "type": "string"
            },
            "description": "\"오늘\"을 계산하는 기준이 되는 IANA 표준 시간대(예: `Europe/Madrid`)입니다. 기본값은 UTC입니다."
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "retrieve_summary",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_summary()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveSummary();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveSummary(ctx, didit.InvestigatorRetrieveSummaryParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveSummary();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->retrieveSummary();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_summary\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveSummaryAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/queue/": {
      "get": {
        "operationId": "investigator_queue",
        "summary": "Investigator 대기열 목록 조회",
        "description": "미해결 보고서 목록으로, **수락 준비 완료**가 먼저 표시된 후 마감 기한, 위험 및 대기 순으로 정렬됩니다. `counts`는 범위 내의 모든 종류를 포함합니다. `count`는 100개로 제한됩니다. 제한된 키에는 `decisions` 범위(읽기)가 필요하며, 거래 알림에는 `transactions`도 필요합니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "counts": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/InvestigatorQueueRow"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "scope",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "identity",
                "transactions"
              ],
              "default": "all"
            },
            "description": "`identity`(세션 및 거래 규칙으로 열리지 않은 케이스) 또는 `transactions`(거래 알림 및 거래 규칙으로 열린 케이스)입니다."
          },
          {
            "in": "query",
            "name": "kind",
            "schema": {
              "type": "string"
            },
            "description": "`session`, `business_session`, `transaction`, `case` 중 하나이거나 쉼표로 구분된 여러 개입니다."
          },
          {
            "in": "query",
            "name": "queue",
            "schema": {
              "type": "string",
              "enum": [
                "kyc",
                "kyb",
                "aml",
                "transactions",
                "cases"
              ]
            }
          },
          {
            "in": "query",
            "name": "recommendation",
            "schema": {
              "type": "string",
              "enum": [
                "approve",
                "decline",
                "escalate",
                "request"
              ]
            }
          },
          {
            "in": "query",
            "name": "confidence",
            "schema": {
              "type": "string",
              "enum": [
                "high",
                "moderate",
                "low"
              ]
            }
          },
          {
            "in": "query",
            "name": "ready",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "search",
            "schema": {
              "type": "string"
            },
            "description": "이름, 기업, 케이스 제목, 번호, 거래 ID 또는 항목 ID."
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "list_queue",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.investigator.list_queue():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.investigator.listQueue()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Investigator.ListQueueAutoPaging(ctx, didit.InvestigatorListQueueParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.investigator().listQueue()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->investigator->listQueue() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.investigator.list_queue.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Investigator.ListQueueAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/investigator/runs/{run_id}/": {
      "get": {
        "operationId": "investigator_run_retrieve",
        "summary": "Investigator 보고서 조회",
        "description": "한 번의 실행에 대한 전체 보고서입니다. 실행에 완료된 보고서가 없거나 해당 항목이 삭제된 경우 404를 반환합니다. 제한된 키에는 `decisions` 스코프(읽기)가 필요하며, 거래 알림에는 `transactions`도 필요합니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvestigatorRunDetail"
                }
              }
            }
          },
          "404": {
            "description": "찾을 수 없거나 보고서가 없습니다."
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "run_id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "retrieve_run",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_run(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveRun(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveRun(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveRun(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->retrieveRun('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_run(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveRunAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/runs/{run_id}/accept/": {
      "post": {
        "operationId": "investigator_run_accept",
        "summary": "권장 사항 수락",
        "description": "항목의 일반적인 경로를 통해 권장 작업을 적용하므로 일반 webhook이 트리거됩니다. `narrative`를 지정하면 수정 후 수락된 것으로 처리됩니다. 제한된 키에는 `decisions` 스코프(쓰기)가 필요하며, 거래 알림에는 `transactions`(쓰기)도 필요합니다. 인증 또는 거래를 에스컬레이션하면 케이스가 열립니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvestigatorDecision"
                }
              }
            }
          },
          "409": {
            "description": "이미 결정되었거나 보고서가 준비되지 않았거나 가드레일이 항목을 보류하고 있습니다."
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "run_id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvestigatorAcceptRequest"
              },
              "example": {
                "send_email": false
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "accept_run",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.accept_run(\n    \"11111111-2222-3333-4444-555555555555\",\n    send_email=False,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.acceptRun(\"11111111-2222-3333-4444-555555555555\", {\n  send_email: false,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.AcceptRun(ctx, \"11111111-2222-3333-4444-555555555555\", didit.InvestigatorAcceptRequest{\n\tSendEmail: didit.Bool(false),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.InvestigatorAcceptRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().acceptRun(\"11111111-2222-3333-4444-555555555555\", InvestigatorAcceptRequest.builder()\n        .sendEmail(false)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->acceptRun('11111111-2222-3333-4444-555555555555', [\n    'send_email' => false,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.accept_run(\n  \"11111111-2222-3333-4444-555555555555\",\n  send_email: false\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.AcceptRunAsync(\"11111111-2222-3333-4444-555555555555\", new InvestigatorAcceptRequest\n{\n    SendEmail = false,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/runs/{run_id}/override/": {
      "post": {
        "operationId": "investigator_run_override",
        "summary": "권장 사항 재정의",
        "description": "카테고리 및 사유와 함께 다른 작업을 수행합니다. 또한 조사관이 자체적으로 내린 결정이 여전히 유효한 동안 이를 재정의합니다. 제한된 키에는 `decisions` 스코프(쓰기)가 필요하며, 거래 알림에는 `transactions`(쓰기)도 필요합니다. 인증 또는 거래를 에스컬레이션하면 케이스가 열립니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvestigatorDecision"
                }
              }
            }
          },
          "409": {
            "description": "이미 결정되었거나 가드레일이 항목을 보류하고 있습니다."
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "run_id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvestigatorOverrideRequest"
              },
              "example": {
                "action": "decline",
                "category": "evidence_misread",
                "reason": "The proof of address is older than three months."
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "override_run",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.override_run(\n    \"11111111-2222-3333-4444-555555555555\",\n    action=\"decline\",\n    category=\"evidence_misread\",\n    reason=\"The proof of address is older than three months.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.overrideRun(\"11111111-2222-3333-4444-555555555555\", {\n  action: \"decline\",\n  category: \"evidence_misread\",\n  reason: \"The proof of address is older than three months.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.OverrideRun(ctx, \"11111111-2222-3333-4444-555555555555\", didit.InvestigatorOverrideRequest{\n\tAction:   \"decline\",\n\tCategory: \"evidence_misread\",\n\tReason:   \"The proof of address is older than three months.\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.InvestigatorOverrideRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().overrideRun(\"11111111-2222-3333-4444-555555555555\", InvestigatorOverrideRequest.builder()\n        .action(InvestigatorOverrideRequest.Action.of(\"decline\"))\n        .category(InvestigatorOverrideRequest.Category.of(\"evidence_misread\"))\n        .reason(\"The proof of address is older than three months.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->overrideRun('11111111-2222-3333-4444-555555555555', [\n    'action' => 'decline',\n    'category' => 'evidence_misread',\n    'reason' => 'The proof of address is older than three months.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.override_run(\n  \"11111111-2222-3333-4444-555555555555\",\n  action: \"decline\",\n  category: \"evidence_misread\",\n  reason: \"The proof of address is older than three months.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.OverrideRunAsync(\"11111111-2222-3333-4444-555555555555\", new InvestigatorOverrideRequest\n{\n    Action = \"decline\",\n    Category = \"evidence_misread\",\n    Reason = \"The proof of address is older than three months.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/runs/batch-accept/": {
      "post": {
        "operationId": "investigator_batch_accept",
        "summary": "추천 일괄 수락",
        "description": "수락 준비 완료로 표시된 보고서를 최대 50개까지 수락합니다. 각 보고서는 자체적인 결정으로 처리됩니다. 수락할 수 없는 항목은 사유와 함께 건너뜁니다. 제한된 키에는 `decisions` 스코프(쓰기)가 필요하며, 거래 알림에는 `transactions`(쓰기)도 필요합니다. 인증 또는 거래를 에스컬레이션하면 케이스가 열립니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvestigatorBatchAcceptResponse"
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvestigatorBatchAcceptRequest"
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "batch_accept_runs",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.batch_accept_runs(\n    run_ids=[\"11111111-2222-3333-4444-555555555555\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.batchAcceptRuns({\n  run_ids: [\"11111111-2222-3333-4444-555555555555\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.BatchAcceptRuns(ctx, didit.InvestigatorBatchAcceptRequest{\n\tRunIDs: []string{\"11111111-2222-3333-4444-555555555555\"},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.InvestigatorBatchAcceptRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().batchAcceptRuns(InvestigatorBatchAcceptRequest.builder()\n        .runIds(List.of(\"11111111-2222-3333-4444-555555555555\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->batchAcceptRuns([\n    'run_ids' => ['11111111-2222-3333-4444-555555555555'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.batch_accept_runs(run_ids: [\"11111111-2222-3333-4444-555555555555\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.BatchAcceptRunsAsync(new InvestigatorBatchAcceptRequest\n{\n    RunIds = new string[] { \"11111111-2222-3333-4444-555555555555\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/transactions/{transaction_id}/": {
      "get": {
        "operationId": "investigator_transaction_retrieve",
        "summary": "거래의 Investigator 검토 조회",
        "description": "거래의 최근 검토 내역이며, 검토 내역이 없는 경우 `investigator: null`입니다. 제한된 키에는 `decisions` 및 `transactions` 스코프(읽기)가 필요합니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transaction_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "investigator": {
                      "$ref": "#/components/schemas/InvestigatorBlock"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "이 애플리케이션의 거래가 아닙니다."
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "transaction_id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "retrieve_transaction",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_transaction(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveTransaction(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveTransaction(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveTransaction(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->retrieveTransaction('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_transaction(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveTransactionAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/guardrails/": {
      "get": {
        "operationId": "investigator_guardrails",
        "summary": "잠긴 가드레일 목록 조회",
        "description": "모든 대기열에 적용되는 다섯 가지 안전 장치입니다. 비활성화할 수 없습니다. 제한된 키에는 `decisions` 스코프(읽기)가 필요하며, 거래 알림에는 `transactions`도 필요합니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string",
                            "enum": [
                              "sanctions_to_person",
                              "no_tipping_off",
                              "no_protected_characteristics",
                              "never_files_reports",
                              "every_decision_logged"
                            ]
                          },
                          "title": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "locked": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "list_guardrails",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.list_guardrails()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.listGuardrails();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.ListGuardrails(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().listGuardrails();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->listGuardrails();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.list_guardrails\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.ListGuardrailsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/dashboard/": {
      "get": {
        "operationId": "investigator_dashboard",
        "summary": "조사관 대시보드",
        "description": "최근 30일 데이터: 검토, 결정, 자동화율, 절감된 시간, 지출, 재정의, 서비스 개시 이후 품질 샘플, 대기열별 및 주별 수치입니다. 제한된 키에는 `decisions` 스코프(읽기)가 필요하며, 거래 알림에는 `transactions`도 필요합니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "stage": {
                      "type": "string"
                    },
                    "window_days": {
                      "type": "integer"
                    },
                    "reviews": {
                      "type": "integer"
                    },
                    "decided": {
                      "type": "integer"
                    },
                    "automated": {
                      "type": "integer"
                    },
                    "automation_rate": {
                      "type": "number",
                      "nullable": true
                    },
                    "hours_saved": {
                      "type": "number",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "scope",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "identity",
                "transactions"
              ],
              "default": "all"
            },
            "description": "`identity`(세션 및 거래 규칙으로 열리지 않은 케이스) 또는 `transactions`(거래 알림 및 거래 규칙으로 열린 케이스)입니다."
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "retrieve_dashboard",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_dashboard()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveDashboard();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveDashboard(ctx, didit.InvestigatorRetrieveDashboardParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveDashboard();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->retrieveDashboard();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_dashboard\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveDashboardAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/performance/": {
      "get": {
        "operationId": "investigator_performance",
        "summary": "조사관 성과",
        "description": "특정 기간 동안의 팀과의 일치율, 처리량, 절약된 시간, 신뢰도 보정, 대기열별 결과, 재정의 사유 및 불일치 내역입니다. 제한된 키에는 `decisions` 스코프(읽기)가 필요하며, 거래 알림에는 `transactions`도 필요합니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "period": {
                      "type": "integer"
                    },
                    "start": {
                      "type": "string",
                      "format": "date"
                    },
                    "end": {
                      "type": "string",
                      "format": "date"
                    },
                    "investigated": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "scope",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "identity",
                "transactions"
              ],
              "default": "all"
            },
            "description": "`identity`(세션 및 거래 규칙으로 열리지 않은 케이스) 또는 `transactions`(거래 알림 및 거래 규칙으로 열린 케이스)입니다."
          },
          {
            "in": "query",
            "name": "period",
            "schema": {
              "type": "string",
              "enum": [
                "7",
                "30",
                "90"
              ],
              "default": "30"
            },
            "description": "오늘로 끝나는 기간(일 수)."
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "retrieve_performance",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_performance()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrievePerformance();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrievePerformance(ctx, didit.InvestigatorRetrievePerformanceParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrievePerformance();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->retrievePerformance();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_performance\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrievePerformanceAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/activity/": {
      "get": {
        "operationId": "investigator_activity",
        "summary": "조사관 활동 목록 조회",
        "description": "추가 전용 감사 로그이며, 최신 항목이 먼저 표시됩니다. 일괄 수락은 하나의 항목으로 기록됩니다. 그룹별 `counts` 및 `actors`가 추가됩니다. 제한된 키에는 `decisions` 스코프(읽기)가 필요하며, 거래 알림에는 `transactions` 스코프도 필요합니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "counts": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "actors": {
                      "type": "array",
                      "items": {}
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "`id`, `at`, `kind`, `group`, `queue`, `run_id`, `item`, `actor`, `agent_version`, `data`, `report_version`, `steps`, `sources`, `batch`."
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "scope",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "identity",
                "transactions"
              ],
              "default": "all"
            },
            "description": "`identity`(세션 및 거래 규칙으로 열리지 않은 케이스) 또는 `transactions`(거래 알림 및 거래 규칙으로 열린 케이스)입니다."
          },
          {
            "in": "query",
            "name": "group",
            "schema": {
              "type": "string",
              "enum": [
                "agent",
                "decisions",
                "overrides",
                "autonomy"
              ]
            }
          },
          {
            "in": "query",
            "name": "actor",
            "schema": {
              "type": "string"
            },
            "description": "Investigator의 경우 `agent`이거나 개인의 이메일입니다."
          },
          {
            "in": "query",
            "name": "since",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "until",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "list_activity",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.investigator.list_activity():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.investigator.listActivity()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Investigator.ListActivityAutoPaging(ctx, didit.InvestigatorListActivityParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.investigator().listActivity()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->investigator->listActivity() as $item) {\n    print_r($item);\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.investigator.list_activity.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Investigator.ListActivityAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/investigator/activity/export/": {
      "get": {
        "operationId": "investigator_activity_export",
        "summary": "Investigator 활동 내역 내보내기",
        "description": "CSV와 동일한 항목으로, 결정당 한 행씩 최신순으로 정렬되며 최대 10,000개 항목까지 제공됩니다. 제한된 키에는 `decisions` 스코프(읽기)가 필요하며, 거래 알림에는 `transactions`도 필요합니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "scope",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "identity",
                "transactions"
              ],
              "default": "all"
            },
            "description": "`identity`(세션 및 거래 규칙으로 열리지 않은 케이스) 또는 `transactions`(거래 알림 및 거래 규칙으로 열린 케이스)입니다."
          },
          {
            "in": "query",
            "name": "group",
            "schema": {
              "type": "string",
              "enum": [
                "agent",
                "decisions",
                "overrides",
                "autonomy"
              ]
            }
          },
          {
            "in": "query",
            "name": "actor",
            "schema": {
              "type": "string"
            },
            "description": "Investigator의 경우 `agent`이거나 개인의 이메일입니다."
          },
          {
            "in": "query",
            "name": "since",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "until",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "export_activity",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.investigator.export_activity()\nwith open(\"download.csv\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.investigator.exportActivity();\nawait writeFile(\"download.csv\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Investigator.ExportActivity(ctx, didit.InvestigatorExportActivityParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.csv\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.investigator().exportActivity()\n        .writeTo(Path.of(\"download.csv\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->investigator->exportActivity();\n$content->saveTo('download.csv');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.investigator.export_activity\nFile.binwrite(\"download.csv\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Investigator.ExportActivityAsync();\nawait content.SaveToAsync(\"download.csv\");"
          }
        ]
      }
    },
    "/v3/investigator/settings/": {
      "get": {
        "operationId": "investigator_settings_retrieve",
        "summary": "Investigator 설정 조회",
        "description": "단계(`none`, `shadow` 또는 `live`)와 이번 달 지출액이 포함된 월간 지출 한도입니다. 제한된 키에는 `applications` 스코프(읽기)가 필요합니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvestigatorSettings"
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "retrieve_settings",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_settings()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveSettings();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveSettings(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveSettings();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->retrieveSettings();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_settings\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveSettingsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "patch": {
        "operationId": "investigator_settings_update",
        "summary": "조사관 설정 업데이트",
        "description": "단계를 변경하거나 월간 지출 한도를 변경하거나 둘 다 변경합니다. `none`을 벗어나려면 Investigator가 포함된 요금제(Growth 이상)가 필요하며, `live` 단계의 경우 가격이 책정된 계약이 있는 경우 해당 계약도 필요합니다. 제한된 키에는 `applications` 스코프(쓰기)가 필요합니다.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvestigatorSettings"
                }
              }
            }
          },
          "400": {
            "description": "두 필드가 모두 전송되지 않았거나 유효하지 않은 값입니다."
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "키에 스코프가 없거나 항목 종류를 읽을 수 없거나 요금제에 Investigator가 포함되어 있지 않습니다."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvestigatorSettings"
              },
              "example": {
                "stage": "shadow",
                "monthly_spend_limit": "500.00"
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "update_settings",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.update_settings(\n    stage=\"shadow\",\n    monthly_spend_limit=\"500.00\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.updateSettings({\n  stage: \"shadow\",\n  monthly_spend_limit: \"500.00\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.UpdateSettings(ctx, didit.InvestigatorSettingsParam{\n\tStage:             didit.Some(didit.InvestigatorSettingsStage(\"shadow\")),\n\tMonthlySpendLimit: didit.String(\"500.00\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.InvestigatorSettings;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().updateSettings(InvestigatorSettings.builder()\n        .stage(InvestigatorSettings.Stage.of(\"shadow\"))\n        .monthlySpendLimit(\"500.00\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->updateSettings([\n    'stage' => 'shadow',\n    'monthly_spend_limit' => '500.00',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.update_settings(\n  stage: \"shadow\",\n  monthly_spend_limit: \"500.00\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.UpdateSettingsAsync(new InvestigatorSettings\n{\n    Stage = new InvestigatorSettingsStage(\"shadow\"),\n    MonthlySpendLimit = \"500.00\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/travel-rule/wallet-addresses/import/": {
      "post": {
        "summary": "지갑 주소 일괄 가져오기",
        "description": "JSON 또는 CSV 파일로 한 번의 호출에 최대 10,000개의 지갑을 Travel Rule 주소록에 추가합니다. 지갑은 주소 자체로 전송하거나 주소를 비공개로 유지하기 위해 소문자로 변환된 주소의 SHA-256(`address_hash`)으로 전송하거나 둘 다로 전송할 수 있습니다. 가져오기는 멱등성이 있습니다. 주소록에 이미 존재하는 지갑은 `existing`으로 보고되며 변경되지 않으므로 동일한 파일을 다시 전송할 수 있습니다. 각 행은 개별적으로 검증되므로 잘못된 행 하나가 다른 행들을 실패하게 만들지 않습니다. 해시로 가져온 지갑은 해당 주소로의 송금과만 일치하며 다른 항목과 마찬가지로 지갑 소유권 위젯으로 증명할 수 있습니다.",
        "operationId": "importTravelRuleWalletAddresses",
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_addresses",
          "method": "bulk_import",
          "auth": "api_key",
          "server": true
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": [
                      "entries"
                    ],
                    "properties": {
                      "entries": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 10000,
                        "items": {
                          "$ref": "#/components/schemas/WalletAddressImportRow"
                        }
                      }
                    }
                  },
                  {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 10000,
                    "items": {
                      "$ref": "#/components/schemas/WalletAddressImportRow"
                    }
                  }
                ]
              },
              "example": {
                "entries": [
                  {
                    "address": "0xBeneficiaryWallet01",
                    "chain": "ETH",
                    "holder_name": "Ana Diaz",
                    "holder_vendor_data": "user-042"
                  },
                  {
                    "address_hash": "4f7d2e1c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e",
                    "chain": "bitcoin",
                    "holder_vendor_data": "user-043"
                  },
                  {
                    "address": "rExchangeSharedAddress01",
                    "chain": "XRP",
                    "memo": "104729",
                    "holder_name": "Ana Diaz"
                  }
                ]
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "열 이름이 행 필드 또는 해당 별칭으로 지정된 헤더 행이 포함된 최대 5MB 크기의 UTF-8 CSV 파일입니다. 빈 셀은 전송되지 않은 것으로 간주되며 가져오기에서 읽지 않는 열은 무시됩니다."
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl (JSON)",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/wallet-addresses/import/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"entries\": [{\"address\": \"0xBeneficiaryWallet01\", \"chain\": \"ETH\", \"holder_name\": \"Ana Diaz\"}, {\"address\": \"rExchangeSharedAddress01\", \"chain\": \"XRP\", \"memo\": \"104729\"}]}'"
          },
          {
            "lang": "curl",
            "label": "curl (CSV)",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/wallet-addresses/import/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'file=@wallets.csv;type=text/csv'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.wallet_addresses.bulk_import(\n    body={\n        \"entries\": [{\n            \"address\": \"0xBeneficiaryWallet01\",\n            \"chain\": \"ETH\",\n            \"holder_name\": \"Ana Diaz\",\n            \"holder_vendor_data\": \"user-042\",\n        }, {\n            \"address_hash\": \"4f7d2e1c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e\",\n            \"chain\": \"bitcoin\",\n            \"holder_vendor_data\": \"user-043\",\n        }, {\n            \"address\": \"rExchangeSharedAddress01\",\n            \"chain\": \"XRP\",\n            \"memo\": \"104729\",\n            \"holder_name\": \"Ana Diaz\",\n        }],\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.walletAddresses.bulkImport({\n  file: await fileFromPath(\"wallet-addresses.csv\"),\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.WalletAddresses.BulkImport(ctx, didit.TravelRuleWalletAddressesBulkImportParams{\n\tFile: didit.Some(didit.FileFromPath(\"wallet-addresses.csv\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.TravelRuleWalletAddressesBulkImportParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().walletAddresses().bulkImport(TravelRuleWalletAddressesBulkImportParams.builder()\n        .file(Path.of(\"wallet-addresses.csv\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->walletAddresses->bulkImport([\n    'file' => File::fromPath('wallet-addresses.csv'),\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.wallet_addresses.bulk_import(\n  body: {\n    entries: [{\n      address: \"0xBeneficiaryWallet01\",\n      chain: \"ETH\",\n      holder_name: \"Ana Diaz\",\n      holder_vendor_data: \"user-042\",\n    }, {\n      address_hash: \"4f7d2e1c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e\",\n      chain: \"bitcoin\",\n      holder_vendor_data: \"user-043\",\n    }, {\n      address: \"rExchangeSharedAddress01\",\n      chain: \"XRP\",\n      memo: \"104729\",\n      holder_name: \"Ana Diaz\",\n    }],\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.WalletAddresses.BulkImportAsync(new TravelRuleWalletAddressesBulkImportParams\n{\n    File = FileUpload.FromPath(\"wallet-addresses.csv\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "모든 행이 생성되었거나, 이미 장부에 있거나, 이전 행의 중복이었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletAddressImportReport"
                },
                "example": {
                  "total": 3,
                  "created": 2,
                  "existing": 1,
                  "duplicate": 0,
                  "failed": 0,
                  "rows": [
                    {
                      "row": 1,
                      "status": "existing",
                      "entry_id": "11111111-2222-3333-4444-555555555555",
                      "errors": {},
                      "duplicate_of_row": null
                    },
                    {
                      "row": 2,
                      "status": "created",
                      "entry_id": "22222222-3333-4444-5555-666666666666",
                      "errors": {},
                      "duplicate_of_row": null
                    },
                    {
                      "row": 3,
                      "status": "created",
                      "entry_id": "33333333-4444-5555-6666-777777777777",
                      "errors": {},
                      "duplicate_of_row": null
                    }
                  ]
                }
              }
            }
          },
          "207": {
            "description": "최소 하나의 행이 실패했으며, 나머지 행은 가져왔습니다. 실패한 각 행에는 해당 오류가 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletAddressImportReport"
                },
                "example": {
                  "total": 2,
                  "created": 1,
                  "existing": 0,
                  "duplicate": 0,
                  "failed": 1,
                  "rows": [
                    {
                      "row": 1,
                      "status": "created",
                      "entry_id": "44444444-5555-6666-7777-888888888888",
                      "errors": {},
                      "duplicate_of_row": null
                    },
                    {
                      "row": 2,
                      "status": "failed",
                      "entry_id": null,
                      "errors": {
                        "address": [
                          "Send address, address_hash or both."
                        ]
                      },
                      "duplicate_of_row": null
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "요청 자체를 읽을 수 없습니다. `entries`와 `file`이 둘 다 있거나 둘 다 없는 경우, 10,000개 이상의 행인 경우, 파일 크기가 5MB를 초과하는 경우, UTF-8 CSV가 아닌 경우, 헤더 행이 없거나 데이터 행이 없는 경우 등이 해당됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "file": [
                    "At most 10000 rows per import."
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/counterparty-contacts/": {
      "get": {
        "summary": "거래 상대방 연락처 목록 조회",
        "description": "EMAIL 레일이 애플리케이션을 위해 발송할 수 있는 컴플라이언스 주소 목록입니다. Didit의 플랫폼 연락처와 애플리케이션 자체 프라이빗 연락처가 포함되며, 반송된 주소도 포함되고 최신순으로 정렬됩니다. `limit`(기본값 50) 및 `offset`으로 페이지네이션되며, `count`는 100에서 멈추므로 100은 100개 이상을 의미합니다.",
        "operationId": "listTravelRuleCounterpartyContacts",
        "x-didit-sdk": {
          "resource": "travel_rule.counterparty_contacts",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "counterparty",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "이 디렉터리 항목의 연락처만 해당합니다. UUID여야 하며, 빈 값은 필터가 없음을 의미합니다."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "페이지 크기, 기본값 50입니다."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "건너뛸 행."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/travel-rule/counterparty-contacts/?counterparty={vasp_id}' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.counterparty_contacts.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.counterpartyContacts.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.CounterpartyContacts.ListAutoPaging(ctx, didit.TravelRuleCounterpartyContactsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().counterpartyContacts().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->travelRule->counterpartyContacts->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.counterparty_contacts.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.CounterpartyContacts.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "연락처입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TravelRuleCounterpartyContact"
                      }
                    }
                  }
                },
                "example": {
                  "count": 1,
                  "next": null,
                  "previous": null,
                  "results": [
                    {
                      "uuid": "6c1f9b8e-2d4a-4f7e-8b3c-5a9d0e1f2a3b",
                      "counterparty": "0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91",
                      "counterparty_name": "Example Counterparty VASP",
                      "email": "compliance@counterparty.example",
                      "name": "Compliance desk",
                      "source": "application",
                      "scope": "application",
                      "created_by": "",
                      "verified_at": null,
                      "is_invalid": false,
                      "invalid_reason": "",
                      "invalid_detail": "",
                      "invalid_at": null,
                      "created_at": "2026-10-19T09:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`counterparty`가 UUID 형식이 아닙니다.",
            "content": {
              "application/json": {
                "example": {
                  "counterparty": [
                    "Must be a valid UUID."
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "거래 상대방 연락처 추가",
        "description": "하나의 디렉터리 항목에 비공개 컴플라이언스 주소를 추가합니다. 귀하의 애플리케이션만 이를 조회하고 사용할 수 있으며, EMAIL 레일은 플랫폼 연락처보다 먼저 이 주소로 전송합니다. 해당 항목이 귀하의 연락처에 이미 보유하고 있는 주소를 추가하면 해당 연락처가 반환됩니다.",
        "operationId": "createTravelRuleCounterpartyContact",
        "x-didit-sdk": {
          "resource": "travel_rule.counterparty_contacts",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleCounterpartyContactCreate"
              },
              "example": {
                "counterparty": "0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91",
                "email": "compliance@counterparty.example",
                "name": "Compliance desk"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/counterparty-contacts/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"counterparty\": \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\", \"email\": \"compliance@counterparty.example\", \"name\": \"Compliance desk\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.counterparty_contacts.create(\n    counterparty=\"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n    email=\"compliance@counterparty.example\",\n    name=\"Compliance desk\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.counterpartyContacts.create({\n  counterparty: \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n  email: \"compliance@counterparty.example\",\n  name: \"Compliance desk\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.CounterpartyContacts.Create(ctx, didit.TravelRuleCounterpartyContactCreate{\n\tCounterparty: \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n\tEmail:        \"compliance@counterparty.example\",\n\tName:         didit.String(\"Compliance desk\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleCounterpartyContactCreate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().counterpartyContacts().create(TravelRuleCounterpartyContactCreate.builder()\n        .counterparty(\"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\")\n        .email(\"compliance@counterparty.example\")\n        .name(\"Compliance desk\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->counterpartyContacts->create([\n    'counterparty' => '0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91',\n    'email' => 'compliance@counterparty.example',\n    'name' => 'Compliance desk',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.counterparty_contacts.create(\n  counterparty: \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n  email: \"compliance@counterparty.example\",\n  name: \"Compliance desk\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.CounterpartyContacts.CreateAsync(new TravelRuleCounterpartyContactCreate\n{\n    Counterparty = \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n    Email = \"compliance@counterparty.example\",\n    Name = \"Compliance desk\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "연락처가 추가되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyContact"
                },
                "example": {
                  "uuid": "6c1f9b8e-2d4a-4f7e-8b3c-5a9d0e1f2a3b",
                  "counterparty": "0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91",
                  "counterparty_name": "Example Counterparty VASP",
                  "email": "compliance@counterparty.example",
                  "name": "Compliance desk",
                  "source": "application",
                  "scope": "application",
                  "created_by": "",
                  "verified_at": null,
                  "is_invalid": false,
                  "invalid_reason": "",
                  "invalid_detail": "",
                  "invalid_at": null,
                  "created_at": "2026-10-19T09:00:00Z"
                }
              }
            }
          },
          "400": {
            "description": "필드가 누락되었거나 유효하지 않거나, 이 ID를 가진 디렉터리 항목이 없습니다.",
            "content": {
              "application/json": {
                "example": {
                  "counterparty": [
                    "No directory entry with this id."
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/counterparty-contacts/{contact_uuid}/": {
      "delete": {
        "summary": "거래 상대방 연락처를 삭제합니다.",
        "description": "애플리케이션 자체 연락처 중 하나를 삭제합니다. EMAIL 레일은 즉시 해당 연락처로의 발송을 중단합니다. 플랫폼 연락처는 삭제할 수 없습니다.",
        "operationId": "deleteTravelRuleCounterpartyContact",
        "x-didit-sdk": {
          "resource": "travel_rule.counterparty_contacts",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "contact_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE https://verification.didit.me/v3/travel-rule/counterparty-contacts/{contact_uuid}/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.travel_rule.counterparty_contacts.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.travelRule.counterpartyContacts.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.TravelRule.CounterpartyContacts.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.travelRule().counterpartyContacts().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->travelRule->counterpartyContacts->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.counterparty_contacts.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.TravelRule.CounterpartyContacts.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ],
        "responses": {
          "204": {
            "description": "삭제되었습니다."
          },
          "404": {
            "description": "귀하의 애플리케이션에 이 id를 가진 연락처가 없습니다. 플랫폼 연락처도 404를 반환합니다."
          }
        }
      }
    },
    "/v3/travel-rule/transfers/": {
      "get": {
        "summary": "Travel Rule 전송 목록 조회",
        "description": "귀하 애플리케이션의 Travel Rule 전송 내역으로, 최신순으로 정렬되며 `limit`(기본값 50) 및 `offset`으로 페이지네이션됩니다. 행에는 VASP 이름, 지갑, 메모만 포함되며 개인 데이터는 절대 포함되지 않습니다. 쉼표로 구분된 값을 통해 여러 항목을 선택할 수 있습니다. 알 수 없는 값이 전달되면 파라미터 이름을 명시하여 400으로 응답합니다(예: `{\"direction\": [\"Unknown value(s): inbound.\"]}`).",
        "operationId": "listTravelRuleTransfers",
        "x-didit-sdk": {
          "resource": "travel_rule.transfers",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "direction",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "INBOUND, OUTBOUND 또는 쉼표로 구분한 두 값입니다. 대소문자를 구분합니다."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "하나 이상의 전송 상태(쉼표로 구분)입니다."
          },
          {
            "name": "rail",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "INTERNAL, TRP, GTR, TRUST, VERIFYVASP, SYGNA, EMAIL, TEST_VASP 중 하나 이상(쉼표로 구분)입니다."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "쉼표로 구분된 withdrawal, deposit 또는 message입니다."
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "거래의 통화(대소문자 구분 없음)입니다."
          },
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "이 날짜(UTC) 당일 또는 이후에 생성된 이체입니다(YYYY-MM-DD)."
          },
          {
            "name": "end_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "이 날짜(UTC) 당일 또는 이전에 생성된 이체입니다(YYYY-MM-DD)."
          },
          {
            "name": "counterparty",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "GET /v3/travel-rule/vasps/의 디렉터리 항목 또는 Didit 네트워크 멤버의 `id`입니다. 해당 거래 상대방과의 전송에 사용됩니다. 유효한 id가 아닌 값은 400을 반환합니다."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "페이지 크기, 기본값 50입니다."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "건너뛸 행."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/travel-rule/transfers/?direction=OUTBOUND&status=AWAITING_COUNTERPARTY' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.transfers.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.transfers.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.Transfers.ListAutoPaging(ctx, didit.TravelRuleTransfersListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().transfers().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->travelRule->transfers->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.transfers.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.Transfers.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "이체 페이지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TravelRuleTransferRow"
                      }
                    }
                  }
                },
                "example": {
                  "count": 1,
                  "next": null,
                  "previous": null,
                  "results": [
                    {
                      "id": "5b0f6c2e-2a4d-4f0e-9a41-0c3f9a7e1d22",
                      "transaction_id": "a3c1e8f4-7b62-4d1a-8e0b-2f9d6c4b7a10",
                      "txn_id": "wd-2026-10-19-0042",
                      "txn_date": "2026-10-19T08:41:12Z",
                      "kind": "withdrawal",
                      "direction": "OUTBOUND",
                      "status": "AWAITING_COUNTERPARTY",
                      "rail": "TRP",
                      "asset": "ETH",
                      "amount": "1.25",
                      "originator_vasp": "Origin CASP SL",
                      "beneficiary_vasp": "Example Counterparty VASP",
                      "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7",
                      "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
                      "originator_memo": "",
                      "beneficiary_memo": "",
                      "originator_wallet_type": "vasp",
                      "beneficiary_wallet_type": "vasp",
                      "matched_transaction_id": null,
                      "deadline_at": "2026-10-21T08:41:13Z",
                      "created_at": "2026-10-19T08:41:13Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "필터 값이 유효하지 않습니다.",
            "content": {
              "application/json": {
                "example": {
                  "start_date": [
                    "Use the YYYY-MM-DD format."
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v3/session/imports/providers/": {
      "get": {
        "summary": "마이그레이션 제공업체 목록 조회",
        "description": "인증을 이전할 수 있는 15개 제공업체 목록입니다. 각 제공업체에 연결하는 데 필요한 항목, 해당 API의 레코드 나열 가능 여부, 키에 필요한 권한, 기본 상태 매핑을 안내합니다.",
        "operationId": "get_v3_session_imports_providers_list",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "list_providers",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "responses": {
          "200": {
            "description": "마이그레이션 제공업체입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "providers": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ImportProvider"
                      }
                    },
                    "mapping_targets": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "skipped_statuses": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 취소되었습니다. 또는 호출자가 이 애플리케이션에 대한 인증을 가져올 수 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.list_providers()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.listProviders();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.ListProviders(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().listProviders();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->listProviders();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.list_providers\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.ListProvidersAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/providers/check/": {
      "post": {
        "summary": "공급자 키 확인",
        "description": "마이그레이션을 생성하기 전에 해당 키로 공급자를 조회합니다. 아무것도 저장되지 않습니다.",
        "operationId": "post_v3_session_imports_providers_check",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "check_provider",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "provider": {
                    "type": "string",
                    "enum": [
                      "sumsub",
                      "jumio",
                      "veriff",
                      "onfido",
                      "persona",
                      "metamap",
                      "socure",
                      "idnow",
                      "shufti",
                      "idenfy",
                      "ondato",
                      "trulioo",
                      "au10tix",
                      "complycube",
                      "other"
                    ],
                    "description": "`GET /v3/session/imports/providers/`에서 가져온 마이그레이션 소스입니다. `source`가 `provider`인 경우 필수입니다."
                  },
                  "credentials": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "`credential_fields`에 나열된 필드 이름을 포함하는 공급자의 읽기 전용 키입니다. 저장 시 암호화되고, 반환되지 않으며, 가져오기가 끝나면 삭제됩니다. multipart에서 JSON 문자열로 전송하십시오."
                  },
                  "options": {
                    "type": "object",
                    "properties": {
                      "region": {
                        "type": "string",
                        "description": "해당 `regions` 중 하나인 공급자 리전입니다(Onfido: `eu`, `us`, `ca`)."
                      }
                    }
                  },
                  "record_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "`api_ids` 제공업체의 경우: 내보내기의 첫 번째 레코드 ID입니다."
                  }
                },
                "required": [
                  "provider",
                  "credentials"
                ]
              },
              "example": {
                "provider": "sumsub",
                "credentials": {
                  "app_token": "YOUR_PROVIDER_APP_TOKEN",
                  "secret_key": "YOUR_PROVIDER_SECRET_KEY"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "키가 레코드를 읽을 수 있습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "provider": {
                      "type": "string"
                    },
                    "credential_hint": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "공급자가 키를 거부했습니다: `code`, `detail`, `missing_permissions`, `suggested_region`."
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 취소되었습니다. 또는 호출자가 이 애플리케이션에 대한 인증을 가져올 수 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.check_provider(\n    provider=\"sumsub\",\n    credentials={\"app_token\": \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\": \"YOUR_PROVIDER_SECRET_KEY\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.checkProvider({\n  provider: \"sumsub\",\n  credentials: { app_token: \"YOUR_PROVIDER_APP_TOKEN\", secret_key: \"YOUR_PROVIDER_SECRET_KEY\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.CheckProvider(ctx, didit.SessionsImportsCheckProviderParams{\n\tProvider:    \"sumsub\",\n\tCredentials: map[string]string{\"app_token\": \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\": \"YOUR_PROVIDER_SECRET_KEY\"},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsImportsCheckProviderParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().checkProvider(SessionsImportsCheckProviderParams.builder()\n        .provider(SessionsImportsCheckProviderParams.Provider.of(\"sumsub\"))\n        .credentials(Map.of(\"app_token\", \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\", \"YOUR_PROVIDER_SECRET_KEY\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->checkProvider([\n    'provider' => 'sumsub',\n    'credentials' => ['app_token' => 'YOUR_PROVIDER_APP_TOKEN', 'secret_key' => 'YOUR_PROVIDER_SECRET_KEY'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.check_provider(\n  provider: \"sumsub\",\n  credentials: { app_token: \"YOUR_PROVIDER_APP_TOKEN\", secret_key: \"YOUR_PROVIDER_SECRET_KEY\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.CheckProviderAsync(new SessionsImportsCheckProviderParams\n{\n    Provider = \"sumsub\",\n    Credentials = new Dictionary<string, string> { [\"app_token\"] = \"YOUR_PROVIDER_APP_TOKEN\", [\"secret_key\"] = \"YOUR_PROVIDER_SECRET_KEY\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/start/": {
      "post": {
        "summary": "드라이 런 시작",
        "description": "드라이 런이 완료된(`READY`) 마이그레이션을 시작합니다. 동일한 작업이 지금 전송된 상태 매핑 및 얼굴 템플릿 선택에 따라 실제로 가져오기를 수행합니다.",
        "operationId": "post_v3_session_imports_start",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "start",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status_mapping": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string",
                      "enum": [
                        "Approved",
                        "Declined",
                        "In Review",
                        "Expired",
                        "Not Finished",
                        "Abandoned"
                      ]
                    },
                    "description": "제공업체의 기본 상태 매핑(소스 상태에서 Didit 상태로)을 수정합니다. `Not Finished` 및 `Abandoned`는 건너뛰고 카운트되며 가져오지 않습니다."
                  },
                  "face_templates": {
                    "type": "boolean",
                    "default": false,
                    "description": "가져온 셀피로 얼굴 템플릿을 생성하고 애플리케이션의 얼굴 및 차단 목록과 대조하여 검색합니다. 일치 항목은 검토용으로만 플래그가 지정됩니다. `lawful_basis_confirmed`가 필요합니다."
                  },
                  "lawful_basis_confirmed": {
                    "type": "boolean",
                    "default": false,
                    "description": "처리자로서 Didit과 해당 셀피를 공유할 수 있는 적법한 근거가 있음을 확인합니다."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "가져오기 작업입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                }
              }
            }
          },
          "400": {
            "description": "작업이 해당 작업을 적용할 수 있는 상태가 아닙니다."
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 취소되었습니다. 또는 호출자가 이 애플리케이션에 대한 인증을 가져올 수 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.start(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.start(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Start(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsImportsStartParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().start(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->start('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.start(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.StartAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/pause/": {
      "post": {
        "summary": "가져오기 작업 일시 중지",
        "description": "대기열에 있거나 실행 중인 가져오기를 일시 중지합니다.",
        "operationId": "post_v3_session_imports_pause",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "pause",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "가져오기 작업입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                }
              }
            }
          },
          "400": {
            "description": "작업이 해당 작업을 적용할 수 있는 상태가 아닙니다."
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 취소되었습니다. 또는 호출자가 이 애플리케이션에 대한 인증을 가져올 수 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.pause(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.pause(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Pause(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().pause(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->pause('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.pause(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.PauseAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/resume/": {
      "post": {
        "summary": "가져오기 작업 재개",
        "description": "일시 중지한 가져오기를 재개합니다. 공급업체의 속도 제한으로 인해 일시 중지된 작업은 자동으로 재개됩니다.",
        "operationId": "post_v3_session_imports_resume",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "resume",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "가져오기 작업입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                }
              }
            }
          },
          "400": {
            "description": "작업이 해당 작업을 적용할 수 있는 상태가 아닙니다."
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 취소되었습니다. 또는 호출자가 이 애플리케이션에 대한 인증을 가져올 수 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.resume(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.resume(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Resume(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().resume(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->resume('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.resume(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.ResumeAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/cancel/": {
      "post": {
        "summary": "가져오기 작업 취소",
        "description": "가져오기를 취소합니다. 이미 가져온 데이터는 유지되며, 업로드된 파일과 키는 삭제됩니다.",
        "operationId": "post_v3_session_imports_cancel",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "cancel",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "가져오기 작업입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                }
              }
            }
          },
          "400": {
            "description": "작업이 해당 작업을 적용할 수 있는 상태가 아닙니다."
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 취소되었습니다. 또는 호출자가 이 애플리케이션에 대한 인증을 가져올 수 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.cancel(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.cancel(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Cancel(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().cancel(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->cancel('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.cancel(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.CancelAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/retry/": {
      "post": {
        "summary": "마이그레이션 재시도",
        "description": "새 키(이전 키는 삭제됨)를 사용하여 종료된 마이그레이션을 새 작업으로 다시 실행합니다. 공급자, 워크플로, 리전, 상태 매핑 및 얼굴 템플릿 선택 항목은 유지되며, Didit에 이미 존재하는 모든 항목은 건너뜁니다.",
        "operationId": "post_v3_session_imports_retry",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "retry",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "credentials": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "`credential_fields`에 나열된 필드 이름을 포함하는 공급자의 읽기 전용 키입니다. 저장 시 암호화되고, 반환되지 않으며, 가져오기가 끝나면 삭제됩니다. multipart에서 JSON 문자열로 전송하십시오."
                  },
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "`api_ids` 및 `export_file` 공급자의 레코드 ID 또는 내보내기 파일(다시 반환됨)입니다."
                  }
                }
              },
              "example": {
                "credentials": {
                  "app_token": "YOUR_PROVIDER_APP_TOKEN",
                  "secret_key": "YOUR_PROVIDER_SECRET_KEY"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "새로운 가져오기 작업입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                }
              }
            }
          },
          "400": {
            "description": "마이그레이션이 아니거나, 종료되지 않았거나, 제공업체가 키를 거부했습니다."
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 취소되었습니다. 또는 호출자가 이 애플리케이션에 대한 인증을 가져올 수 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.retry(\n    \"11111111-2222-3333-4444-555555555555\",\n    credentials={\"app_token\": \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\": \"YOUR_PROVIDER_SECRET_KEY\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.retry(\"11111111-2222-3333-4444-555555555555\", {\n  credentials: { app_token: \"YOUR_PROVIDER_APP_TOKEN\", secret_key: \"YOUR_PROVIDER_SECRET_KEY\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Retry(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsImportsRetryParams{\n\tCredentials: didit.Some(map[string]string{\"app_token\": \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\": \"YOUR_PROVIDER_SECRET_KEY\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsImportsRetryParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().retry(\"11111111-2222-3333-4444-555555555555\", SessionsImportsRetryParams.builder()\n        .credentials(Map.of(\"app_token\", \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\", \"YOUR_PROVIDER_SECRET_KEY\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->retry('11111111-2222-3333-4444-555555555555', [\n    'credentials' => ['app_token' => 'YOUR_PROVIDER_APP_TOKEN', 'secret_key' => 'YOUR_PROVIDER_SECRET_KEY'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.retry(\n  \"11111111-2222-3333-4444-555555555555\",\n  credentials: { app_token: \"YOUR_PROVIDER_APP_TOKEN\", secret_key: \"YOUR_PROVIDER_SECRET_KEY\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.RetryAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsImportsRetryParams\n{\n    Credentials = new Dictionary<string, string> { [\"app_token\"] = \"YOUR_PROVIDER_APP_TOKEN\", [\"secret_key\"] = \"YOUR_PROVIDER_SECRET_KEY\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/import-jobs/": {
      "get": {
        "summary": "가져오기 작업 목록 조회",
        "description": "단일 형식으로 된 애플리케이션의 모든 가져오기 내역(인증 가져오기 및 마이그레이션, 개인 및 기업)입니다.",
        "operationId": "get_v3_import_jobs_list",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "list_jobs",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "scope",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "sessions",
                "users",
                "businesses"
              ],
              "default": "all"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "가져오기 작업 목록이며, 최신순으로 정렬됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ImportJobSummary"
                      }
                    },
                    "counts": {
                      "type": "object",
                      "properties": {
                        "all": {
                          "type": "integer"
                        },
                        "running_and_waiting": {
                          "type": "integer"
                        },
                        "needs_attention": {
                          "type": "integer"
                        },
                        "done": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 취소되었습니다. 또는 호출자가 이 애플리케이션에 대한 인증을 가져올 수 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.list_jobs()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.listJobs();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.ListJobs(ctx, didit.SessionsImportsListJobsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().listJobs();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->listJobs();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.list_jobs\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.ListJobsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/import-jobs/active/": {
      "get": {
        "summary": "활성 가져오기 작업 목록 조회",
        "description": "진행률 표시기를 위한 실행 중이거나 대기 중인 항목 및 방금 종료된 항목입니다.",
        "operationId": "get_v3_import_jobs_active",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "list_active_jobs",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "responses": {
          "200": {
            "description": "활성 가져오기 작업입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ImportJobSummary"
                      }
                    },
                    "running": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API 키가 누락되었거나 유효하지 않거나 취소되었습니다. 또는 호출자가 이 애플리케이션에 대한 인증을 가져올 수 없습니다.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.list_active_jobs()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.listActiveJobs();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.ListActiveJobs(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().listActiveJobs();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->listActiveJobs();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.list_active_jobs\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.ListActiveJobsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/transactions/delete/": {
      "delete": {
        "summary": "거래 일괄 삭제",
        "description": "하나 이상의 거래를 영구적으로 삭제합니다. `transaction_uuids`로 선택하거나, `delete_all: true`로 애플리케이션의 모든 거래를 삭제할 수 있습니다.\n\n삭제된 거래는 해당 거래 전용 레코드와 함께 삭제됩니다: 당사자, 태그, 메모, 결제 수단 링크, 문서 및 해당 파일의 모든 저장된 버전, 규칙 실행 내역, 알림, 제공업체 결과, 네트워크 스냅샷 및 Travel Rule 데이터. 케이스, 인물 및 기업은 유지되며, 삭제된 거래와의 연결만 해제됩니다. 규제 보고서 초안에는 해당 거래가 더 이상 나열되지 않으며 이를 제외하고 다시 생성됩니다. 삭제는 영구적이며 취소할 수 없습니다. 실행 취소 endpoint는 제공되지 않습니다.\n\n선택한 거래 중 하나라도 확정된 규제 보고서에 포함되어 있다면 전체 요청이 `409`와 함께 거부되며 아무것도 삭제되지 않습니다. 응답 본문은 `code: in_filed_report`를 사용하며 각 거래 및 해당 거래가 포함된 보고서 이름을 명시합니다. 해당 보고서를 삭제한 후 요청을 다시 시도하십시오.",
        "operationId": "batch_delete_transactions",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "batch_delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "조직 UUID입니다."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "애플리케이션 UUID입니다."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "oneOf": [
                  {
                    "title": "Selected transactions",
                    "required": [
                      "transaction_uuids"
                    ],
                    "properties": {
                      "transaction_uuids": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "description": "삭제할 Didit 거래 UUID입니다. `delete_all`이 true가 아닌 경우 필수입니다.",
                        "minItems": 1
                      },
                      "delete_all": {
                        "type": "boolean",
                        "enum": [
                          false
                        ],
                        "default": false,
                        "description": "`transaction_uuids`로 거래를 선택할 때는 제외하거나 `false`를 전송하세요."
                      }
                    }
                  },
                  {
                    "title": "All transactions",
                    "required": [
                      "delete_all"
                    ],
                    "properties": {
                      "delete_all": {
                        "type": "boolean",
                        "enum": [
                          true
                        ],
                        "description": "애플리케이션의 모든 거래를 삭제합니다. `transaction_uuids`는 무시됩니다."
                      },
                      "transaction_uuids": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "description": "`delete_all`이 true일 때는 무시됩니다."
                      }
                    }
                  }
                ]
              },
              "examples": {
                "Selected transactions": {
                  "value": {
                    "transaction_uuids": [
                      "abcdef12-3456-7890-abcd-ef1234567890",
                      "12345678-90ab-cdef-1234-567890abcdef"
                    ]
                  }
                },
                "All transactions": {
                  "value": {
                    "delete_all": true
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl (selected transactions)",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/transactions/delete/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"transaction_uuids\": [\"abcdef12-3456-7890-abcd-ef1234567890\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.transactions.batch_delete(\n    body={\n        \"transaction_uuids\": [\"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\"],\n    },\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.transactions.batchDelete({\n  transaction_uuids: [\"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\"],\n});"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.TransactionsBatchDeleteParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.transactions().batchDelete(TransactionsBatchDeleteParams.builder()\n        .putAdditionalProperty(\"transaction_uuids\", List.of(\"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\"))\n        .build());"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->transactions->batchDelete([\n    'transaction_uuids' => ['abcdef12-3456-7890-abcd-ef1234567890', '12345678-90ab-cdef-1234-567890abcdef'],\n]);"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.transactions.batch_delete(\n  body: {\n    transaction_uuids: [\"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\"],\n  }\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Transactions.BatchDeleteAsync(new TransactionsBatchDeleteParams\n{\n    TransactionUuids = new string[] { \"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\" },\n});"
          }
        ],
        "responses": {
          "204": {
            "description": "선택한 거래가 삭제되었습니다."
          },
          "400": {
            "description": "거래 선택자가 제공되지 않았습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transaction_uuids": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "transaction_uuids": [
                    "This field is required unless delete_all is true."
                  ]
                }
              }
            }
          },
          "403": {
            "description": "API 키로 거래를 삭제할 수 없습니다. 이 엔드포인트에는 `write:transactions` 권한이 필요합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "선택한 거래 중 최소 하나가 확정된 규제 보고서에 포함되어 있습니다. 아무것도 삭제되지 않았습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InFiledReportError"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/travel-rule/networks/": {
      "get": {
        "summary": "Travel Rule 네트워크 조회",
        "description": "이 애플리케이션에 대해 모든 네트워크의 실제 상태를 조회합니다. 자체 멤버십을 통해 전송하는지, Didit의 멤버십을 통해 전송하는지, 아직 전송할 수 없다면 그 이유는 무엇인지 확인합니다. 실사 설문지와 참가자 목록도 함께 반환됩니다. 조회 시 아무것도 생성되지 않습니다.",
        "operationId": "getTravelRuleNetworks",
        "x-didit-sdk": {
          "resource": "travel_rule.networks",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/networks/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.retrieve()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.retrieve();\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().retrieve();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->networks->retrieve();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.retrieve\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.RetrieveAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "네트워크 상태, 설문지 및 참가자입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleNetworksOverview"
                },
                "examples": {
                  "Before the questionnaire": {
                    "value": {
                      "platform_networks_enabled": false,
                      "questionnaire": {
                        "status": "draft",
                        "answers": {},
                        "submitted_at": null,
                        "reviewed_at": null,
                        "review_note": "",
                        "history": [],
                        "updated_at": null
                      },
                      "participants": [],
                      "networks": {
                        "gtr": {
                          "rail": "GTR",
                          "mode": "unavailable",
                          "state": "didit_onboarding",
                          "reason": "didit_membership_not_live",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        },
                        "trust": {
                          "rail": "TRUST",
                          "mode": "unavailable",
                          "state": "unavailable",
                          "reason": "own_membership_only",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        },
                        "verifyvasp": {
                          "rail": "VERIFYVASP",
                          "mode": "unavailable",
                          "state": "didit_onboarding",
                          "reason": "didit_membership_not_live",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        },
                        "sygna": {
                          "rail": "SYGNA",
                          "mode": "unavailable",
                          "state": "didit_onboarding",
                          "reason": "didit_membership_not_live",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          }
        }
      }
    },
    "/v3/travel-rule/networks/questionnaire/": {
      "get": {
        "summary": "네트워크 설문지 가져오기",
        "description": "이 애플리케이션에 대한 Didit의 네트워크 실사 설문지, 해당 상태 및 Didit의 검토 메모를 읽습니다. 설문지를 저장한 적이 없는 애플리케이션은 빈 초안을 읽습니다.",
        "operationId": "getTravelRuleNetworkQuestionnaire",
        "x-didit-sdk": {
          "resource": "travel_rule.networks",
          "method": "retrieve_questionnaire",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/networks/questionnaire/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.retrieve_questionnaire()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.retrieveQuestionnaire();\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().retrieveQuestionnaire();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->networks->retrieveQuestionnaire();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.retrieve_questionnaire\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.RetrieveQuestionnaireAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "설문지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaire"
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          }
        }
      },
      "put": {
        "summary": "네트워크 설문지 답변 저장",
        "description": "설문지가 draft 또는 changes_requested 상태일 때 설문지 답변을 저장합니다. 저장은 부분적입니다. 전송하지 않은 답변은 유지됩니다.",
        "operationId": "updateTravelRuleNetworkQuestionnaire",
        "x-didit-sdk": {
          "resource": "travel_rule.networks",
          "method": "update_questionnaire",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PUT https://verification.didit.me/v3/travel-rule/networks/questionnaire/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"legal_name\": \"Example VASP Ltd\", \"incorporation_country\": \"ES\", \"aml_ctf_policy_attested\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.update_questionnaire(\n    legal_name=\"Example VASP Ltd\",\n    incorporation_country=\"ES\",\n    aml_ctf_policy_attested=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.updateQuestionnaire({\n  legal_name: \"Example VASP Ltd\",\n  incorporation_country: \"ES\",\n  aml_ctf_policy_attested: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleNetworkQuestionnaireAnswers;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().updateQuestionnaire(TravelRuleNetworkQuestionnaireAnswers.builder()\n        .legalName(\"Example VASP Ltd\")\n        .incorporationCountry(\"ES\")\n        .amlCtfPolicyAttested(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->networks->updateQuestionnaire([\n    'legal_name' => 'Example VASP Ltd',\n    'incorporation_country' => 'ES',\n    'aml_ctf_policy_attested' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.update_questionnaire(\n  legal_name: \"Example VASP Ltd\",\n  incorporation_country: \"ES\",\n  aml_ctf_policy_attested: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.UpdateQuestionnaireAsync(new TravelRuleNetworkQuestionnaireAnswers\n{\n    LegalName = \"Example VASP Ltd\",\n    IncorporationCountry = \"ES\",\n    AmlCtfPolicyAttested = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaireAnswers"
              },
              "example": {
                "legal_name": "Example VASP Ltd",
                "incorporation_country": "ES",
                "aml_ctf_policy_attested": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "병합된 답변이 포함된 설문지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaire"
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류이며, 필드별로 키가 지정됩니다."
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "Didit 멤버십을 통한 네트워크 접근이 아직 열리지 않았습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "travel_rule_platform_networks_disabled"
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "설문지가 Didit에 있거나 결정된 상태입니다. draft 또는 changes_requested 상태에서만 변경할 수 있습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "travel_rule_questionnaire_not_editable"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/networks/questionnaire/submit/": {
      "post": {
        "summary": "네트워크 설문지 제출",
        "description": "저장된 설문지를 Didit의 검토를 위해 전송합니다. 저장된 답변은 완전해야 합니다. 세 가지 증명이 참인 상태에서 lei 및 data_protection_contact_email을 제외한 모든 필드가 작성되어야 합니다. Didit은 이를 승인하거나, 변경을 요청하거나(수정 후 다시 제출), 거절합니다. 보류 중인 동안 요청한 네트워크는 승인 시 온보딩으로 인계됩니다.",
        "operationId": "submitTravelRuleNetworkQuestionnaire",
        "x-didit-sdk": {
          "resource": "travel_rule.networks",
          "method": "submit_questionnaire",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/networks/questionnaire/submit/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.submit_questionnaire()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.submitQuestionnaire();\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().submitQuestionnaire();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->networks->submitQuestionnaire();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.submit_questionnaire\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.SubmitQuestionnaireAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "제출된 설문지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaire"
                }
              }
            }
          },
          "400": {
            "description": "저장된 답변이 불완전하거나 유효하지 않으며, 필드별로 키가 지정됩니다."
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "Didit 멤버십을 통한 네트워크 접근이 아직 열리지 않았습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "travel_rule_platform_networks_disabled"
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "설문지가 Didit에 있거나 결정된 상태입니다. draft 또는 changes_requested 상태에서만 변경할 수 있습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "travel_rule_questionnaire_not_editable"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/networks/{network}/request/": {
      "post": {
        "summary": "Travel Rule 네트워크 요청",
        "description": "Didit 멤버십이 지원하는 네트워크(GTR 또는 Sygna)에서 이 애플리케이션 자체의 참가자를 요청합니다. 승인된 설문지가 없으면 참가자는 이를 대기하며(questionnaire_pending), 설문지가 있으면 네트워크의 온보딩으로 이동하고(submitted_to_network) 네트워크에서 코드를 부여하면 활성화됩니다. 멱등성을 가집니다: 대기 중, 온보딩 중 또는 활성 상태인 참가자는 변경 없이 반환됩니다. 네트워크에서 등록을 거부한 경우(last_error 설정됨) 다시 요청하면 재시도합니다. TRUST 및 VerifyVASP는 자체 멤버십을 통해서만 접근할 수 있습니다. TRUST는 VASP별로 멤버를 허용하며, VerifyVASP Enclave는 하나의 VASP id를 지원합니다.",
        "operationId": "requestTravelRuleNetworkAccess",
        "x-didit-sdk": {
          "resource": "travel_rule.networks",
          "method": "request_access",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "network",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "gtr",
                "sygna"
              ]
            },
            "description": "Didit의 멤버십을 통해 참여할 네트워크입니다."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/networks/gtr/request/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.request_access(\n    \"your-network\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.requestAccess(\"your-network\");\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().requestAccess(\"your-network\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->networks->requestAccess('your-network');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.request_access(\"your-network\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.RequestAccessAsync(\"your-network\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "네트워크 상의 귀하의 참여자입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleNetworkParticipant"
                }
              }
            }
          },
          "400": {
            "description": "알 수 없는 네트워크이거나, Didit에서 지원하지 않는 네트워크(자체 멤버십 연결 필요)이거나, 샌드박스 애플리케이션입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "travel_rule_network_own_membership_only",
                        "travel_rule_network_sandbox_application"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API 키가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "Didit 멤버십을 통한 네트워크 접근이 아직 열리지 않았습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "travel_rule_platform_networks_disabled"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/address-validation/": {
      "post": {
        "summary": "주소 검증",
        "description": "주소가 존재하는지 확인하고 정규화된 형태(배송 주소 행, 구성 요소, 좌표)로 반환받습니다. 주소 자체만 확인하며, 주소를 특정 개인과 연결하지는 않습니다.\n\n**요청.** 주소를 한 줄(`address`) 또는 구조화된 필드(`address_line_1` 및 선택 사항인 `address_line_2`, `city`, `region`, `postal_code`) 중 하나로 전송해야 하며(둘 다 전송 불가), `country`(ISO 3166-1 alpha-2 또는 alpha-3)는 항상 포함해야 합니다.\n\n**결과.** `address_validation.status`는 `verified`(건물 단위까지 확인됨), `partially_verified`(도로명 단위 이상만 확인됨), `not_verified`(지역 또는 도시만 일치하거나 일치하는 정보가 없음), `unavailable`(검증을 실행할 수 없음) 중 하나입니다. `unavailable`을 포함하여 완료된 모든 요청에 대해 HTTP는 `200`입니다. `unavailable` 결과는 나중에 재시도하세요.\n\n**결제.** 프로덕션 호출은 검증된 주소당 $0.10가 청구됩니다. `unavailable` 결과에는 요금이 청구되지 않습니다. 사용 기록 외에는 아무것도 저장되지 않습니다. 세션이 생성되지 않으며 결과는 이 응답에만 반환됩니다.\n\n**샌드박스.** 샌드박스 키는 요청을 검증하고 크레딧을 소비하지 않으면서 전송된 주소를 그대로 반영하는 결정론적 `verified` 결과를 항상 반환합니다.\n\n**인증.** 애플리케이션의 API 키를 `x-api-key`에 넣어 전송하세요. 자격 증명이 누락되었거나 유효하지 않으면 `403`이 반환됩니다. 이 API는 `401`을 반환하지 않습니다.\n\n**속도 제한.** API 키당 POST/PATCH/DELETE endpoint 전체에 분당 300건의 공유 쓰기 예산이 적용됩니다(거래 생성 및 이벤트 수집에는 별도의 600건 예산 적용).",
        "operationId": "post_v3_address_validation",
        "x-didit-sdk": {
          "resource": "address_validation",
          "method": "validate",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/address-validation/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"address_line_1\": \"1600 Amphitheatre Pkwy\",\n    \"city\": \"Mountain View\",\n    \"region\": \"CA\",\n    \"postal_code\": \"94043\",\n    \"country\": \"US\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.address_validation.validate(\n    address_line_1=\"1600 Amphitheatre Pkwy\",\n    city=\"Mountain View\",\n    region=\"CA\",\n    postal_code=\"94043\",\n    country=\"US\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.addressValidation.validate({\n  address_line_1: \"1600 Amphitheatre Pkwy\",\n  city: \"Mountain View\",\n  region: \"CA\",\n  postal_code: \"94043\",\n  country: \"US\",\n});\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.AddressValidationRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.addressValidation().validate(AddressValidationRequest.builder()\n        .addressLine1(\"1600 Amphitheatre Pkwy\")\n        .city(\"Mountain View\")\n        .region(\"CA\")\n        .postalCode(\"94043\")\n        .country(\"US\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->addressValidation->validate([\n    'address_line_1' => '1600 Amphitheatre Pkwy',\n    'city' => 'Mountain View',\n    'region' => 'CA',\n    'postal_code' => '94043',\n    'country' => 'US',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.address_validation.validate(\n  address_line_1: \"1600 Amphitheatre Pkwy\",\n  city: \"Mountain View\",\n  region: \"CA\",\n  postal_code: \"94043\",\n  country: \"US\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.AddressValidation.ValidateAsync(new AddressValidationRequest\n{\n    AddressLine1 = \"1600 Amphitheatre Pkwy\",\n    City = \"Mountain View\",\n    Region = \"CA\",\n    PostalCode = \"94043\",\n    Country = \"US\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddressValidationRequest"
              },
              "examples": {
                "Structured": {
                  "summary": "구조화된 주소 필드",
                  "value": {
                    "address_line_1": "1600 Amphitheatre Pkwy",
                    "city": "Mountain View",
                    "region": "CA",
                    "postal_code": "94043",
                    "country": "US"
                  }
                },
                "One line": {
                  "summary": "한 줄로 작성된 전체 주소",
                  "value": {
                    "address": "Paseo de la Castellana 259, 28046 Madrid",
                    "country": "ES"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "검증이 완료되었습니다. `address_validation.status`를 확인하세요. 완료된 요청의 HTTP 상태는 항상 `200`입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddressValidationResponse"
                },
                "examples": {
                  "Verified": {
                    "summary": "건물 단위까지 확인된 실제 주소",
                    "value": {
                      "request_id": "6f7d2c1e-1c5a-4a1e-9b8f-2a1f0f4b9c3d",
                      "address_validation": {
                        "status": "verified",
                        "verification_level": "premise",
                        "address": {
                          "address_line_1": "1600 Amphitheatre Pkwy",
                          "address_line_2": null,
                          "city": "Mountain View",
                          "region": "CA",
                          "postal_code": "94043-1351",
                          "country": "US"
                        },
                        "formatted_address": "1600 Amphitheatre Pkwy, Mountain View CA 94043-1351",
                        "latitude": 37.422022,
                        "longitude": -122.08429
                      },
                      "created_at": "2026-10-27T11:20:00.000000+00:00"
                    }
                  },
                  "Not verified": {
                    "summary": "가상의 거리 이름: 도시만 일치함",
                    "value": {
                      "request_id": "0b9e3f4a-6c2d-4e8b-a1f7-5d3c2b1a0e9f",
                      "address_validation": {
                        "status": "not_verified",
                        "verification_level": "locality",
                        "address": {
                          "address_line_1": "Calle Inventada Que No Existe 99999 28046",
                          "address_line_2": null,
                          "city": "Madrid",
                          "region": "Madrid",
                          "postal_code": null,
                          "country": "ES"
                        },
                        "formatted_address": "Calle Inventada Que No Existe 99999 28046, Madrid, MADRID, SPAIN",
                        "latitude": 40.42603054,
                        "longitude": -3.68645331
                      },
                      "created_at": "2026-10-27T11:21:00.000000+00:00"
                    }
                  },
                  "Unavailable": {
                    "summary": "검증을 실행할 수 없음. 요금 미청구",
                    "value": {
                      "request_id": "3c1b2a0f-9e8d-4c7b-b6a5-1f0e9d8c7b6a",
                      "address_validation": {
                        "status": "unavailable",
                        "verification_level": null,
                        "address": null,
                        "formatted_address": null,
                        "latitude": null,
                        "longitude": null
                      },
                      "created_at": "2026-10-27T11:22:00.000000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/AddressValidationValidationError"
          },
          "403": {
            "$ref": "#/components/responses/AddressValidationPermissionDenied"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        }
      }
    },
    "/v3/travel-rule/wallet-proofs/": {
      "get": {
        "summary": "검토할 스크린샷 지갑 증명 목록 조회",
        "description": "스크린샷 지갑 소유권 증명을 위한 귀하의 검토 대기열입니다. 스크린샷은 Didit이 직접 확인할 수 없는 유일한 증명 방식입니다. 최종 사용자가 위젯에서 업로드하면 POST /v3/travel-rule/wallet-proofs/{proof_uuid}/decision/을 통해 승인하거나 거부할 때까지 PENDING 상태로 대기합니다. 가장 오래된 항목부터 정렬되므로 대기열은 가장 오래 대기한 증명부터 처리됩니다. 업로드된 스크린샷만 표시되며, 최종 사용자가 아직 파일을 업로드하지 않은 증명이나 주소록에서 삭제한 지갑의 증명(Didit은 이를 OWNERSHIP_CHANGED로 종결함)은 표시되지 않습니다.",
        "operationId": "listTravelRuleWalletProofs",
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_proofs",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "description": "조회할 증명 목록입니다. 기본값은 아직 결정되지 않은 항목인 PENDING입니다.",
            "schema": {
              "type": "string",
              "enum": [
                "PENDING",
                "VERIFIED",
                "REJECTED",
                "EXPIRED"
              ],
              "default": "PENDING"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl https://verification.didit.me/v3/travel-rule/wallet-proofs/?status=PENDING \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.wallet_proofs.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.walletProofs.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().walletProofs().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->travelRule->walletProofs->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.wallet_proofs.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.WalletProofs.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "페이지네이션된 스크린샷 증명 목록입니다. 개수는 100까지 정확하며, 100을 초과하면 100으로 제한됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TravelRuleWalletProofReview"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "알 수 없는 상태입니다."
          },
          "401": {
            "description": "x-api-key가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "호출자에게 거래 권한이 없습니다."
          }
        }
      }
    },
    "/v3/travel-rule/wallet-proofs/{proof_uuid}/decision/": {
      "post": {
        "summary": "스크린샷 지갑 증명 승인 또는 거부",
        "description": "검토 대기열에서 스크린샷 증명에 대해 결정을 내립니다. approve는 검증된 서명과 동일하게 증명 및 주소록 항목을 검증하고 위젯 세션이 생성된 대상 거래에 소유권을 적용합니다. 스크린샷으로는 다른 Didit 고객이 INTERNAL 레일을 통해 전송한 거래를 절대 확인할 수 없으며, 이는 서명된 메시지나 테스트 입금이 필요합니다. reject는 failure_reason REVIEW_REJECTED와 함께 증명을 REJECTED 상태로 마감합니다. 최종 사용자는 위젯에서 새 증명을 시작할 수 있습니다. 메모는 증명과 함께 보관됩니다.",
        "operationId": "decideTravelRuleWalletProof",
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_proofs",
          "method": "decide",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "proof_uuid",
            "in": "path",
            "required": true,
            "description": "검토 대기열의 proof_id입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleWalletProofDecision"
              },
              "example": {
                "decision": "approve",
                "note": "Address matches the wallet app."
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/wallet-proofs/{proof_uuid}/decision/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"decision\": \"approve\", \"note\": \"Address matches the wallet app.\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.wallet_proofs.decide(\n    \"11111111-2222-3333-4444-555555555555\",\n    decision=\"approve\",\n    note=\"Address matches the wallet app.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.walletProofs.decide(\"11111111-2222-3333-4444-555555555555\", {\n  decision: \"approve\",\n  note: \"Address matches the wallet app.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWalletProofDecision;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().walletProofs().decide(\"11111111-2222-3333-4444-555555555555\", TravelRuleWalletProofDecision.builder()\n        .decision(TravelRuleWalletProofDecision.Decision.of(\"approve\"))\n        .note(\"Address matches the wallet app.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->walletProofs->decide('11111111-2222-3333-4444-555555555555', [\n    'decision' => 'approve',\n    'note' => 'Address matches the wallet app.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.wallet_proofs.decide(\n  \"11111111-2222-3333-4444-555555555555\",\n  decision: \"approve\",\n  note: \"Address matches the wallet app.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.WalletProofs.DecideAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleWalletProofDecision\n{\n    Decision = \"approve\",\n    Note = \"Address matches the wallet app.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "결정된 증명입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWalletProofReview"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 결정이거나 메모가 512자를 초과합니다."
          },
          "401": {
            "description": "x-api-key가 누락되었거나 유효하지 않습니다."
          },
          "403": {
            "description": "호출자에게 거래 권한이 없습니다."
          },
          "404": {
            "description": "애플리케이션에 이 id를 가진 제출된 스크린샷 증명이 없습니다."
          },
          "409": {
            "description": "증명이 이미 결정되었거나(본문에 상태 포함), OWNERSHIP_CHANGED 코드입니다. 위젯 세션이 생성된 후 지갑 소유자가 변경되었거나 지갑이 삭제되어 증명이 종료되었으므로 현재 소유자에게 새 증명이 필요합니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofError"
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/widget/{token}/proofs/": {
      "post": {
        "summary": "지갑 소유권 증명을 시작합니다.",
        "description": "위젯 세션 token으로 식별되는 공개 endpoint이며 API 키가 필요하지 않습니다. 최종 사용자가 증명 방식을 선택할 때 호스팅된 위젯이 이를 호출합니다. 증명은 오직 이 호출을 통해서만 생성되고 증명 퍼널에 집계됩니다. 동일한 방식을 다시 선택하면 두 번째 증명을 시작하는 대신 이미 열려 있는 증명을 반환합니다(200, 동일한 챌린지 또는 입금액). 다른 방식을 선택하면 제출된 스크린샷이나 확인 중인 테스트 입금을 제외하고 완료되지 않은 증명을 METHOD_SWITCHED로 종료합니다. MESSAGE_SIGNING은 서명할 챌린지를 반환하고, SATOSHI_TEST는 입금 주소, 정확한 금액 및 유효 기간을 반환하며, SELF_DECLARATION은 즉시 검증됩니다(상태 VERIFIED). 체인 패밀리별로 검증되는 서명 형식: EVM 체인은 hex 인코딩된 personal_sign(EIP-191) 서명, Bitcoin은 base64 인코딩된 BIP-137 signmessage 서명(P2PKH, P2SH-P2WPKH, P2WPKH 주소) 또는 BIP-322 simple 서명(P2WPKH 및 P2TR 주소), Solana는 base58 인코딩된 챌린지에 대한 Ed25519 서명, Tron은 hex 인코딩된 signMessageV2(TIP-191) 서명을 지원합니다. BIP-322 full 또는 proof-of-funds 서명, 또는 다중 서명 주소는 SIGNATURE_UNSUPPORTED_SCHEME 오류로 실패합니다.",
        "operationId": "createTravelRuleWidgetProof",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "create_widget_proof",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "위젯 세션이 생성되었을 때 반환된 불투명 세션 token입니다.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleWidgetProofCreate"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/widget/{token}/proofs/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"method\": \"MESSAGE_SIGNING\"}'"
          }
        ],
        "responses": {
          "201": {
            "description": "새로운 PENDING 증명(SELF_DECLARATION의 경우 VERIFIED).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofSummary"
                }
              }
            }
          },
          "200": {
            "description": "이 방식에 대해 이미 열려 있던 증명이 재개되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofSummary"
                }
              }
            }
          },
          "400": {
            "description": "유효하지 않은 본문, 전송과 일치하지 않는 지갑, 허용되지 않는 SCREENSHOT, 또는 해당 체인에서 메서드를 사용할 수 없을 때 발생하는 CHAIN_UNSUPPORTED 코드입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofError"
                }
              }
            }
          },
          "403": {
            "description": "이 애플리케이션에는 SELF_DECLARATION이 허용되지 않습니다."
          },
          "404": {
            "description": "알 수 없는 token입니다."
          },
          "409": {
            "description": "코드 OWNERSHIP_CHANGED: 세션이 발급된 후 지갑 소유자가 변경되었거나 지갑이 삭제되었습니다. 현재 소유자를 위해 새 세션을 발급하십시오. 세션에 satoshi_deposit_address가 없을 때, 그리고 세션에 남은 시도 횟수가 없을 때(코드 없음. 본문에 max_attempts, attempts_used, attempts_remaining 0 포함) SATOSHI_TEST에 대해서도 반환됩니다: 새 세션을 발급하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofError"
                }
              }
            }
          },
          "410": {
            "description": "세션이 만료되었습니다."
          }
        }
      }
    },
    "/v3/travel-rule/widget/{token}/proofs/{proof_id}/verify/": {
      "post": {
        "summary": "지갑 소유권 증명 증빙 제출",
        "description": "위젯 세션 token으로 식별되는 공개 endpoint이며 API 키가 필요하지 않습니다. 증명 방식에 필요한 증빙을 전송하십시오: MESSAGE_SIGNING의 경우 서명, SATOSHI_TEST의 경우 txid(JSON), SCREENSHOT의 경우 파일(multipart). 모든 제출은 시도 횟수로 계산됩니다. 검증되지 않은 서명이나 일치하지 않는 입금은 오류 코드와 함께 400으로 응답하며 최종 사용자가 다시 시도할 수 있도록 증명 상태를 PENDING으로 유지합니다. 입금이 감지되었으나 아직 확인되지 않은 경우 상태 PENDING과 함께 200으로 응답하고 기한이 만료될 때까지 자동으로 재확인합니다. 스크린샷은 상태 PENDING과 함께 200으로 응답하고 검토 대기열(GET /v3/travel-rule/wallet-proofs/)에서 대기합니다. EXPIRED 또는 REJECTED된 증명은 나중에 검증되지 않으므로 새 증명을 시작하십시오. 체인 패밀리별로 검증되는 서명 형식: EVM 체인은 hex 인코딩된 personal_sign(EIP-191) 서명, Bitcoin은 base64 인코딩된 BIP-137 signmessage 서명(P2PKH, P2SH-P2WPKH, P2WPKH 주소) 또는 BIP-322 simple 서명(P2WPKH 및 P2TR 주소), Solana는 base58 인코딩된 챌린지에 대한 Ed25519 서명, Tron은 hex 인코딩된 signMessageV2(TIP-191) 서명을 지원합니다. BIP-322 full 또는 proof-of-funds 서명, 또는 다중 서명 주소는 SIGNATURE_UNSUPPORTED_SCHEME 오류로 실패합니다.",
        "operationId": "verifyTravelRuleWidgetProof",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "verify_widget_proof",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "위젯 세션이 생성되었을 때 반환된 불투명 세션 token입니다.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "proof_id",
            "in": "path",
            "required": true,
            "description": "증명이 시작되었을 때 반환된 proof_id입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "signature": {
                    "type": "string",
                    "description": "MESSAGE_SIGNING: 증명의 챌린지에 대한 지갑 서명입니다."
                  },
                  "txid": {
                    "type": "string",
                    "description": "SATOSHI_TEST: 테스트 입금의 거래 ID입니다."
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "SCREENSHOT: 최종 사용자의 지갑 앱에 표시된 지갑을 보여주는 이미지입니다."
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/widget/{token}/proofs/{proof_id}/verify/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"signature\": \"0x...\"}'"
          }
        ],
        "responses": {
          "200": {
            "description": "VERIFIED 또는 여전히 PENDING 상태입니다(검토 대기 중인 스크린샷, 아직 색인되지 않았거나 확인되지 않은 입금, 코드 DEPOSIT_NOT_FOUND 또는 DEPOSIT_UNCONFIRMED).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofVerifyResult"
                }
              }
            }
          },
          "400": {
            "description": "증거가 누락되었습니다. 최종 사용자가 다시 시도할 수 있도록 증명을 PENDING 상태로 유지하는 실패한 시도(코드 SIGNATURE_INVALID, SIGNATURE_UNSUPPORTED_SCHEME 또는 DEPOSIT_LOOKUP_FAILED)이거나, 증명을 거부하는 테스트 입금(코드 DEPOSIT_MISMATCH, DEPOSIT_STALE 또는 TXID_REUSED, 상태 REJECTED, 세션의 시도 횟수 포함)입니다. attempts_remaining이 0보다 큰 동안 방법을 다시 선택하면 새 증명이 시작됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofError"
                }
              }
            }
          },
          "404": {
            "description": "알 수 없는 token이거나 이 세션에 해당 증명이 없습니다."
          },
          "409": {
            "description": "코드 OWNERSHIP_CHANGED(증명이 이 코드로 종료됨); 종료된 증명(REJECTED 또는 EXPIRED) 및 해당 상태, 증명을 종료한 코드 및 세션 시도 횟수: 새 증명을 시작하려면 방법을 다시 선택하십시오; 또는 시작 시 검증되는 SELF_DECLARATION 증명입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofError"
                }
              }
            }
          },
          "410": {
            "description": "세션이 만료되었거나, 사토시 테스트 윈도우가 닫혔을 때 WINDOW_EXPIRED 코드가 반환되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofError"
                }
              }
            }
          }
        }
      }
    },
    "/v3/id-verification/wallets/verifications/{request_id}/response/": {
      "post": {
        "operationId": "submit_wallet_verification_response",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "submit_verification_response",
          "auth": "api_key",
          "server": true
        },
        "description": "Digital Credentials API 지갑(Google Wallet): next_action이 request_digital_credential인 인증에 대해 지갑이 페이지 또는 앱으로 반환한 값을 전송합니다. Didit은 이를 복호화하고, 신뢰할 수 있는 발급자 루트와 발급자의 서명을 대조 확인하며, 반환된 모든 값을 서명된 다이제스트와 대조 확인하고, 원본(origin) 및 이 요청에 대한 기기 서명을 확인한 다음 인증을 결정합니다: verified(1회 결제됨) 또는 오류 코드와 함께 declined. 일회용: 두 번째 제출 시에는 결정된 인증 결과를 반환합니다.",
        "summary": "지갑 응답 제출",
        "parameters": [
          {
            "in": "path",
            "name": "request_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "start endpoint가 반환한 request_id입니다.",
            "required": true
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletDigitalCredentialResponseRequest"
              },
              "example": {
                "response": {
                  "protocol": "openid4vp-v1-signed",
                  "data": {
                    "response": "<compact JWE returned by the wallet>"
                  }
                }
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletDigitalCredentialResponseRequest"
              },
              "example": {
                "response": {
                  "protocol": "openid4vp-v1-signed",
                  "data": {
                    "response": "<compact JWE returned by the wallet>"
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletDigitalCredentialResponseRequest"
              },
              "example": {
                "response": {
                  "protocol": "openid4vp-v1-signed",
                  "data": {
                    "response": "<compact JWE returned by the wallet>"
                  }
                }
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "google_wallet",
                      "name": "Google Wallet",
                      "issuing_authority": "Google Wallet (ID pass) and US state issuers (mobile driving licence)"
                    },
                    "country": "USA",
                    "status": "Approved",
                    "outcome": "verified",
                    "error": null,
                    "interaction": "digital_credentials",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": null,
                    "identity": {
                      "full_name": "Alex Example",
                      "first_name": "Alex",
                      "last_name": "Example",
                      "date_of_birth": "1990-01-31",
                      "nationality": "USA",
                      "issuing_state": "USA"
                    },
                    "attributes": {
                      "document_number": "X0000000",
                      "document_expiry_date": "2030-01-31"
                    },
                    "level_of_assurance": "substantial",
                    "verified_at": "2026-01-01T10:01:00Z",
                    "signature_valid": true,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": "자격 증명(x-api-key 또는 Authorization: Bearer)이 누락되었습니다."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 not_found: 이 애플리케이션의 어떤 지갑 인증에도 이 request_id가 없습니다."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]})입니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 not_a_digital_credentials_wallet: 이 인증에서는 지갑 응답을 받지 않습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑을 검증할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/verifications/REQUEST_ID/response/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"response\": {\n    \"protocol\": \"openid4vp-v1-signed\",\n    \"data\": {\n      \"response\": \"<compact JWE returned by the wallet>\"\n    }\n  }\n}'"
          }
        ]
      }
    },
    "/v3/id-verification/wallets/google-wallet/": {
      "post": {
        "operationId": "start_google_wallet_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_google_wallet",
          "auth": "api_key",
          "server": true
        },
        "description": "워크플로 없이 Google Wallet 로그인(Google Wallet(신분증 패스) 및 미국 주정부 발급기관(모바일 운전면허증); USA, GBR, BRA, SGP, TWN)을 시작합니다. 신원이 인증된 경우에만 1회 결제됩니다. 응답에는 애플리케이션을 위해 Didit이 서명한 요청과 함께 next_action.type=request_digital_credential이 포함되며, 이는 origin에서만 사용할 수 있습니다. 해당 위치의 사용자 제스처에서 next_action.digital_credentials.request를 navigator.credentials.get({digital: ...})에(또는 Android Credential Manager에 GetDigitalCredentialOption requestJson으로) 전달한 다음, 지갑이 반환한 내용을 /v3/id-verification/wallets/verifications/{request_id}/response/로 POST합니다. 지갑이 다른 기기에 있는 경우 브라우저가 자체 QR 코드를 표시합니다. 샌드박스 애플리케이션은 공급자에게 연결되지 않는 결정론적 시뮬레이션(simulated: true)을 받습니다.",
        "summary": "Google Wallet 인증 시작",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "선택적 재시도 안전 키(최대 255자)입니다. 동일한 키, 지갑 및 본문으로 재시도하면 두 번째 로그인을 시작하지 않고 기존 인증을 반환합니다. 동일한 키를 다른 지갑이나 본문과 함께 사용하면 409 idempotency_key_reused를 반환합니다."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGoogleWalletWalletVerificationStartRequest"
              },
              "example": {
                "country": "USA",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "origin": "https://app.example.com"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGoogleWalletWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGoogleWalletWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "google_wallet",
                      "name": "Google Wallet",
                      "issuing_authority": "Google Wallet (ID pass) and US state issuers (mobile driving licence)"
                    },
                    "country": "USA",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "digital_credentials",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "request_digital_credential",
                      "digital_credentials": {
                        "protocol": "openid4vp-v1-signed",
                        "request": {
                          "requests": [
                            {
                              "protocol": "openid4vp-v1-signed",
                              "data": {
                                "request": "<compact JWS signed by Didit>"
                              }
                            }
                          ]
                        }
                      }
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "필드 유효성 검사 오류({field: [messages]}) 또는 오류 return_url_invalid, return_url_not_allowed, origin_invalid, origin_not_allowed, invalid_personal_code, invalid_phone_number, idempotency_key_invalid입니다."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "자격 증명이 누락되었거나({detail}), wallet_unavailable, insufficient_credits 또는 contract_rate_missing 오류가 발생했습니다."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 idempotency_key_reused 또는 idempotency_key_in_progress(Retry-After 포함)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_provider_unavailable: 공급자가 시작되지 못했습니다. 아무것도 생성되지 않았습니다."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "오류 wallet_not_configured: 이 환경에서 지갑에 연결할 수 없습니다."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/google-wallet/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"USA\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"origin\": \"https://app.example.com\"\n}'"
          }
        ],
        "x-didit-wallet-id": "google_wallet"
      }
    },
    "/v3/session/{sessionId}/kyb/documents/": {
      "post": {
        "summary": "세션에 KYB 문서 업로드",
        "description": "호스팅 페이지 대신 자체 서버에서 기업 확인 세션의 KYB 문서 단계로 하나 이상의 기업 문서(정관, 주주명부, 법인 설립 증명서 등)를 업로드합니다. Didit은 압축, OCR, 위변조 및 교차 문서 검사, 문서 그룹화 등 호스팅 파이프라인을 실행하며 필요한 문서 그룹이 충족되면 세션을 진행합니다. 이 단계는 전송하는 파일 수와 관계없이 단일 고정 요금이 부과됩니다. 세션은 열려 있고 KYB 문서 단계여야 하며 법인 등기부 단계에서 선택한 기업이 존재해야 합니다. `GET /v3/session/{sessionId}/kyb/extracted-parties/`로 문서에 명시된 인물을 확인하세요. `write:businesses` 권한이 필요합니다.",
        "operationId": "post_v3_session_kyb_documents",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "upload_kyb_documents",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "기업 확인(KYB) 세션의 UUID입니다. 해당 API 키의 애플리케이션에 속해 있어야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "KYB 단계의 워크플로 노드입니다. 워크플로에 둘 이상의 KYB 노드가 있는 경우에만 필요하며, 기본적으로 Didit은 세션 자체의 노드를 사용합니다.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "documents"
                ],
                "properties": {
                  "documents": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    },
                    "description": "업로드할 파일: JPG, JPEG, PNG, TIFF, WEBP, PDF 또는 이들의 ZIP 압축 파일입니다. PDF는 최대 50 MB, 사진은 압축 전 최대 6 MB까지 가능합니다."
                  },
                  "document_passwords": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "`documents`의 파일당 동일한 순서의 항목 1개입니다. 보호된 PDF의 비밀번호이며 다른 파일의 경우 비어 있습니다."
                  },
                  "document_group": {
                    "type": "string",
                    "enum": [
                      "LEGAL_PRESENCE",
                      "COMPANY_DETAILS",
                      "OWNERSHIP_STRUCTURE",
                      "REPRESENTATIVES_AUTHORIZATION"
                    ],
                    "description": "이 업로드가 대응하는 필수 문서 그룹입니다."
                  },
                  "locale": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "다음 단계의 응답을 번역하는 데 사용되는 로캘입니다."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "문서가 처리되었습니다. 필요한 모든 그룹이 충족되면 세션이 진행되고 `next_step`에 다음 단계가 표시됩니다. 그렇지 않으면 문서 단계에 유지되며 `document_groups` 및 `document_answer`에 누락된 항목이 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean"
                    },
                    "next_step": {
                      "type": "string",
                      "nullable": true,
                      "description": "업로드 후 세션이 위치한 단계입니다."
                    },
                    "kyb_status": {
                      "type": "string",
                      "description": "기업 검사의 상태입니다."
                    },
                    "document_answer": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "업로드된 문서별 결과 및 남은 업로드 수입니다."
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "valid": true,
                  "next_step": "KYB_KEY_PEOPLE",
                  "kyb_status": "In Progress"
                }
              }
            }
          },
          "400": {
            "description": "문서가 거부되었거나(위변조, 판독 불가 또는 지원되지 않음) 세션에 아직 KYB 기업이 없습니다. 시도 횟수가 남아 있는 동안 다른 파일로 재시도하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "example": {
                  "message": "No KYB company found. Submit company data first."
                }
              }
            }
          },
          "402": {
            "description": "문서 단계에 사용할 조직의 크레딧이 남아 있지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "example": {
                  "detail": "Insufficient credits."
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "스코프 지정 키에 decisions: write 권한이 없음",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나, 삭제되었거나, 다른 애플리케이션에 속해 있거나, 범위가 지정된 키의 제한 범위를 벗어났습니다. 이를 구분하는 세부 정보는 제공되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          },
          "409": {
            "description": "세션이 종료되었거나(`kyb_session_not_writable`), KYB Documents 단계에 있지 않습니다(`kyb_step_mismatch`, `next_step`에 현재 단계 표시).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    },
                    "code": {
                      "type": "string"
                    },
                    "next_step": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "The session is not on the step this operation completes.",
                  "code": "kyb_step_mismatch",
                  "next_step": "KYB_REGISTRY"
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. API 키당 분당 300회의 쓰기(POST, PATCH, DELETE) 요청으로 제한됩니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요. `X-RateLimit-*` 헤더에 한도 정보가 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "현재 분에 할당된 예산이 소진되었습니다",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/DocumentProcessingBusy"
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.upload_kyb_documents(\n    \"33333333-4444-5555-6666-777777777777\",\n    documents=[open(\"document.pdf\", \"rb\")],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.uploadKybDocuments(\"33333333-4444-5555-6666-777777777777\", {\n  documents: [await fileFromPath(\"document.pdf\")],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UploadKYBDocuments(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsUploadKYBDocumentsParams{\n\tDocuments: []didit.File{didit.FileFromPath(\"document.pdf\")},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUploadKybDocumentsParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().uploadKybDocuments(\"33333333-4444-5555-6666-777777777777\", SessionsUploadKybDocumentsParams.builder()\n        .documents(List.of(Path.of(\"document.pdf\")))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->uploadKybDocuments('33333333-4444-5555-6666-777777777777', [\n    'documents' => [File::fromPath('document.pdf')],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.upload_kyb_documents(\n  \"33333333-4444-5555-6666-777777777777\",\n  documents: [Pathname(\"document.pdf\")]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UploadKybDocumentsAsync(\"33333333-4444-5555-6666-777777777777\", new SessionsUploadKybDocumentsParams\n{\n    Documents = new FileUpload[] { FileUpload.FromPath(\"document.pdf\") },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/extracted-parties/": {
      "get": {
        "summary": "업로드된 문서에 명시된 당사자 목록을 조회합니다",
        "description": "이 KYB 세션에 업로드된 문서에 명시된 주주와 이사를 개인별로 병합하고 해당 인물을 명시한 문서에 귀속시켜 반환합니다. 신청자에게 표시하여 확인받은 후 party 초안 endpoint를 사용하여 신고하십시오. 범위는 범위로 유지됩니다: `ownership_percent.text`에는 원문 수치가 유지되고 `min` / `max`에는 이로부터 읽은 숫자가 유지됩니다. 여기서는 아무도 UBO로 지정되지 않으며, party가 제출될 때 워크플로의 역할 설정 및 소유 구조 임계값에 따라 결정됩니다. 동일한 목록이 세션 결정에 `document_verifications[].extracted_parties`로 포함되어 있습니다. `read:businesses` 또는 `read:sessions` 권한이 필요합니다.",
        "operationId": "get_v3_session_kyb_extracted_parties",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list_kyb_extracted_parties",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "기업 확인(KYB) 세션의 UUID입니다. 해당 API 키의 애플리케이션에 속해 있어야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "KYB 단계의 워크플로 노드입니다. 워크플로에 둘 이상의 KYB 노드가 있는 경우에만 필요하며, 기본적으로 Didit은 세션 자체의 노드를 사용합니다.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "현재 문서에 명시된 당사자입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "parties",
                    "document_count"
                  ],
                  "properties": {
                    "parties": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "entity_type": {
                            "type": "string",
                            "enum": [
                              "person",
                              "company"
                            ]
                          },
                          "first_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "last_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "appointment_date": {
                            "type": "string",
                            "nullable": true
                          },
                          "designation": {
                            "type": "string",
                            "nullable": true
                          },
                          "roles": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "role": {
                                  "type": "string",
                                  "enum": [
                                    "director",
                                    "non_executive_director",
                                    "secretary",
                                    "chairman",
                                    "ubo",
                                    "shareholder",
                                    "representative",
                                    "founder",
                                    "legal_advisor",
                                    "authorized_signatory",
                                    "trustee",
                                    "beneficiary",
                                    "settlor",
                                    "protector",
                                    "company_officer",
                                    "investor",
                                    "other"
                                  ]
                                },
                                "ownership_percent": {
                                  "type": "object",
                                  "properties": {
                                    "text": {
                                      "type": "string",
                                      "nullable": true,
                                      "description": "`25-50%`, `>50%`, `NO EXHIBE` 등 문서에 명시된 그대로의 소유 지분 수치입니다."
                                    },
                                    "min": {
                                      "type": "number",
                                      "nullable": true,
                                      "description": "`text`에서 읽어낸 더 작은 숫자입니다. 명시된 것이 없으면 null입니다."
                                    },
                                    "max": {
                                      "type": "number",
                                      "nullable": true,
                                      "description": "`text`에서 읽어낸 상위 숫자입니다. 없는 경우 null입니다."
                                    }
                                  }
                                }
                              }
                            }
                          },
                          "documents": {
                            "type": "array",
                            "description": "이 당사자를 명시한 업로드된 문서입니다.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "document_uuid": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "document_type": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "document_subtype": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "original_filename": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "status": {
                                  "type": "string",
                                  "nullable": true
                                }
                              }
                            }
                          }
                        }
                      },
                      "description": "업로드된 문서에 명시된 주주 및 이사 목록으로, 개인별로 병합됩니다. 여기서는 아무도 UBO로 지정되지 않으며, 이는 당사자 정보가 제출될 때 결정됩니다."
                    },
                    "document_count": {
                      "type": "integer",
                      "description": "목록을 읽어온 업로드된 문서 수입니다."
                    },
                    "node_id": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                },
                "example": {
                  "parties": [
                    {
                      "name": "Ana Lopez",
                      "entity_type": "person",
                      "first_name": "Ana",
                      "last_name": "Lopez",
                      "appointment_date": null,
                      "designation": "Administrador unico",
                      "roles": [
                        {
                          "role": "shareholder",
                          "ownership_percent": {
                            "text": "60%",
                            "min": 60,
                            "max": 60
                          }
                        }
                      ],
                      "documents": [
                        {
                          "document_uuid": "0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41",
                          "document_type": "OWNERSHIP_STRUCTURE",
                          "document_subtype": "ARTICLES_OF_INCORPORATION",
                          "original_filename": "acta_constitutiva.pdf",
                          "status": "Approved"
                        }
                      ]
                    }
                  ],
                  "document_count": 1,
                  "node_id": "node_kyb_documents"
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "스코프 지정 키에 decisions: write 권한이 없음",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나, 삭제되었거나, 다른 애플리케이션에 속해 있거나, 범위가 지정된 키의 제한 범위를 벗어났습니다. 이를 구분하는 세부 정보는 제공되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.list_kyb_extracted_parties(\n    \"33333333-4444-5555-6666-777777777777\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.listKybExtractedParties(\"33333333-4444-5555-6666-777777777777\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ListKYBExtractedParties(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsListKYBExtractedPartiesParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().listKybExtractedParties(\"33333333-4444-5555-6666-777777777777\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->listKybExtractedParties('33333333-4444-5555-6666-777777777777');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.list_kyb_extracted_parties(\"33333333-4444-5555-6666-777777777777\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ListKybExtractedPartiesAsync(\"33333333-4444-5555-6666-777777777777\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/parties/drafts/": {
      "get": {
        "summary": "KYB 당사자 초안 목록 조회",
        "description": "이 KYB 세션을 위해 준비 중인 당사자 목록을 오래된 순으로 조회합니다. 초안은 신고된 당사자가 아닙니다. 결정이나 콘솔에 표시되지 않으며 `POST /v3/session/{sessionId}/kyb/parties/submit/`으로 제출하기 전까지는 인증 세션을 생성하지 않습니다. `write:businesses` 권한이 필요합니다.",
        "operationId": "get_v3_session_kyb_party_drafts",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list_kyb_party_drafts",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "기업 확인(KYB) 세션의 UUID입니다. 해당 API 키의 애플리케이션에 속해 있어야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "KYB 단계의 워크플로 노드입니다. 워크플로에 둘 이상의 KYB 노드가 있는 경우에만 필요하며, 기본적으로 Didit은 세션 자체의 노드를 사용합니다.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "저장된 임시 저장본입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "parties": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "draft_id",
                          "created_at",
                          "updated_at",
                          "party"
                        ],
                        "properties": {
                          "draft_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "party": {
                            "type": "object",
                            "required": [
                              "entity_type",
                              "nationality"
                            ],
                            "properties": {
                              "entity_type": {
                                "type": "string",
                                "enum": [
                                  "person",
                                  "company"
                                ],
                                "description": "해당 당사자가 개인인지 기업인지 여부입니다."
                              },
                              "full_name": {
                                "type": "string",
                                "maxLength": 255,
                                "description": "개인의 성명입니다. 이 값을 전송하거나, `first_name` 및 `last_name`을 전송하십시오."
                              },
                              "first_name": {
                                "type": "string",
                                "maxLength": 128
                              },
                              "last_name": {
                                "type": "string",
                                "maxLength": 128
                              },
                              "role": {
                                "type": "string",
                                "enum": [
                                  "director",
                                  "non_executive_director",
                                  "secretary",
                                  "chairman",
                                  "ubo",
                                  "shareholder",
                                  "representative",
                                  "founder",
                                  "legal_advisor",
                                  "authorized_signatory",
                                  "trustee",
                                  "beneficiary",
                                  "settlor",
                                  "protector",
                                  "company_officer",
                                  "investor",
                                  "other"
                                ],
                                "description": "해당 당사자가 보유한 역할. `roles`와 서로 바꿔 사용할 수 있으며, 둘 다 전송되면 병합됩니다."
                              },
                              "roles": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "director",
                                    "non_executive_director",
                                    "secretary",
                                    "chairman",
                                    "ubo",
                                    "shareholder",
                                    "representative",
                                    "founder",
                                    "legal_advisor",
                                    "authorized_signatory",
                                    "trustee",
                                    "beneficiary",
                                    "settlor",
                                    "protector",
                                    "company_officer",
                                    "investor",
                                    "other"
                                  ]
                                },
                                "description": "해당 주체가 보유한 모든 역할입니다. 개인은 최소 하나의 역할(여기 또는 `role`)이 필요합니다."
                              },
                              "position": {
                                "type": "string",
                                "maxLength": 128,
                                "description": "개인의 직책입니다."
                              },
                              "date_of_birth": {
                                "type": "string",
                                "format": "date",
                                "nullable": true
                              },
                              "company_name": {
                                "type": "string",
                                "maxLength": 255,
                                "description": "기업 당사자의 이름입니다. `entity_type`이 `company`인 경우 필수입니다."
                              },
                              "registration_number": {
                                "type": "string",
                                "maxLength": 100,
                                "description": "기업 당사자의 등록번호입니다."
                              },
                              "email": {
                                "type": "string",
                                "format": "email",
                                "description": "인증 링크가 전송되는 위치입니다. 당사자가 인증을 완료해야 할 때 필수이며, 이는 워크플로의 역할 설정 및 소유 구조 임계값에 따라 결정됩니다."
                              },
                              "ownership_percent": {
                                "type": "number",
                                "nullable": true,
                                "description": "해당 주체가 보유한 기업의 지분입니다."
                              },
                              "nationality": {
                                "type": "string",
                                "maxLength": 100,
                                "description": "개인의 국적 또는 기업의 설립 국가입니다. 모든 당사자에게 필수입니다."
                              },
                              "phone_number": {
                                "type": "string",
                                "maxLength": 32
                              },
                              "custom_fields": {
                                "type": "object",
                                "additionalProperties": true,
                                "description": "워크플로에서 정의된 추가 필드입니다."
                              },
                              "skip_verification": {
                                "type": "boolean",
                                "default": false,
                                "description": "이 당사자의 인증 건너뛰기를 요청합니다. 워크플로의 주요 인물 설정에서 해당 당사자의 역할에 건너뛰기가 허용된 경우에만 적용됩니다."
                              }
                            }
                          }
                        }
                      }
                    },
                    "node_id": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                },
                "example": {
                  "parties": [
                    {
                      "draft_id": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d",
                      "created_at": "2026-10-31T10:00:00Z",
                      "updated_at": "2026-10-31T10:00:00Z",
                      "party": {
                        "entity_type": "person",
                        "first_name": "Ana",
                        "last_name": "Lopez",
                        "roles": [
                          "ubo",
                          "director"
                        ],
                        "ownership_percent": 60,
                        "nationality": "MEX",
                        "email": "ana.lopez@example.com",
                        "date_of_birth": "1984-06-12"
                      }
                    }
                  ],
                  "node_id": "node_kyb_key_people"
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "스코프 지정 키에 decisions: write 권한이 없음",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나, 삭제되었거나, 다른 애플리케이션에 속해 있거나, 범위가 지정된 키의 제한 범위를 벗어났습니다. 이를 구분하는 세부 정보는 제공되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.list_kyb_party_drafts(\n    \"33333333-4444-5555-6666-777777777777\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.listKybPartyDrafts(\"33333333-4444-5555-6666-777777777777\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ListKYBPartyDrafts(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsListKYBPartyDraftsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().listKybPartyDrafts(\"33333333-4444-5555-6666-777777777777\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->listKybPartyDrafts('33333333-4444-5555-6666-777777777777');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.list_kyb_party_drafts(\"33333333-4444-5555-6666-777777777777\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ListKybPartyDraftsAsync(\"33333333-4444-5555-6666-777777777777\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "post": {
        "summary": "KYB 당사자 초안 생성",
        "description": "이 KYB 세션을 위해 준비 중인 목록에 당사자(개인 또는 법인)를 추가합니다. 호스팅된 주요 인물 화면과 동일한 필드 및 규칙이 적용됩니다. 개인의 경우 `full_name` 또는 `first_name` 및 `last_name`, 최소 하나의 역할, 국적이 필요합니다. 법인의 경우 `company_name` 및 설립 국가를 `nationality`에 입력해야 합니다. `POST /v3/session/{sessionId}/kyb/parties/submit/` 호출 전까지는 신고되거나 청구되지 않습니다. `write:businesses` 권한이 필요합니다.",
        "operationId": "post_v3_session_kyb_party_drafts",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "create_kyb_party_draft",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "기업 확인(KYB) 세션의 UUID입니다. 해당 API 키의 애플리케이션에 속해 있어야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "KYB 단계의 워크플로 노드입니다. 워크플로에 둘 이상의 KYB 노드가 있는 경우에만 필요하며, 기본적으로 Didit은 세션 자체의 노드를 사용합니다.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "entity_type",
                  "nationality"
                ],
                "properties": {
                  "entity_type": {
                    "type": "string",
                    "enum": [
                      "person",
                      "company"
                    ],
                    "description": "해당 당사자가 개인인지 기업인지 여부입니다."
                  },
                  "full_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "개인의 성명입니다. 이 값을 전송하거나, `first_name` 및 `last_name`을 전송하십시오."
                  },
                  "first_name": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "last_name": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "director",
                      "non_executive_director",
                      "secretary",
                      "chairman",
                      "ubo",
                      "shareholder",
                      "representative",
                      "founder",
                      "legal_advisor",
                      "authorized_signatory",
                      "trustee",
                      "beneficiary",
                      "settlor",
                      "protector",
                      "company_officer",
                      "investor",
                      "other"
                    ],
                    "description": "해당 당사자가 보유한 역할. `roles`와 서로 바꿔 사용할 수 있으며, 둘 다 전송되면 병합됩니다."
                  },
                  "roles": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "director",
                        "non_executive_director",
                        "secretary",
                        "chairman",
                        "ubo",
                        "shareholder",
                        "representative",
                        "founder",
                        "legal_advisor",
                        "authorized_signatory",
                        "trustee",
                        "beneficiary",
                        "settlor",
                        "protector",
                        "company_officer",
                        "investor",
                        "other"
                      ]
                    },
                    "description": "해당 주체가 보유한 모든 역할입니다. 개인은 최소 하나의 역할(여기 또는 `role`)이 필요합니다."
                  },
                  "position": {
                    "type": "string",
                    "maxLength": 128,
                    "description": "개인의 직책입니다."
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "nullable": true
                  },
                  "company_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "기업 당사자의 이름입니다. `entity_type`이 `company`인 경우 필수입니다."
                  },
                  "registration_number": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "기업 당사자의 등록번호입니다."
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "인증 링크가 전송되는 위치입니다. 당사자가 인증을 완료해야 할 때 필수이며, 이는 워크플로의 역할 설정 및 소유 구조 임계값에 따라 결정됩니다."
                  },
                  "ownership_percent": {
                    "type": "number",
                    "nullable": true,
                    "description": "해당 주체가 보유한 기업의 지분입니다."
                  },
                  "nationality": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "개인의 국적 또는 기업의 설립 국가입니다. 모든 당사자에게 필수입니다."
                  },
                  "phone_number": {
                    "type": "string",
                    "maxLength": 32
                  },
                  "custom_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "워크플로에서 정의된 추가 필드입니다."
                  },
                  "skip_verification": {
                    "type": "boolean",
                    "default": false,
                    "description": "이 당사자의 인증 건너뛰기를 요청합니다. 워크플로의 주요 인물 설정에서 해당 당사자의 역할에 건너뛰기가 허용된 경우에만 적용됩니다."
                  }
                }
              },
              "example": {
                "entity_type": "person",
                "first_name": "Ana",
                "last_name": "Lopez",
                "roles": [
                  "ubo",
                  "director"
                ],
                "ownership_percent": 60,
                "nationality": "MEX",
                "email": "ana.lopez@example.com",
                "date_of_birth": "1984-06-12"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "초안이 생성되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "draft_id",
                    "created_at",
                    "updated_at",
                    "party"
                  ],
                  "properties": {
                    "draft_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "party": {
                      "type": "object",
                      "required": [
                        "entity_type",
                        "nationality"
                      ],
                      "properties": {
                        "entity_type": {
                          "type": "string",
                          "enum": [
                            "person",
                            "company"
                          ],
                          "description": "해당 당사자가 개인인지 기업인지 여부입니다."
                        },
                        "full_name": {
                          "type": "string",
                          "maxLength": 255,
                          "description": "개인의 성명입니다. 이 값을 전송하거나, `first_name` 및 `last_name`을 전송하십시오."
                        },
                        "first_name": {
                          "type": "string",
                          "maxLength": 128
                        },
                        "last_name": {
                          "type": "string",
                          "maxLength": 128
                        },
                        "role": {
                          "type": "string",
                          "enum": [
                            "director",
                            "non_executive_director",
                            "secretary",
                            "chairman",
                            "ubo",
                            "shareholder",
                            "representative",
                            "founder",
                            "legal_advisor",
                            "authorized_signatory",
                            "trustee",
                            "beneficiary",
                            "settlor",
                            "protector",
                            "company_officer",
                            "investor",
                            "other"
                          ],
                          "description": "해당 당사자가 보유한 역할. `roles`와 서로 바꿔 사용할 수 있으며, 둘 다 전송되면 병합됩니다."
                        },
                        "roles": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "enum": [
                              "director",
                              "non_executive_director",
                              "secretary",
                              "chairman",
                              "ubo",
                              "shareholder",
                              "representative",
                              "founder",
                              "legal_advisor",
                              "authorized_signatory",
                              "trustee",
                              "beneficiary",
                              "settlor",
                              "protector",
                              "company_officer",
                              "investor",
                              "other"
                            ]
                          },
                          "description": "해당 주체가 보유한 모든 역할입니다. 개인은 최소 하나의 역할(여기 또는 `role`)이 필요합니다."
                        },
                        "position": {
                          "type": "string",
                          "maxLength": 128,
                          "description": "개인의 직책입니다."
                        },
                        "date_of_birth": {
                          "type": "string",
                          "format": "date",
                          "nullable": true
                        },
                        "company_name": {
                          "type": "string",
                          "maxLength": 255,
                          "description": "기업 당사자의 이름입니다. `entity_type`이 `company`인 경우 필수입니다."
                        },
                        "registration_number": {
                          "type": "string",
                          "maxLength": 100,
                          "description": "기업 당사자의 등록번호입니다."
                        },
                        "email": {
                          "type": "string",
                          "format": "email",
                          "description": "인증 링크가 전송되는 위치입니다. 당사자가 인증을 완료해야 할 때 필수이며, 이는 워크플로의 역할 설정 및 소유 구조 임계값에 따라 결정됩니다."
                        },
                        "ownership_percent": {
                          "type": "number",
                          "nullable": true,
                          "description": "해당 주체가 보유한 기업의 지분입니다."
                        },
                        "nationality": {
                          "type": "string",
                          "maxLength": 100,
                          "description": "개인의 국적 또는 기업의 설립 국가입니다. 모든 당사자에게 필수입니다."
                        },
                        "phone_number": {
                          "type": "string",
                          "maxLength": 32
                        },
                        "custom_fields": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "워크플로에서 정의된 추가 필드입니다."
                        },
                        "skip_verification": {
                          "type": "boolean",
                          "default": false,
                          "description": "이 당사자의 인증 건너뛰기를 요청합니다. 워크플로의 주요 인물 설정에서 해당 당사자의 역할에 건너뛰기가 허용된 경우에만 적용됩니다."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "draft_id": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d",
                  "created_at": "2026-10-31T10:00:00Z",
                  "updated_at": "2026-10-31T10:00:00Z",
                  "party": {
                    "entity_type": "person",
                    "first_name": "Ana",
                    "last_name": "Lopez",
                    "roles": [
                      "ubo",
                      "director"
                    ],
                    "ownership_percent": 60,
                    "nationality": "MEX",
                    "email": "ana.lopez@example.com",
                    "date_of_birth": "1984-06-12"
                  }
                }
              }
            }
          },
          "400": {
            "description": "당사자 필드가 유효하지 않거나 필수 필드가 누락되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "example": {
                  "non_field_errors": [
                    "Person parties require at least one role."
                  ]
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "스코프 지정 키에 decisions: write 권한이 없음",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나, 삭제되었거나, 다른 애플리케이션에 속해 있거나, 범위가 지정된 키의 제한 범위를 벗어났습니다. 이를 구분하는 세부 정보는 제공되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          },
          "409": {
            "description": "세션이 종료되었습니다(`kyb_session_not_writable`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "This verification session is no longer accepting changes.",
                  "code": "kyb_session_not_writable"
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. API 키당 분당 300회의 쓰기(POST, PATCH, DELETE) 요청으로 제한됩니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요. `X-RateLimit-*` 헤더에 한도 정보가 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "현재 분에 할당된 예산이 소진되었습니다",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.create_kyb_party_draft(\n    \"33333333-4444-5555-6666-777777777777\",\n    entity_type=\"person\",\n    first_name=\"Ana\",\n    last_name=\"Lopez\",\n    roles=[\"ubo\", \"director\"],\n    date_of_birth=\"1984-06-12\",\n    email=\"ana.lopez@example.com\",\n    ownership_percent=60.0,\n    nationality=\"MEX\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.createKybPartyDraft(\"33333333-4444-5555-6666-777777777777\", {\n  entity_type: \"person\",\n  first_name: \"Ana\",\n  last_name: \"Lopez\",\n  roles: [\"ubo\", \"director\"],\n  date_of_birth: \"1984-06-12\",\n  email: \"ana.lopez@example.com\",\n  ownership_percent: 60.0,\n  nationality: \"MEX\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.CreateKYBPartyDraft(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsCreateKYBPartyDraftParams{\n\tEntityType:       \"person\",\n\tFirstName:        didit.String(\"Ana\"),\n\tLastName:         didit.String(\"Lopez\"),\n\tRoles:            didit.Some([]didit.SessionsCreateKYBPartyDraftParamsRoles{\"ubo\", \"director\"}),\n\tDateOfBirth:      didit.String(\"1984-06-12\"),\n\tEmail:            didit.String(\"ana.lopez@example.com\"),\n\tOwnershipPercent: didit.Float(60.0),\n\tNationality:      \"MEX\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsCreateKybPartyDraftParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().createKybPartyDraft(\"33333333-4444-5555-6666-777777777777\", SessionsCreateKybPartyDraftParams.builder()\n        .entityType(SessionsCreateKybPartyDraftParams.EntityType.of(\"person\"))\n        .firstName(\"Ana\")\n        .lastName(\"Lopez\")\n        .roles(List.of(SessionsCreateKybPartyDraftParams.Roles.of(\"ubo\"), SessionsCreateKybPartyDraftParams.Roles.of(\"director\")))\n        .dateOfBirth(LocalDate.parse(\"1984-06-12\"))\n        .email(\"ana.lopez@example.com\")\n        .ownershipPercent(60.0)\n        .nationality(\"MEX\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->createKybPartyDraft('33333333-4444-5555-6666-777777777777', [\n    'entity_type' => 'person',\n    'first_name' => 'Ana',\n    'last_name' => 'Lopez',\n    'roles' => ['ubo', 'director'],\n    'date_of_birth' => '1984-06-12',\n    'email' => 'ana.lopez@example.com',\n    'ownership_percent' => 60.0,\n    'nationality' => 'MEX',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.create_kyb_party_draft(\n  \"33333333-4444-5555-6666-777777777777\",\n  entity_type: \"person\",\n  first_name: \"Ana\",\n  last_name: \"Lopez\",\n  roles: [\"ubo\", \"director\"],\n  date_of_birth: \"1984-06-12\",\n  email: \"ana.lopez@example.com\",\n  ownership_percent: 60.0,\n  nationality: \"MEX\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.CreateKybPartyDraftAsync(\"33333333-4444-5555-6666-777777777777\", new SessionsCreateKybPartyDraftParams\n{\n    EntityType = \"person\",\n    FirstName = \"Ana\",\n    LastName = \"Lopez\",\n    Roles = new SessionsCreateKybPartyDraftParamsRoles[] { \"ubo\", \"director\" },\n    DateOfBirth = \"1984-06-12\",\n    Email = \"ana.lopez@example.com\",\n    OwnershipPercent = 60.0,\n    Nationality = \"MEX\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/parties/drafts/{draftId}/": {
      "patch": {
        "summary": "KYB 당사자 초안 수정",
        "description": "관계자 임시 저장본 하나의 필드를 변경합니다. 수정 사항은 저장된 임시 저장본에 병합되며 병합된 관계자 정보 전체를 대상으로 유효성을 검사하므로, 관계자 정보가 불완전해지는 수정은 거부됩니다. `first_name` 또는 `last_name`을 변경하면 저장된 성명이 대체됩니다. `write:businesses` 권한이 필요합니다.",
        "operationId": "patch_v3_session_kyb_party_draft",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_kyb_party_draft",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "기업 확인(KYB) 세션의 UUID입니다. 해당 API 키의 애플리케이션에 속해 있어야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "description": "당사자 초안의 UUID(생성 시 반환된 `draft_id`).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "KYB 단계의 워크플로 노드입니다. 워크플로에 둘 이상의 KYB 노드가 있는 경우에만 필요하며, 기본적으로 Didit은 세션 자체의 노드를 사용합니다.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "당사자 필드의 모든 하위 집합입니다. 수정 사항은 저장된 임시 초안에 병합되며 병합된 당사자 정보는 전체적으로 유효성이 검증되므로, 수정 전에 제출할 수 있었던 초안은 수정 후에도 제출할 수 있습니다.",
                "properties": {
                  "entity_type": {
                    "type": "string",
                    "enum": [
                      "person",
                      "company"
                    ],
                    "description": "해당 당사자가 개인인지 기업인지 여부입니다."
                  },
                  "full_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "개인의 성명입니다. 이 값을 전송하거나, `first_name` 및 `last_name`을 전송하십시오."
                  },
                  "first_name": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "last_name": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "director",
                      "non_executive_director",
                      "secretary",
                      "chairman",
                      "ubo",
                      "shareholder",
                      "representative",
                      "founder",
                      "legal_advisor",
                      "authorized_signatory",
                      "trustee",
                      "beneficiary",
                      "settlor",
                      "protector",
                      "company_officer",
                      "investor",
                      "other"
                    ],
                    "description": "해당 당사자가 보유한 역할. `roles`와 서로 바꿔 사용할 수 있으며, 둘 다 전송되면 병합됩니다."
                  },
                  "roles": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "director",
                        "non_executive_director",
                        "secretary",
                        "chairman",
                        "ubo",
                        "shareholder",
                        "representative",
                        "founder",
                        "legal_advisor",
                        "authorized_signatory",
                        "trustee",
                        "beneficiary",
                        "settlor",
                        "protector",
                        "company_officer",
                        "investor",
                        "other"
                      ]
                    },
                    "description": "해당 주체가 보유한 모든 역할입니다. 개인은 최소 하나의 역할(여기 또는 `role`)이 필요합니다."
                  },
                  "position": {
                    "type": "string",
                    "maxLength": 128,
                    "description": "개인의 직책입니다."
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "nullable": true
                  },
                  "company_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "기업 당사자의 이름입니다. `entity_type`이 `company`인 경우 필수입니다."
                  },
                  "registration_number": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "기업 당사자의 등록번호입니다."
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "인증 링크가 전송되는 위치입니다. 당사자가 인증을 완료해야 할 때 필수이며, 이는 워크플로의 역할 설정 및 소유 구조 임계값에 따라 결정됩니다."
                  },
                  "ownership_percent": {
                    "type": "number",
                    "nullable": true,
                    "description": "해당 주체가 보유한 기업의 지분입니다."
                  },
                  "nationality": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "개인의 국적 또는 기업의 설립 국가입니다. 모든 당사자에게 필수입니다."
                  },
                  "phone_number": {
                    "type": "string",
                    "maxLength": 32
                  },
                  "custom_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "워크플로에서 정의된 추가 필드입니다."
                  },
                  "skip_verification": {
                    "type": "boolean",
                    "default": false,
                    "description": "이 당사자의 인증 건너뛰기를 요청합니다. 워크플로의 주요 인물 설정에서 해당 당사자의 역할에 건너뛰기가 허용된 경우에만 적용됩니다."
                  }
                }
              },
              "example": {
                "ownership_percent": 55
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "초안이 업데이트되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "draft_id",
                    "created_at",
                    "updated_at",
                    "party"
                  ],
                  "properties": {
                    "draft_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "party": {
                      "type": "object",
                      "required": [
                        "entity_type",
                        "nationality"
                      ],
                      "properties": {
                        "entity_type": {
                          "type": "string",
                          "enum": [
                            "person",
                            "company"
                          ],
                          "description": "해당 당사자가 개인인지 기업인지 여부입니다."
                        },
                        "full_name": {
                          "type": "string",
                          "maxLength": 255,
                          "description": "개인의 성명입니다. 이 값을 전송하거나, `first_name` 및 `last_name`을 전송하십시오."
                        },
                        "first_name": {
                          "type": "string",
                          "maxLength": 128
                        },
                        "last_name": {
                          "type": "string",
                          "maxLength": 128
                        },
                        "role": {
                          "type": "string",
                          "enum": [
                            "director",
                            "non_executive_director",
                            "secretary",
                            "chairman",
                            "ubo",
                            "shareholder",
                            "representative",
                            "founder",
                            "legal_advisor",
                            "authorized_signatory",
                            "trustee",
                            "beneficiary",
                            "settlor",
                            "protector",
                            "company_officer",
                            "investor",
                            "other"
                          ],
                          "description": "해당 당사자가 보유한 역할. `roles`와 서로 바꿔 사용할 수 있으며, 둘 다 전송되면 병합됩니다."
                        },
                        "roles": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "enum": [
                              "director",
                              "non_executive_director",
                              "secretary",
                              "chairman",
                              "ubo",
                              "shareholder",
                              "representative",
                              "founder",
                              "legal_advisor",
                              "authorized_signatory",
                              "trustee",
                              "beneficiary",
                              "settlor",
                              "protector",
                              "company_officer",
                              "investor",
                              "other"
                            ]
                          },
                          "description": "해당 주체가 보유한 모든 역할입니다. 개인은 최소 하나의 역할(여기 또는 `role`)이 필요합니다."
                        },
                        "position": {
                          "type": "string",
                          "maxLength": 128,
                          "description": "개인의 직책입니다."
                        },
                        "date_of_birth": {
                          "type": "string",
                          "format": "date",
                          "nullable": true
                        },
                        "company_name": {
                          "type": "string",
                          "maxLength": 255,
                          "description": "기업 당사자의 이름입니다. `entity_type`이 `company`인 경우 필수입니다."
                        },
                        "registration_number": {
                          "type": "string",
                          "maxLength": 100,
                          "description": "기업 당사자의 등록번호입니다."
                        },
                        "email": {
                          "type": "string",
                          "format": "email",
                          "description": "인증 링크가 전송되는 위치입니다. 당사자가 인증을 완료해야 할 때 필수이며, 이는 워크플로의 역할 설정 및 소유 구조 임계값에 따라 결정됩니다."
                        },
                        "ownership_percent": {
                          "type": "number",
                          "nullable": true,
                          "description": "해당 주체가 보유한 기업의 지분입니다."
                        },
                        "nationality": {
                          "type": "string",
                          "maxLength": 100,
                          "description": "개인의 국적 또는 기업의 설립 국가입니다. 모든 당사자에게 필수입니다."
                        },
                        "phone_number": {
                          "type": "string",
                          "maxLength": 32
                        },
                        "custom_fields": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "워크플로에서 정의된 추가 필드입니다."
                        },
                        "skip_verification": {
                          "type": "boolean",
                          "default": false,
                          "description": "이 당사자의 인증 건너뛰기를 요청합니다. 워크플로의 주요 인물 설정에서 해당 당사자의 역할에 건너뛰기가 허용된 경우에만 적용됩니다."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "draft_id": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d",
                  "created_at": "2026-10-31T10:00:00Z",
                  "updated_at": "2026-10-31T10:00:00Z",
                  "party": {
                    "entity_type": "person",
                    "first_name": "Ana",
                    "last_name": "Lopez",
                    "roles": [
                      "ubo",
                      "director"
                    ],
                    "ownership_percent": 55,
                    "nationality": "MEX",
                    "email": "ana.lopez@example.com",
                    "date_of_birth": "1984-06-12"
                  }
                }
              }
            }
          },
          "400": {
            "description": "병합된 당사자가 유효하지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "example": {
                  "non_field_errors": [
                    "Person parties require at least one role."
                  ]
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "스코프 지정 키에 decisions: write 권한이 없음",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션 또는 초안이 존재하지 않거나, 세션이 키의 애플리케이션 외부이거나 범위가 지정된 키의 제한 범위를 벗어났습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          },
          "409": {
            "description": "세션이 종료되었습니다(`kyb_session_not_writable`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "This verification session is no longer accepting changes.",
                  "code": "kyb_session_not_writable"
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. API 키당 분당 300회의 쓰기(POST, PATCH, DELETE) 요청으로 제한됩니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요. `X-RateLimit-*` 헤더에 한도 정보가 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "현재 분에 할당된 예산이 소진되었습니다",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_kyb_party_draft(\n    \"33333333-4444-5555-6666-777777777777\",\n    \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n    ownership_percent=55.0,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateKybPartyDraft(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n  {\n    ownership_percent: 55.0,\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateKYBPartyDraft(ctx, \"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\", didit.SessionsUpdateKYBPartyDraftParams{\n\tOwnershipPercent: didit.Float(55.0),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateKybPartyDraftParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateKybPartyDraft(\"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\", SessionsUpdateKybPartyDraftParams.builder()\n        .ownershipPercent(55.0)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateKybPartyDraft('33333333-4444-5555-6666-777777777777', '5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d', [\n    'ownership_percent' => 55.0,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_kyb_party_draft(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n  ownership_percent: 55.0\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateKybPartyDraftAsync(\"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\", new SessionsUpdateKybPartyDraftParams\n{\n    OwnershipPercent = 55.0,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "summary": "KYB 관계자 초안을 삭제합니다.",
        "description": "관계자 초안 하나를 삭제합니다. 신고된 관계자에게는 영향을 주지 않습니다. `write:businesses` 권한이 필요합니다.",
        "operationId": "delete_v3_session_kyb_party_draft",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "delete_kyb_party_draft",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "기업 확인(KYB) 세션의 UUID입니다. 해당 API 키의 애플리케이션에 속해 있어야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "description": "당사자 초안의 UUID(생성 시 반환된 `draft_id`).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "KYB 단계의 워크플로 노드입니다. 워크플로에 둘 이상의 KYB 노드가 있는 경우에만 필요하며, 기본적으로 Didit은 세션 자체의 노드를 사용합니다.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "초안이 삭제되었습니다. 본문이 없습니다."
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "스코프 지정 키에 decisions: write 권한이 없음",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션 또는 초안이 존재하지 않거나, 세션이 키의 애플리케이션 외부이거나 범위가 지정된 키의 제한 범위를 벗어났습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          },
          "409": {
            "description": "세션이 종료되었습니다(`kyb_session_not_writable`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "This verification session is no longer accepting changes.",
                  "code": "kyb_session_not_writable"
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. API 키당 분당 300회의 쓰기(POST, PATCH, DELETE) 요청으로 제한됩니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요. `X-RateLimit-*` 헤더에 한도 정보가 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "현재 분에 할당된 예산이 소진되었습니다",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.sessions.delete_kyb_party_draft(\n    \"33333333-4444-5555-6666-777777777777\",\n    \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.sessions.deleteKybPartyDraft(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Sessions.DeleteKYBPartyDraft(ctx, \"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\", didit.SessionsDeleteKYBPartyDraftParams{}); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().deleteKybPartyDraft(\"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->sessions->deleteKybPartyDraft('33333333-4444-5555-6666-777777777777', '5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.delete_kyb_party_draft(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\"\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Sessions.DeleteKybPartyDraftAsync(\"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\");"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/parties/submit/": {
      "post": {
        "summary": "KYB 당사자 초안 제출",
        "description": "저장된 초안을 회사의 주요 인물로 신고합니다. 이는 귀하의 API 키로 실행되는 호스팅 주요 인물 단계입니다. Didit은 워크플로의 역할 설정 및 소유권 임계값에 따라 검증해야 할 대상을 결정하고, 각 대상에 대해 개별 KYC 세션(법인 소유자의 경우 KYB 하위 세션)을 하나씩 생성하며, 워크플로에서 요구하는 이메일을 발송하고 세션을 진행합니다. 각 하위 세션은 호스팅 플로우와 동일하게 과금됩니다. 초안은 소진됩니다. 성공적으로 제출한 후 호출을 반복해도 변경되지 않으며 `already_submitted: true` 및 이미 존재하는 대상 목록과 함께 `200`을 반환합니다. 세션은 주요 인물 단계에 있어야 합니다. 각 사람에게 `kyc_session_url`을 전송하거나 임베드하세요. `write:businesses` 권한이 필요합니다.",
        "operationId": "post_v3_session_kyb_parties_submit",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "submit_kyb_parties",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "기업 확인(KYB) 세션의 UUID입니다. 해당 API 키의 애플리케이션에 속해 있어야 합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "KYB 단계의 워크플로 노드입니다. 워크플로에 둘 이상의 KYB 노드가 있는 경우에만 필요하며, 기본적으로 Didit은 세션 자체의 노드를 사용합니다.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "locale": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "세션이 진행되는 다음 단계의 응답을 번역하는 데 사용되는 로캘입니다."
                  }
                }
              },
              "example": {
                "locale": "es"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "신고된(또는 이미 신고된) 당사자입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean"
                    },
                    "next_step": {
                      "type": "string",
                      "nullable": true,
                      "description": "세션이 위치한 단계입니다."
                    },
                    "status": {
                      "type": "string",
                      "description": "기업 세션의 상태입니다."
                    },
                    "advanced": {
                      "type": "boolean",
                      "description": "이 호출로 당사자가 선언되고 세션이 진행된 경우 `true`입니다."
                    },
                    "already_submitted": {
                      "type": "boolean",
                      "description": "이전 호출을 통해 당사자들이 이미 선언된 경우 `true`입니다."
                    },
                    "kyb_key_people_status": {
                      "type": "string"
                    },
                    "parties": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/KYBKeyPeopleParty"
                      }
                    }
                  }
                },
                "example": {
                  "valid": true,
                  "next_step": "FINISHED",
                  "status": "In Progress",
                  "advanced": true,
                  "already_submitted": false,
                  "kyb_key_people_status": "In Progress",
                  "parties": []
                }
              }
            }
          },
          "402": {
            "description": "하위 인증 세션에 사용할 조직의 크레딧이 남아 있지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "example": {
                  "detail": "Insufficient credits."
                }
              }
            }
          },
          "401": {
            "description": "스코프가 지정된 API 키가 만료되었습니다. `401`이 반환되는 유일한 경우이며, 누락되었거나 유효하지 않거나 폐기된 키에는 `403`이 반환됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "키의 만료일이 지났습니다",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "인증 또는 권한 부여에 실패했습니다. 키가 누락된 경우 `403`이 반환되며, 다른 애플리케이션의 키, 이 endpoint에 필요한 권한이 없는 범위 지정 키, 키의 IP 허용 목록 외부에서 보낸 요청의 경우에도 마찬가지입니다. 잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. `detail`로 구분하십시오.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "x-api-key 헤더가 없거나 키 검증에 실패했습니다",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "세션과 다른 애플리케이션에 속한 유효한 키입니다",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "스코프 지정 키에 decisions: write 권한이 없음",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "키의 IP 허용 목록 외부로부터의 요청",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "세션이 존재하지 않거나, 삭제되었거나, 다른 애플리케이션에 속해 있거나, 범위가 지정된 키의 제한 범위를 벗어났습니다. 이를 구분하는 세부 정보는 제공되지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          },
          "409": {
            "description": "`kyb_no_party_drafts`: 제출할 내용이 없습니다. `kyb_parties_already_submitted`: 당사자가 선언된 후 임시 초안이 추가되었습니다. `kyb_step_mismatch`: 세션이 주요 인물 단계에 있지 않습니다(`next_step`에 해당 단계 이름이 지정됨). `kyb_session_not_writable`: 세션이 완료되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    },
                    "code": {
                      "type": "string"
                    },
                    "next_step": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "There are no draft parties to submit.",
                  "code": "kyb_no_party_drafts"
                }
              }
            }
          },
          "429": {
            "description": "속도 제한을 초과했습니다. API 키당 분당 300회의 쓰기(POST, PATCH, DELETE) 요청으로 제한됩니다. 재시도하기 전에 `Retry-After`초 동안 대기하세요. `X-RateLimit-*` 헤더에 한도 정보가 표시됩니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "사람이 읽기 쉬운 오류 메시지입니다."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "현재 분에 할당된 예산이 소진되었습니다",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "재시도하기 전 대기할 시간(초)입니다.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.submit_kyb_parties(\n    \"33333333-4444-5555-6666-777777777777\",\n    locale=\"es\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.submitKybParties(\"33333333-4444-5555-6666-777777777777\", {\n  locale: \"es\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.SubmitKYBParties(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsSubmitKYBPartiesParams{\n\tLocale: didit.String(\"es\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsSubmitKybPartiesParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().submitKybParties(\"33333333-4444-5555-6666-777777777777\", SessionsSubmitKybPartiesParams.builder()\n        .locale(\"es\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->submitKybParties('33333333-4444-5555-6666-777777777777', [\n    'locale' => 'es',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.submit_kyb_parties(\n  \"33333333-4444-5555-6666-777777777777\",\n  locale: \"es\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.SubmitKybPartiesAsync(\"33333333-4444-5555-6666-777777777777\", new SessionsSubmitKybPartiesParams\n{\n    Locale = \"es\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/files-export/": {
      "post": {
        "summary": "세션의 모든 파일 내보내기",
        "description": "사용자 인증(KYC) 또는 기업 확인(KYB) 세션의 모든 이미지, 동영상 및 문서를 원본 품질로 하나의 ZIP 파일로 준비하기 시작합니다. 파일은 캡처된 그대로 ZIP에 저장되며 재압축되지 않습니다. 내보내기 정보와 함께 `202`로 응답하며, `status`가 `READY`가 될 때까지 `GET /v3/session/{sessionId}/files-export/{exportId}/`로 조회한 후 `download_url`을 다운로드합니다. 동일한 세션의 내보내기가 여전히 준비 중인 경우 새 내보내기 대신 해당 내보내기가 반환됩니다.\n\nZIP 파일은 준비된 지 24시간 후에 삭제되며, 세션이 삭제되면 즉시 삭제됩니다. 삭제된 세션은 내보낼 수 없습니다. 제공된 모든 내보내기 및 다운로드 링크는 세션의 감사 로그에 기록됩니다. 범위가 지정된 API 키에는 `media: read` 및 `decisions: read` 권한이 필요하며, 콘솔 사용자에게는 세션 읽기 권한이 필요합니다.",
        "operationId": "post_v3_session_files_export",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "export_files",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "인증 세션의 UUID(`POST /v3/session/`에서 반환된 `session_id`)입니다. 사용자 인증(KYC) 및 기업 확인(KYB) 세션 ID를 모두 지원합니다. 삭제된 세션은 `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/files-export/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.export_files(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.exportFiles(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ExportFiles(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().exportFiles(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->exportFiles('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.export_files(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ExportFilesAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "202": {
            "description": "준비 중인 내보내기입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionFilesExport"
                },
                "example": {
                  "export_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                  "session_id": "11111111-2222-3333-4444-555555555555",
                  "status": "PENDING",
                  "file_count": null,
                  "size_bytes": null,
                  "download_url": null,
                  "expires_at": null,
                  "error": null,
                  "created_at": "2026-10-29T12:00:03Z",
                  "completed_at": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/files-export/{exportId}/": {
      "get": {
        "summary": "세션 파일 내보내기 조회",
        "description": "`POST /v3/session/{sessionId}/files-export/`로 시작된 내보내기의 진행 상황입니다. `status`가 `READY`가 되면 `download_url`은 짧은 시간 동안 유효한 서명된 ZIP URL이 됩니다. `expires_at`까지 새 URL을 받으려면 내보내기를 다시 조회하십시오. 다운로드 링크를 제공하는 각 조회는 세션의 감사 로그에 기록됩니다. 삭제된 세션의 내보내기는 `404`를 반환합니다.",
        "operationId": "get_v3_session_files_export",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "get_files_export",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "인증 세션의 UUID(`POST /v3/session/`에서 반환된 `session_id`)입니다. 사용자 인증(KYC) 및 기업 확인(KYB) 세션 ID를 모두 지원합니다. 삭제된 세션은 `404`를 반환합니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "description": "`POST /v3/session/{sessionId}/files-export/`에서 반환된 `export_id`입니다.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/files-export/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.get_files_export(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.getFilesExport(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.GetFilesExport(ctx, \"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().getFilesExport(\"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->getFilesExport('11111111-2222-3333-4444-555555555555', 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.get_files_export(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.GetFilesExportAsync(\"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "내보내기입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionFilesExport"
                },
                "example": {
                  "export_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                  "session_id": "11111111-2222-3333-4444-555555555555",
                  "status": "READY",
                  "file_count": 9,
                  "size_bytes": 18734120,
                  "download_url": "https://storage.example.com/session/11111111-2222-3333-4444-555555555555/files-export/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/session-42-files.zip?X-Amz-Signature=...",
                  "expires_at": "2026-10-30T12:00:41Z",
                  "error": null,
                  "created_at": "2026-10-29T12:00:03Z",
                  "completed_at": "2026-10-29T12:00:41Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/travel-rule/unmatched/": {
      "get": {
        "summary": "일치하지 않는 Travel Rule 입금 내역 목록 조회",
        "description": "송금인 VASP의 Travel Rule 데이터를 아직 기다리고 있는 인바운드 입금: 전송 상태가 `AWAITING_COUNTERPARTY`, `NOT_ENOUGH_COUNTERPARTY_DATA` 또는 `COUNTERPARTY_VASP_NOT_FOUND`이며, 수신된 메시지와 매칭되지 않았고, 아무도 수동으로 매칭하지 않은 상태입니다. 행과 필터는 `GET /v3/travel-rule/transfers/`와 동일하며 최신순으로 정렬되고 `limit`(기본값 50) 및 `offset`으로 페이지네이션됩니다. `POST /v3/travel-rule/unmatched/{transaction_uuid}/match/`를 사용하여 송금인 VASP가 보낸 메시지와 입금을 매칭하십시오.",
        "operationId": "listUnmatchedTravelRuleDeposits",
        "x-didit-sdk": {
          "resource": "travel_rule.unmatched_deposits",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "direction",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "INBOUND, OUTBOUND 또는 쉼표로 구분한 두 값입니다. 대소문자를 구분합니다."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "하나 이상의 전송 상태(쉼표로 구분)입니다."
          },
          {
            "name": "rail",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "INTERNAL, TRP, GTR, TRUST, VERIFYVASP, SYGNA, EMAIL, TEST_VASP 중 하나 이상(쉼표로 구분)입니다."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "쉼표로 구분된 withdrawal, deposit 또는 message입니다."
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "거래의 통화(대소문자 구분 없음)입니다."
          },
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "이 날짜(UTC) 당일 또는 이후에 생성된 이체입니다(YYYY-MM-DD)."
          },
          {
            "name": "end_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "이 날짜(UTC) 당일 또는 이전에 생성된 이체입니다(YYYY-MM-DD)."
          },
          {
            "name": "counterparty",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "GET /v3/travel-rule/vasps/의 디렉터리 항목 또는 Didit 네트워크 멤버의 `id`입니다. 해당 거래 상대방과의 전송에 사용됩니다. 유효한 id가 아닌 값은 400을 반환합니다."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000000
            },
            "description": "페이지 크기, 기본값 50입니다."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 1000000
            },
            "description": "건너뛸 행."
          }
        ],
        "responses": {
          "200": {
            "description": "일치되지 않은 입금 페이지입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TravelRuleTransferRow"
                      }
                    }
                  }
                },
                "example": {
                  "count": 1,
                  "next": null,
                  "previous": null,
                  "results": [
                    {
                      "id": "7d3a1c55-0b9e-4d52-8a3c-1f6e2b9d4a08",
                      "transaction_id": "c41f9b2e-5a8d-4e0c-9f17-3b6d8a2e5c91",
                      "txn_id": "dep-2026-10-20-0007",
                      "txn_date": "2026-10-19T08:41:12Z",
                      "kind": "deposit",
                      "direction": "INBOUND",
                      "status": "AWAITING_COUNTERPARTY",
                      "rail": "TRP",
                      "asset": "ETH",
                      "amount": "1.25",
                      "originator_vasp": "",
                      "beneficiary_vasp": "Example Counterparty VASP",
                      "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7",
                      "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
                      "originator_memo": "",
                      "beneficiary_memo": "",
                      "originator_wallet_type": "vasp",
                      "beneficiary_wallet_type": "vasp",
                      "matched_transaction_id": null,
                      "deadline_at": null,
                      "created_at": "2026-10-19T08:41:13Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "필터 값이 유효하지 않습니다.",
            "content": {
              "application/json": {
                "example": {
                  "start_date": [
                    "Use the YYYY-MM-DD format."
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.unmatched_deposits.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.unmatchedDeposits.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.UnmatchedDeposits.ListAutoPaging(ctx, didit.TravelRuleUnmatchedDepositsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().unmatchedDeposits().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->travelRule->unmatchedDeposits->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.unmatched_deposits.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.UnmatchedDeposits.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/travel-rule/unmatched/{transaction_uuid}/match/": {
      "post": {
        "summary": "Travel Rule 입금을 수신된 메시지와 일치시키기",
        "operationId": "matchUnmatchedTravelRuleDeposit",
        "x-didit-sdk": {
          "resource": "travel_rule.unmatched_deposits",
          "method": "match",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "송금인 데이터가 아직 도착하기를 기다리는 인바운드 입금을 송신 VASP가 해당 입금에 대해 전송한 Travel Rule 메시지와 연결합니다. 입금 건은 메시지의 송금인 데이터, 거래 상대방 VASP 및 레일을 가져오며, 두 전송 건 모두 타임라인에 일치 결과를 기록합니다. `transaction_uuid`는 `GET /v3/travel-rule/unmatched/`에서 조회한 입금의 `transaction_id`입니다. 본문의 `transaction_id`는 `GET /v3/travel-rule/transfers/?kind=message`의 행에서 가져온 수신 메시지의 `transaction_id`이며, 전송 자체의 `id`로는 조회되지 않습니다. 메시지는 입금과 동일한 자산에 대한 것이어야 합니다. Console에서 삭제된 입금 또는 메시지는 `404`를 반환하고, 이미 진행된(일치 완료되었거나 더 이상 대기 중이 아닌) 건은 `409`를 반환합니다.",
        "parameters": [
          {
            "name": "transaction_uuid",
            "in": "path",
            "required": true,
            "description": "일치하지 않은 입금의 `transaction_id`입니다.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleManualMatchRequest"
              },
              "example": {
                "transaction_id": "e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "일치 후의 두 이체입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleManualMatchResponse"
                },
                "example": {
                  "deposit": {
                    "id": "7d3a1c55-0b9e-4d52-8a3c-1f6e2b9d4a08",
                    "transaction_id": "c41f9b2e-5a8d-4e0c-9f17-3b6d8a2e5c91",
                    "txn_id": "dep-2026-10-20-0007",
                    "txn_date": "2026-10-19T08:41:12Z",
                    "kind": "deposit",
                    "direction": "INBOUND",
                    "status": "AWAITING_COUNTERPARTY",
                    "rail": "TRP",
                    "asset": "ETH",
                    "amount": "1.25",
                    "originator_vasp": "Example Counterparty VASP",
                    "beneficiary_vasp": "Example Counterparty VASP",
                    "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7",
                    "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
                    "originator_memo": "",
                    "beneficiary_memo": "",
                    "originator_wallet_type": "vasp",
                    "beneficiary_wallet_type": "vasp",
                    "matched_transaction_id": "e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24",
                    "deadline_at": null,
                    "created_at": "2026-10-19T08:41:13Z"
                  },
                  "message": {
                    "id": "2b8e6f10-9c3a-47d1-b5e2-0a4c7d9f3e66",
                    "transaction_id": "e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24",
                    "txn_id": "msg-2026-10-20-0003",
                    "txn_date": "2026-10-19T08:41:12Z",
                    "kind": "message",
                    "direction": "INBOUND",
                    "status": "COMPLETED",
                    "rail": "TRP",
                    "asset": "ETH",
                    "amount": "1.25",
                    "originator_vasp": "Origin CASP SL",
                    "beneficiary_vasp": "Example Counterparty VASP",
                    "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7",
                    "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
                    "originator_memo": "",
                    "beneficiary_memo": "",
                    "originator_wallet_type": "vasp",
                    "beneficiary_wallet_type": "vasp",
                    "matched_transaction_id": null,
                    "deadline_at": "2026-10-21T08:41:13Z",
                    "created_at": "2026-10-19T08:41:13Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "유효성 검사 오류: `transaction_id`가 누락되었거나, 입금 자체이거나, 수신된 Travel Rule 메시지가 아니거나, 입금과 다른 자산에 대한 것이거나, 경로의 거래가 인바운드 입금이 아닙니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Error": {
                    "value": {
                      "transaction_id": [
                        "The travel rule message is for a different asset than the deposit."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "알 수 없는 입금 또는 메시지이거나 둘 중 하나가 삭제되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No TravelRuleTransfer matches the given query."
                }
              }
            }
          },
          "409": {
            "description": "입금이 더 이상 송금인 데이터를 기다리지 않거나, 메시지가 이미 입금과 일치되었습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Error": {
                    "value": {
                      "detail": "This deposit is no longer waiting for originator data."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.unmatched_deposits.match(\n    \"11111111-2222-3333-4444-555555555555\",\n    transaction_id=\"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.unmatchedDeposits.match(\"11111111-2222-3333-4444-555555555555\", {\n  transaction_id: \"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.UnmatchedDeposits.Match(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleManualMatchRequest{\n\tTransactionID: \"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleManualMatchRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().unmatchedDeposits().match(\"11111111-2222-3333-4444-555555555555\", TravelRuleManualMatchRequest.builder()\n        .transactionId(\"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->unmatchedDeposits->match('11111111-2222-3333-4444-555555555555', [\n    'transaction_id' => 'e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.unmatched_deposits.match(\n  \"11111111-2222-3333-4444-555555555555\",\n  transaction_id: \"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.UnmatchedDeposits.MatchAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleManualMatchRequest\n{\n    TransactionId = \"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "DocumentAIDetectedCode": {
        "type": "object",
        "required": [
          "type",
          "page_number",
          "position",
          "x",
          "y",
          "width",
          "height",
          "page_width",
          "page_height",
          "raw_payload",
          "parsed_payload"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "감지된 심볼로지(예: `QR_CODE`, `CODE_128`, `EAN_13`, `DATA_MATRIX` 또는 `PDF_417`)입니다."
          },
          "page_number": {
            "type": "integer",
            "minimum": 1,
            "description": "1부터 시작하는 페이지 번호입니다."
          },
          "position": {
            "type": "array",
            "nullable": true,
            "description": "렌더링된 페이지의 픽셀 좌표로 감지된 다각형(polygon)입니다. 신뢰할 수 있는 위치를 찾을 수 없는 경우 `null`입니다.",
            "items": {
              "type": "array",
              "minItems": 2,
              "maxItems": 2,
              "items": {
                "type": "integer"
              }
            }
          },
          "x": {
            "type": "integer",
            "nullable": true,
            "description": "렌더링된 페이지 픽셀 단위의 경계 상자 왼쪽 가장자리입니다."
          },
          "y": {
            "type": "integer",
            "nullable": true,
            "description": "렌더링된 페이지 픽셀 기준 경계 상자의 상단 가장자리입니다."
          },
          "width": {
            "type": "integer",
            "nullable": true,
            "description": "렌더링된 페이지 픽셀 단위의 경계 상자 너비입니다."
          },
          "height": {
            "type": "integer",
            "nullable": true,
            "description": "렌더링된 페이지 픽셀 단위의 경계 상자 높이입니다."
          },
          "page_width": {
            "type": "integer",
            "description": "렌더링된 페이지 너비(픽셀 단위)입니다."
          },
          "page_height": {
            "type": "integer",
            "description": "렌더링된 페이지 높이(픽셀 단위)입니다."
          },
          "raw_payload": {
            "type": "string",
            "description": "사용 가능한 경우 base64 문자열 형식의 원시 디코더 payload이며, 그렇지 않은 경우 빈 문자열입니다."
          },
          "parsed_payload": {
            "nullable": true,
            "description": "디코딩된 문자열 또는 구조화된 값입니다. 코드가 감지되었으나 디코딩할 수 없는 경우 `null`입니다."
          }
        }
      },
      "SessionImportJob": {
        "type": "object",
        "required": [
          "uuid",
          "status",
          "import_type",
          "source_format",
          "source_filename",
          "total_rows",
          "processed_rows",
          "created_count",
          "updated_count",
          "skipped_count",
          "failed_count"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "가져오기 작업 ID입니다. 이 값을 사용하여 진행 상황을 폴링하고 행 오류를 조회하십시오."
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "PROCESSING",
              "COMPLETED",
              "FAILED",
              "PAUSED",
              "CANCELLED",
              "READY"
            ]
          },
          "import_type": {
            "type": "string",
            "enum": [
              "user_verification",
              "business_verification",
              "status_rules",
              "transactions"
            ]
          },
          "source_format": {
            "type": "string",
            "enum": [
              "csv",
              "ndjson"
            ]
          },
          "source_filename": {
            "type": "string"
          },
          "total_rows": {
            "type": "integer",
            "format": "int64"
          },
          "processed_rows": {
            "type": "integer",
            "format": "int64"
          },
          "checkpoint_row": {
            "type": "integer",
            "format": "int64"
          },
          "created_count": {
            "type": "integer",
            "format": "int64"
          },
          "updated_count": {
            "type": "integer",
            "format": "int64"
          },
          "skipped_count": {
            "type": "integer",
            "format": "int64"
          },
          "failed_count": {
            "type": "integer",
            "format": "int64"
          },
          "total_media_bytes": {
            "type": "integer",
            "format": "int64"
          },
          "last_error": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "state": {
            "type": "string",
            "enum": [
              "ready",
              "queued",
              "running",
              "paused",
              "completed",
              "errors",
              "failed",
              "cancelled"
            ],
            "description": "콘솔에 표시되는 작업 상태입니다. `errors`는 거부된 행이 포함된 완료된 작업입니다."
          },
          "source": {
            "type": "string",
            "enum": [
              "file",
              "api",
              "provider"
            ]
          },
          "provider": {
            "type": "string",
            "description": "마이그레이션 소스입니다. 파일 또는 API 가져오기의 경우 비어 있습니다."
          },
          "provider_options": {
            "type": "object"
          },
          "credential_hint": {
            "type": "string",
            "description": "마이그레이션이 보유한 키의 첫 몇 글자입니다. 키 자체는 절대 반환되지 않습니다."
          },
          "credentials_expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "resumes_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "제공업체의 속도 제한으로 인해 일시 중지된 작업이 자체적으로 재개된 시점입니다."
          },
          "status_mapping": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "is_dry_run": {
            "type": "boolean"
          },
          "dry_run_summary": {
            "type": "object",
            "description": "시험 실행에서 발견된 내용: `total`, `by_status`, `already_in_didit`, `same_person`, `not_finished`, `failed`, `unmapped_statuses`입니다."
          },
          "face_templates_enabled": {
            "type": "boolean"
          },
          "lawful_basis_confirmed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "not_finished_count": {
            "type": "integer",
            "format": "int64"
          },
          "same_person_count": {
            "type": "integer",
            "format": "int64"
          },
          "face_templates_count": {
            "type": "integer",
            "format": "int64"
          },
          "face_duplicates_count": {
            "type": "integer",
            "format": "int64"
          },
          "face_blocklist_hits_count": {
            "type": "integer",
            "format": "int64"
          },
          "created_by_name": {
            "type": "string",
            "nullable": true
          },
          "created_by_email": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "SessionImportError": {
        "type": "object",
        "required": [
          "uuid",
          "row_number",
          "error",
          "raw_row"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "row_number": {
            "type": "integer",
            "format": "int64"
          },
          "external_id": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "type": "string"
          },
          "raw_row": {
            "type": "object",
            "additionalProperties": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BrandingCustomizationUpdate": {
        "type": "object",
        "description": "부분 브랜딩 업데이트 본문입니다. 변경하려는 필드만 제공하십시오. 16진수 색상은 `#RRGGBB` 또는 `#RRGGBBAA`를 허용합니다. 커스텀 도메인 및 화이트 라벨 이메일은 여기서 허용되지 않습니다.",
        "properties": {
          "color_primary": {
            "type": "string",
            "description": "헤더 / 기본 텍스트 색상입니다."
          },
          "color_secondary": {
            "type": "string",
            "description": "본문 / 보조 텍스트 색상입니다."
          },
          "color_background": {
            "type": "string",
            "description": "페이지 배경색입니다."
          },
          "color_panel": {
            "type": "string",
            "description": "패널 / 강조 색상입니다."
          },
          "color_panel_10": {
            "type": "string",
            "description": "불투명도 10%의 패널 색상입니다."
          },
          "color_on_panel_1": {
            "type": "string",
            "description": "패널의 보조 텍스트 색상입니다."
          },
          "color_on_panel_2": {
            "type": "string",
            "description": "패널의 필(pill)/배지 색상입니다."
          },
          "color_on_background": {
            "type": "string",
            "description": "배경 위의 텍스트 색상입니다."
          },
          "color_button_1": {
            "type": "string",
            "description": "기본 버튼 색상입니다."
          },
          "color_button_2": {
            "type": "string",
            "description": "보조 버튼 색상."
          },
          "color_button_text_1": {
            "type": "string",
            "description": "기본 버튼 텍스트 색상입니다."
          },
          "color_button_text_2": {
            "type": "string",
            "description": "보조 버튼 텍스트 색상."
          },
          "color_pill_text": {
            "type": "string",
            "description": "필, 입력란 및 선택기의 텍스트 색상입니다."
          },
          "border_radius_panel": {
            "type": "integer",
            "minimum": 0,
            "description": "패널 모서리 곡률(픽셀 단위)입니다."
          },
          "border_radius_buttons": {
            "type": "integer",
            "minimum": 0,
            "description": "버튼 모서리 반경(픽셀 단위)입니다."
          },
          "font_family": {
            "type": "string",
            "description": "Google Font 글꼴 패밀리 이름(예: `Inter`, `AR One Sans`)."
          },
          "font_weight": {
            "type": "string",
            "description": "선택한 글꼴 패밀리에서 사용 가능한 굵기(예: `regular`, `500`, `700`)."
          },
          "app_public_name": {
            "type": "string",
            "nullable": true,
            "description": "인증 워크플로에 표시되는 공개 이름입니다."
          },
          "privacy_policy_url": {
            "type": "string",
            "nullable": true,
            "description": "최종 사용자에게 표시되는 개인정보 처리방침 URL입니다."
          },
          "skip_welcome_screen": {
            "type": "boolean",
            "description": "초기 환영 화면을 건너뜁니다."
          },
          "disable_login_with_didit": {
            "type": "boolean",
            "description": "Didit으로 로그인 화면을 표시하는 대신 게스트로 계속 진행합니다. 커스텀 도메인이 구성되어 있는 동안에는 다시 `false`로 설정할 수 없습니다(400)."
          },
          "hide_progress_bar": {
            "type": "boolean",
            "description": "플로우 진행 중 진행률 표시줄을 숨깁니다."
          },
          "callback_seconds": {
            "type": "integer",
            "minimum": 0,
            "description": "콜백 URL로 리디렉션하기 전 지연 시간(초)입니다."
          },
          "delete_logo_square": {
            "type": "boolean",
            "description": "`true`인 경우 현재 정사각형 로고를 제거합니다."
          },
          "delete_logo_rectangular": {
            "type": "boolean",
            "description": "`true`인 경우 현재 직사각형 로고를 제거합니다."
          },
          "delete_logo_rectangular_dark": {
            "type": "boolean",
            "description": "`true`인 경우 현재 다크 모드 로고를 제거하며, 이후 `logo_rectangular_dark`는 `null`로 표시됩니다. 동일한 멀티파트 요청에서 `image_rectangular_dark`도 업로드하는 경우 업로드가 우선 적용됩니다."
          },
          "delete_favicon": {
            "type": "boolean",
            "description": "`true`인 경우 현재 파비콘을 제거합니다."
          }
        }
      },
      "BrandingCustomization": {
        "type": "object",
        "description": "애플리케이션을 위한 화이트 라벨 브랜딩: 색상, 글꼴, 모서리 곡률, 로고 URL 및 UI/UX 옵션입니다. 로고 URL은 읽기 전용입니다(이미지를 업로드하여 설정). 사용자 지정 도메인 및 화이트 라벨 이메일은 포함되지 않습니다.",
        "properties": {
          "color_primary": {
            "type": "string"
          },
          "color_secondary": {
            "type": "string"
          },
          "color_background": {
            "type": "string"
          },
          "color_panel": {
            "type": "string"
          },
          "color_panel_10": {
            "type": "string"
          },
          "color_on_panel_1": {
            "type": "string"
          },
          "color_on_panel_2": {
            "type": "string"
          },
          "color_on_background": {
            "type": "string"
          },
          "color_button_1": {
            "type": "string"
          },
          "color_button_2": {
            "type": "string"
          },
          "color_button_text_1": {
            "type": "string"
          },
          "color_button_text_2": {
            "type": "string"
          },
          "color_pill_text": {
            "type": "string"
          },
          "border_radius_panel": {
            "type": "integer"
          },
          "border_radius_buttons": {
            "type": "integer"
          },
          "font_family": {
            "type": "string"
          },
          "font_weight": {
            "type": "string"
          },
          "font_url": {
            "type": "string",
            "nullable": true,
            "description": "읽기 전용입니다. 선택한 글꼴 모음에 대해 확인된 Google Fonts 스타일시트 URL입니다."
          },
          "logo_square": {
            "type": "string",
            "nullable": true,
            "description": "정사각형 로고의 읽기 전용 URL입니다. `image_square`를 통해 업로드합니다."
          },
          "logo_rectangular": {
            "type": "string",
            "nullable": true,
            "description": "직사각형 로고의 읽기 전용 URL입니다. `image_rectangular`를 통해 업로드합니다."
          },
          "logo_rectangular_dark": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "읽기 전용입니다. 다크 모드용 직사각형 로고의 서명된 임시 URL로, 어두운 배경에 표시됩니다. 다크 모드 로고가 설정되어 있지 않거나 계정에 직사각형 로고가 표시되지 않는 경우 `null`입니다. `image_rectangular_dark`로 업로드합니다."
          },
          "favicon": {
            "type": "string",
            "nullable": true,
            "description": "파비콘의 읽기 전용 URL입니다. `image_favicon`을 통해 업로드합니다."
          },
          "app_public_name": {
            "type": "string",
            "nullable": true
          },
          "privacy_policy_url": {
            "type": "string",
            "nullable": true
          },
          "skip_welcome_screen": {
            "type": "boolean"
          },
          "disable_login_with_didit": {
            "type": "boolean"
          },
          "hide_progress_bar": {
            "type": "boolean"
          },
          "callback_seconds": {
            "type": "integer"
          }
        }
      },
      "WebhookEvent": {
        "type": "string",
        "description": "지원되는 webhook 이벤트 이름입니다. `subscribed_events`에 이 정확한 문자열을 사용해야 하며, 지원되지 않는 값은 거부됩니다.",
        "enum": [
          "status.updated",
          "data.updated",
          "user.status.updated",
          "user.data.updated",
          "business.status.updated",
          "business.data.updated",
          "activity.created",
          "transaction.created",
          "transaction.status.updated",
          "travel_rule.status.updated",
          "workflow.compliance_changed",
          "transaction_rule_suggestions.created",
          "auth.signup",
          "auth.login",
          "auth.login_failed",
          "auth.password_reset_requested",
          "auth.password_reset_completed",
          "auth.mfa_changed",
          "auth.new_device",
          "auth.account_locked",
          "investigator.report.ready",
          "investigator.decision.automated",
          "investigator.decision.overridden",
          "investigator.decision.contested",
          "investigator.question.raised",
          "investigator.automation.paused",
          "investigator.rfi.answered",
          "investigator.rfi.overdue",
          "investigator.drift.detected",
          "investigator.sla.breached",
          "investigator.qa.failed",
          "investigator.external.report.ready"
        ]
      },
      "WebhookSubscribedEvents": {
        "type": "array",
        "description": "이 webhook 대상의 이벤트 필터입니다. Didit은 이벤트 유형이 이 값 중 하나와 정확히 일치하는 webhook만 전송하며, 와일드카드 구독은 지원하지 않습니다. 요청을 보낼 때 목록에는 최소 하나 이상의 유효한 이벤트가 포함되어야 하며(명시적인 `[]`는 400 오류로 거부됨), 목록이 비어 있는(생성 시 필드를 생략한) 대상은 아무것도 수신하지 않습니다. 업데이트 시 목록은 병합되지 않고 전체가 대체됩니다.",
        "minItems": 1,
        "uniqueItems": true,
        "items": {
          "$ref": "#/components/schemas/WebhookEvent"
        },
        "example": [
          "status.updated",
          "data.updated"
        ]
      },
      "PhoneVerificationSendResponse": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "인증의 세션 id입니다. `Retry` 전송은 최초 전송과 동일한 `request_id`를 반환합니다. 이 id는 Business Console에 표시되며, 완료된 `POST /v3/phone/check/`에 의해 다시 반환되고, `GET /v3/session/{sessionId}/decision/`에 전달할 수 있습니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "Success",
              "Retry",
              "Blocked"
            ],
            "description": "`Success` — 새 인증에 OTP가 전송되었습니다. `Retry` — 이전 전송으로 생성된 대기 중인 인증에 OTP가 재전송되었습니다. `Blocked` — 사기 방지 계층에서 전송을 거부했습니다. 인증은 즉시 `Declined` 상태로 완료 처리되며 요금은 청구되지 않습니다."
          },
          "reason": {
            "type": "string",
            "nullable": true,
            "description": "발송이 `Blocked`된 이유입니다(예: `repeated_attempts`, `suspicious`, `spam`). `Success` 및 `Retry`에서는 `null`입니다."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "세션에 저장된 `vendor_data`의 에코 값입니다(첫 전송 기준)."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "description": "세션에 저장된 `metadata`의 에코 값입니다(첫 전송 기준)."
          }
        }
      },
      "PhoneVerificationCheckResponse": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "`Approved`/`Declined`인 경우: 일치하는 인증의 세션 ID — `POST /v3/phone/send/`에서 반환된 `request_id`와 동일합니다. `Failed` 및 `Expired or Not Found`인 경우: 나중에 조회할 수 없는 일회성 무작위 UUID입니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "Declined",
              "Failed",
              "Expired or Not Found"
            ],
            "description": "`Approved` — 올바른 코드이며 거부 위험이 없음. `Declined` — 최종 상태: 거부 위험이 일치했거나 시도 횟수 한도(3회)가 소진됨. `Failed` — 잘못된 코드이며 잔여 시도 횟수가 있음. `Expired or Not Found` — 지난 5분 동안 이 번호에 대한 보류 중인 인증이 없음."
          },
          "message": {
            "type": "string",
            "description": "잘못된 코드 입력 후 남은 시도 횟수를 포함한 결과에 대한 사람이 읽기 쉬운 설명입니다."
          },
          "phone": {
            "type": "object",
            "nullable": true,
            "description": "전체 전화번호 보고서입니다. 확정된 결과(`Approved`/`Declined`)에만 존재(null이 아님)하며, `Failed`인 경우 `null`, `Expired or Not Found`인 경우 생략됩니다.",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "Approved",
                  "Declined",
                  "In Review",
                  "Not Finished",
                  "Expired"
                ],
                "description": "전화번호 인증의 최종 상태입니다. 완료된 검사의 최상위 `status`와 일치합니다."
              },
              "phone_number_prefix": {
                "type": "string",
                "description": "`+`로 시작하는 국가 전화번호 코드(예: `+1`)입니다.",
                "example": "+1"
              },
              "phone_number": {
                "type": "string",
                "description": "국가 전화 코드를 제외한 국내 번호.",
                "example": "4155552671"
              },
              "full_number": {
                "type": "string",
                "description": "E.164 형식의 전체 번호입니다.",
                "example": "+14155552671"
              },
              "country_code": {
                "type": "string",
                "nullable": true,
                "description": "해당 번호의 ISO 3166-1 alpha-2 국가 코드입니다.",
                "example": "US"
              },
              "country_name": {
                "type": "string",
                "description": "`country_code`에서 파생된 전체 국가명입니다.",
                "example": "United States"
              },
              "carrier": {
                "type": "object",
                "description": "완료 단계에서 실행된 통신사 조회를 통해 확인된 해당 번호의 현재 네트워크입니다.",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "통신사 이름. 조회 시 식별할 수 없는 경우 빈 문자열입니다."
                  },
                  "type": {
                    "type": "string",
                    "description": "조회 결과로 보고된 회선 유형: `mobile`, `fixed_line`, `voip`, `isp`, `vpn`, `toll_free`, `premium_rate`, `pager`, `payphone`, `satellite`, `service`, `shared_cost`, `short_codes_commercial`, `calling_cards`, `local_rate`, `universal_access`, `voice_mail`, `other`, 또는 `unknown`."
                  }
                }
              },
              "is_disposable": {
                "type": "boolean",
                "description": "번호가 임시/버너 번호 서비스에 속하는 경우 `true`입니다."
              },
              "is_virtual": {
                "type": "boolean",
                "description": "회선 유형이 가상(`voip`, `isp` 또는 `vpn`)인 경우 `true`입니다."
              },
              "verification_method": {
                "type": "string",
                "description": "전송이 확인된 후 실제로 OTP를 전송한 채널(예: `whatsapp`, `sms`)이며, 확인되기 전까지는 요청된 채널입니다."
              },
              "verification_attempts": {
                "type": "integer",
                "description": "이 인증에 대한 OTP 전송 횟수입니다(1회, 재시도 후에는 2회)."
              },
              "verified_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "올바른 코드가 입력된 시점입니다. 인증이 승인되지 않은 경우 `null`입니다."
              },
              "warnings": {
                "type": "array",
                "description": "인증 중 기록된 위험 경고(중복, 일회용, VoIP, 시도 횟수 초과, 차단 목록 등). 없을 경우 빈 배열입니다.",
                "items": {
                  "type": "object",
                  "properties": {
                    "feature": {
                      "type": "string",
                      "description": "경고를 생성한 기능입니다. 여기서는 항상 `PHONE`입니다."
                    },
                    "risk": {
                      "type": "string",
                      "description": "기계 판독 가능한 위험 코드입니다."
                    },
                    "additional_data": {
                      "type": "object",
                      "nullable": true,
                      "description": "위험별 컨텍스트(예: 중복 위험의 경우 중복된 세션 ID). 위험에 추가 데이터가 없는 경우 `null`입니다."
                    },
                    "log_type": {
                      "type": "string",
                      "enum": [
                        "error",
                        "warning",
                        "information"
                      ],
                      "description": "심각도입니다. `error` 위험은 인증을 거부하고, `warning`은 검토 대상으로 표시하며, `information`은 상태에 영향을 주지 않고 기록됩니다."
                    },
                    "short_description": {
                      "type": "string",
                      "description": "사람이 읽을 수 있는 한 줄의 위험 요약입니다."
                    },
                    "long_description": {
                      "type": "string",
                      "description": "위험에 대한 사람이 읽기 쉬운 설명입니다."
                    }
                  }
                }
              },
              "lifecycle": {
                "type": "array",
                "description": "인증의 시간순 감사 로그입니다. 이벤트 `type`은 `PHONE_VERIFICATION_MESSAGE_SENT`, `PHONE_VERIFICATION_RETRY_MESSAGE_SENT`, `PHONE_VERIFICATION_BLOCKED`, `PHONE_DELIVERY_DELIVERED`, `PHONE_DELIVERY_UNDELIVERABLE`, `VALID_CODE_ENTERED`, `INVALID_CODE_ENTERED`, `PHONE_VERIFICATION_APPROVED`, `PHONE_VERIFICATION_DECLINED`, `PHONE_VERIFICATION_IN_REVIEW`, `PHONE_VERIFICATION_EXPIRED` 중 하나입니다.",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "description": "이벤트 유형입니다."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time",
                      "description": "이벤트가 발생한 시점입니다."
                    },
                    "details": {
                      "type": "object",
                      "nullable": true,
                      "description": "이벤트 관련 payload입니다. 발송 이벤트: `{status, reason, channel, actual_channel}` (`actual_channel`은 전송이 확인되면 채워집니다). 전송 이벤트: `{channel, status}`. 코드 입력 이벤트: `{code_tried, status}`. 최종 상태 이벤트: `null`, 또는 거부됨/검토 중일 때 `{reason}`."
                    },
                    "fee": {
                      "type": "number",
                      "description": "이 이벤트에 대해 청구된 USD 금액입니다. 발송 이벤트(전송 가격)에서만 0이 아니며, 코드 입력, 전송 확인 및 상태 이벤트에서는 0입니다."
                    }
                  }
                }
              },
              "matches": {
                "type": "array",
                "description": "다른 사용자(다른 `vendor_data`)가 동일한 전화번호를 사용한 애플리케이션의 다른 세션(KYC, KYB 또는 API)입니다. 최대 5개 항목이며, 합성 목록 항목에 대한 차단 목록 일치 항목이 있는 경우 먼저 표시됩니다(세션 파생 일치는 쿼리 순서 유지). 일치하는 항목이 없으면 빈 배열입니다.",
                "items": {
                  "type": "object",
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "이 전화번호를 사용한 다른 인증의 세션 id입니다."
                    },
                    "session_number": {
                      "type": "integer",
                      "description": "해당 세션의 사람이 읽기 쉬운 순차 번호입니다."
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "해당 세션의 `vendor_data`입니다."
                    },
                    "verification_date": {
                      "type": "string",
                      "description": "해당 세션이 생성된 시점(`YYYY-MM-DDTHH:MM:SSZ`)입니다."
                    },
                    "phone_number": {
                      "type": "string",
                      "description": "일치하는 전화번호입니다."
                    },
                    "status": {
                      "type": "string",
                      "description": "해당 세션의 상태(예: `Approved`, `Declined`, `In Progress`)입니다."
                    },
                    "is_blocklisted": {
                      "type": "boolean",
                      "description": "전화번호가 애플리케이션의 차단 목록에 있는지 여부입니다."
                    },
                    "api_service": {
                      "type": "string",
                      "nullable": true,
                      "description": "API 유형 세션의 경우 이를 생성한 독립형 API(예: `PHONE_VERIFICATION`), 일반 인증 세션의 경우 `null`입니다."
                    },
                    "source": {
                      "type": "string",
                      "description": "일치 항목이 발견된 위치입니다. 일반적으로 `session`이며, 조직 목록 항목을 통한 차단 목록 일치는 `source: \"list_entry\"` 및 null `session_id`/`session_number`가 있는 합성 일치 항목을 앞에 추가합니다."
                    }
                  }
                }
              },
              "phone_social": {
                "$ref": "#/components/schemas/PhoneSocialFootprint"
              },
              "phone_intelligence": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/PhoneIntelligence"
                  }
                ],
                "description": "전화번호 인텔리전스 신호입니다. 검사 시 `enable_enrichment`가 `true`인 경우에만 존재합니다."
              }
            }
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "일치하는 인증 세션의 `vendor_data`입니다. `Expired or Not Found`인 경우 `null`입니다."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "description": "일치하는 인증 세션의 `metadata`입니다. `Expired or Not Found`인 경우 `null`입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "이 검사 응답의 타임스탬프입니다."
          }
        }
      },
      "EmailVerificationSendResponse": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "인증의 세션 id입니다. `Retry` 전송은 최초 전송과 동일한 `request_id`를 반환합니다. 이 id는 Business Console에 표시되며, 완료된 `POST /v3/email/check/`에 의해 다시 반환되고, `GET /v3/session/{sessionId}/decision/`에 전달할 수 있습니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "Success",
              "Retry",
              "Undeliverable"
            ],
            "description": "`Success` — 새 인증에 OTP가 이메일로 전송되었습니다(요금 청구됨). `Retry` — 이전 전송으로 생성된 대기 중인 인증에 새 OTP가 이메일로 재전송되었습니다(무료). `Undeliverable` — 주소 전송 가능성 검증에 실패했거나 메시지를 보낼 수 없습니다. 인증은 즉시 `Declined` 상태로 완료 처리되며 요금은 청구되지 않습니다."
          },
          "reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "email_can_not_be_delivered",
              null
            ],
            "description": "`status`가 `Undeliverable`인 경우 `email_can_not_be_delivered`, 그 외의 경우 `null`."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "세션에 저장된 `vendor_data`의 에코 값입니다(첫 전송 기준)."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "description": "세션에 저장된 `metadata`의 에코 값입니다(첫 전송 기준)."
          }
        }
      },
      "EmailVerificationCheckResponse": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "`Approved`/`Declined`인 경우: 일치하는 인증의 세션 ID — `POST /v3/email/send/`에서 반환된 `request_id`와 동일합니다. `Failed` 및 `Expired or Not Found`인 경우: 나중에 조회할 수 없는 일회성 무작위 UUID입니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "Declined",
              "Failed",
              "Expired or Not Found"
            ],
            "description": "`Approved` — 올바른 코드이며 거부 위험이 없음. `Declined` — 최종 상태: 거부 위험이 일치했거나 시도 횟수 한도(3회)가 소진됨. `Failed` — 잘못된 코드이며 잔여 시도 횟수가 있음. `Expired or Not Found` — 지난 5분 동안 이 주소에 대한 보류 중인 인증이 없음."
          },
          "message": {
            "type": "string",
            "description": "잘못된 코드 입력 후 남은 시도 횟수를 포함한 결과에 대한 사람이 읽기 쉬운 설명입니다."
          },
          "email": {
            "type": "object",
            "nullable": true,
            "description": "전체 이메일 보고서입니다. 최종 완료된 결과(`Approved`/`Declined`)에만 존재(null이 아님)하며, `Failed`의 경우 `null`이고 `Expired or Not Found`의 경우 생략됩니다.",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "Approved",
                  "Declined",
                  "In Review",
                  "Not Finished",
                  "Expired"
                ],
                "description": "이메일 인증의 최종 상태입니다. 완료된 검사의 최상위 `status`와 일치합니다."
              },
              "email": {
                "type": "string",
                "format": "email",
                "description": "인증된 이메일 주소입니다.",
                "example": "alice@example.com"
              },
              "is_breached": {
                "type": "boolean",
                "description": "주소가 알려진 데이터 유출 사고에 나타난 경우 `true`입니다(완료 시점에 유출 인텔리전스 조회가 실행됨)."
              },
              "breaches": {
                "type": "array",
                "description": "이 주소를 포함하는 가장 최근의 알려진 침해 사례 최대 5건입니다. `is_breached`가 `false`이면 빈 배열이거나 생략됩니다.",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "침해 식별자입니다."
                    },
                    "domain": {
                      "type": "string",
                      "description": "침해된 서비스의 도메인입니다."
                    },
                    "breach_date": {
                      "type": "string",
                      "format": "date",
                      "description": "위반이 발생한 일자입니다."
                    },
                    "breach_emails_count": {
                      "type": "integer",
                      "description": "유출 사건에서 노출된 계정의 총 개수입니다."
                    },
                    "description": {
                      "type": "string",
                      "description": "침해에 대한 사람이 읽기 쉬운 설명입니다(HTML 마크업을 포함할 수 있음)."
                    },
                    "logo_path": {
                      "type": "string",
                      "description": "침해된 서비스 로고의 URL입니다."
                    },
                    "data_classes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "노출된 데이터의 카테고리(snake_case 형식, 예: `email_addresses`, `passwords`)."
                    },
                    "is_verified": {
                      "type": "boolean",
                      "description": "유출이 사실인 것으로 확인되었는지 여부입니다."
                    }
                  }
                }
              },
              "is_disposable": {
                "type": "boolean",
                "description": "도메인이 알려진 일회용/임시 이메일 제공업체에 속하는 경우 `true`입니다."
              },
              "is_undeliverable": {
                "type": "boolean",
                "description": "주소에서 메일을 수신할 수 없는 경우(구문 또는 DNS/MX 검증 실패, 또는 메시지 반송) `true`입니다."
              },
              "verification_attempts": {
                "type": "integer",
                "description": "이 인증에 대한 OTP 전송 횟수입니다(1회, 재시도 후에는 2회)."
              },
              "verified_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "올바른 코드가 입력된 시점입니다. 인증이 승인되지 않은 경우 `null`입니다."
              },
              "warnings": {
                "type": "array",
                "description": "인증 중 기록된 위험 경고(중복, 유출, 일회용, 전송 불가, 시도 횟수 초과, 차단 목록 등). 없을 경우 빈 배열입니다.",
                "items": {
                  "type": "object",
                  "properties": {
                    "feature": {
                      "type": "string",
                      "description": "경고를 생성한 기능입니다. 여기서는 항상 `EMAIL`입니다."
                    },
                    "risk": {
                      "type": "string",
                      "description": "기계 판독 가능한 위험 코드입니다."
                    },
                    "additional_data": {
                      "type": "object",
                      "nullable": true,
                      "description": "위험별 컨텍스트(예: 중복 위험의 경우 중복된 세션 ID). 위험에 추가 데이터가 없는 경우 `null`입니다."
                    },
                    "log_type": {
                      "type": "string",
                      "enum": [
                        "error",
                        "warning",
                        "information"
                      ],
                      "description": "심각도입니다. `error` 위험은 인증을 거부하고, `warning`은 검토 대상으로 표시하며, `information`은 상태에 영향을 주지 않고 기록됩니다."
                    },
                    "short_description": {
                      "type": "string",
                      "description": "사람이 읽을 수 있는 한 줄의 위험 요약입니다."
                    },
                    "long_description": {
                      "type": "string",
                      "description": "위험에 대한 사람이 읽기 쉬운 설명입니다."
                    }
                  }
                }
              },
              "lifecycle": {
                "type": "array",
                "description": "인증의 시간순 감사 로그입니다. 이벤트 `type`은 `EMAIL_VERIFICATION_MESSAGE_SENT`, `EMAIL_VERIFICATION_RETRY_MESSAGE_SENT`, `VALID_CODE_ENTERED`, `INVALID_CODE_ENTERED`, `EMAIL_VERIFICATION_APPROVED`, `EMAIL_VERIFICATION_DECLINED`, `EMAIL_VERIFICATION_IN_REVIEW`, `EMAIL_VERIFICATION_EXPIRED` 중 하나입니다.",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "description": "이벤트 유형입니다."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time",
                      "description": "이벤트가 발생한 시점입니다."
                    },
                    "details": {
                      "type": "object",
                      "nullable": true,
                      "description": "이벤트 관련 payload입니다. 발송 이벤트: `{status, reason}`. 코드 입력 이벤트: `{code_tried, status}`. 최종 상태 이벤트: `null`, 또는 거부됨/검토 중일 때 `{reason}`."
                    },
                    "fee": {
                      "type": "number",
                      "description": "이 이벤트에 대해 청구된 USD 금액입니다. 첫 번째 성공적인 발송에서만 0이 아니며, 재시도, 코드 입력 및 상태 이벤트에서는 0입니다."
                    }
                  }
                }
              },
              "matches": {
                "type": "array",
                "description": "다른 사용자(서로 다른 `vendor_data`)가 동일한 이메일 주소를 사용한 애플리케이션의 다른 세션(KYC, KYB 또는 API)입니다. 최대 5개 항목까지 표시되며, 가상 목록 항목 차단 목록 일치 항목이 있는 경우(세션 기반 차단 목록 이메일이 없는 경우에만) 맨 앞에 추가됩니다. 세션 기반 일치 항목은 created_at 순서를 유지합니다. 일치 항목이 없는 경우 빈 배열입니다.",
                "items": {
                  "type": "object",
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "이 이메일 주소를 사용한 다른 인증의 세션 id입니다."
                    },
                    "session_number": {
                      "type": "integer",
                      "description": "해당 세션의 사람이 읽기 쉬운 순차 번호입니다."
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "해당 세션의 `vendor_data`입니다."
                    },
                    "verification_date": {
                      "type": "string",
                      "description": "해당 세션이 생성된 시점(`YYYY-MM-DDTHH:MM:SSZ`)입니다."
                    },
                    "email": {
                      "type": "string",
                      "description": "일치하는 이메일 주소입니다."
                    },
                    "status": {
                      "type": "string",
                      "description": "해당 세션의 상태(예: `Approved`, `Declined`, `In Progress`)입니다."
                    },
                    "is_blocklisted": {
                      "type": "boolean",
                      "description": "이메일 주소가 애플리케이션의 차단 목록에 있는지 여부입니다."
                    },
                    "api_service": {
                      "type": "string",
                      "nullable": true,
                      "description": "API 유형 세션의 경우 이를 생성한 독립형 API(예: `PHONE_VERIFICATION`), 일반 인증 세션의 경우 `null`입니다."
                    },
                    "source": {
                      "type": "string",
                      "description": "일치 항목이 발견된 위치입니다. 일반적으로 `session`이며, 조직 목록 항목을 통한 차단 목록 일치는 `source: \"list_entry\"` 및 null `session_id`/`session_number`가 있는 합성 일치 항목을 앞에 추가합니다."
                    }
                  }
                }
              },
              "email_social": {
                "$ref": "#/components/schemas/EmailSocialFootprint"
              },
              "email_intelligence": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/EmailIntelligence"
                  }
                ],
                "description": "이메일 인텔리전스 신호입니다. 확인 시 `enable_enrichment`가 `true`인 경우에만 표시됩니다."
              }
            }
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "일치하는 인증 세션의 `vendor_data`입니다. `Expired or Not Found`인 경우 `null`입니다."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "description": "일치하는 인증 세션의 `metadata`입니다. `Expired or Not Found`인 경우 `null`입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "이 검사 응답의 타임스탬프입니다."
          }
        }
      },
      "WorkflowListItem": {
        "type": "object",
        "description": "목록 보기에 표시되는 워크플로 버전 1개입니다.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "버전별 UUID입니다. 조회/업데이트/삭제 시 `{settings_uuid}`로 사용하고, 세션 생성 시 `workflow_id`로 사용합니다."
          },
          "workflow_id": {
            "type": "string",
            "format": "uuid",
            "description": "동일한 워크플로의 모든 버전에서 공유되는 안정적인 그룹 ID입니다. 버전 1의 경우 `uuid`와 동일합니다."
          },
          "workflow_label": {
            "type": "string",
            "description": "워크플로의 표시 이름입니다."
          },
          "workflow_type": {
            "type": "string",
            "nullable": true,
            "description": "단순 워크플로의 기본 유형: `kyc`, `kyb`, `adaptive_age_verification`, `biometric_authentication` 등. KYB 기능이 없는 그래프 기반 워크플로의 경우 `null`입니다."
          },
          "is_default": {
            "type": "boolean",
            "description": "이 워크플로가 새 세션의 기본 워크플로인지 여부입니다."
          },
          "is_archived": {
            "type": "boolean"
          },
          "is_white_label_enabled": {
            "type": "boolean",
            "description": "이 워크플로로 생성된 세션에 화이트 라벨 맞춤 설정이 적용되는지 여부입니다."
          },
          "total_price": {
            "type": "number",
            "description": "인증 건당 고정 가격(USD 단위, JSON 숫자, DATABASE_VALIDATION 및 PHONE_VERIFICATION과 같이 변동 가격이 적용되는 기능 제외)."
          },
          "min_price": {
            "type": "number",
            "description": "워크플로 그래프 경로 전체에서 가장 저렴한 고정 가격(USD)입니다."
          },
          "max_price": {
            "type": "number",
            "description": "워크플로 그래프 경로 전체에서 가장 비싼 고정 가격(USD)."
          },
          "features": {
            "type": "string",
            "description": "활성화된 기능을 `\" + \"`로 연결한 단일 문자열입니다(예: `\"OCR + LIVENESS + FACE_MATCH\"`). 목록으로 가져오려면 `\" + \"` 기준으로 분할하세요."
          },
          "is_simple_workflow": {
            "type": "boolean",
            "description": "워크플로에 커스텀 워크플로 그래프가 없는 경우 true입니다."
          },
          "is_editable": {
            "type": "boolean",
            "description": "이 버전이 `draft`인 경우 true입니다(초안은 해당 위치에서 편집 가능하며, 게시된 버전은 Console에서 변경할 수 없음)."
          },
          "workflow_url": {
            "type": "string",
            "format": "uri",
            "description": "이 워크플로의 공개 공유 가능 인증 URL(`https://verify.didit.me/u/<token>`)입니다."
          },
          "max_retry_attempts": {
            "type": "integer",
            "description": "거부된 인증 후 허용되는 최대 재시도 횟수(0-10)."
          },
          "retry_window_days": {
            "type": "integer",
            "nullable": true,
            "description": "재시도 횟수를 계산하는 데 사용되는 롤링 윈도우 일수(1-365). `null` = 전체 기간 제한."
          },
          "session_expiration_time": {
            "type": "integer",
            "description": "완료되지 않은 세션이 만료되기까지 남은 시간(초)(3600-2419200)."
          },
          "version": {
            "type": "integer",
            "description": "`workflow_id` 그룹 내의 버전 번호로, 1부터 시작합니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ],
            "description": "버전 상태입니다. 새 세션은 그룹의 최신 `published` 버전을 사용합니다."
          },
          "has_draft": {
            "type": "boolean",
            "description": "이 `workflow_id` 그룹의 임의 버전이 현재 초안인 경우 true입니다."
          },
          "created_by": {
            "type": "object",
            "nullable": true,
            "description": "이 버전을 생성한 주체: `{name, email, type}` 형식이며 여기서 `type`은 `user`(콘솔 사용자, `email` 설정됨) 또는 `api_key`(`name`은 클라이언트 ID, `email`은 null)입니다. 생성자가 기록되지 않은 경우 `null`입니다.",
            "properties": {
              "name": {
                "type": "string"
              },
              "email": {
                "type": "string",
                "nullable": true
              },
              "type": {
                "type": "string",
                "enum": [
                  "user",
                  "api_key"
                ]
              }
            }
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SimpleWorkflowRequest": {
        "type": "object",
        "description": "단순한 선형 워크플로를 생성합니다. API는 이 기능 목록을 내부적으로 노드 기반 워크플로 그래프로 변환합니다. 엄격한 필드 허용 목록: 여기에 나열되지 않은 모든 키(`workflow_type` 포함)는 400으로 거부됩니다.",
        "required": [
          "features"
        ],
        "properties": {
          "workflow_label": {
            "type": "string",
            "maxLength": 50,
            "default": "ID Verification",
            "description": "워크플로의 표시 이름(최대 50자)입니다. 생략 시 기본값은 `\"ID Verification\"`입니다 — 워크플로를 구분할 수 있도록 항상 설정하세요.",
            "example": "Standard KYC"
          },
          "is_default": {
            "type": "boolean",
            "description": "이 워크플로를 새 세션의 기본값으로 설정합니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ],
            "description": "세션에 바로 사용할 수 있도록 게시된 워크플로를 생성하려면 이 필드를 생략하세요. 게시하지 않고 저장하려는 경우에만 `draft`를 사용하세요."
          },
          "features": {
            "type": "array",
            "minItems": 1,
            "description": "실행 순서에 따른 인증 기능입니다. API는 각 항목을 다음 항목에 연결하고 마지막 상태 노드 하나를 자동으로 추가합니다.",
            "items": {
              "$ref": "#/components/schemas/SimpleWorkflowFeature"
            }
          },
          "is_white_label_enabled": {
            "type": "boolean",
            "description": "이 워크플로로 생성된 세션에 화이트 라벨 맞춤 설정을 활성화합니다.",
            "default": false
          },
          "is_desktop_allowed": {
            "type": "boolean",
            "description": "데스크톱 브라우저에서 인증 워크플로가 실행되도록 허용합니다.",
            "default": false
          },
          "max_retry_attempts": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10,
            "default": 3,
            "description": "거부된 인증 후 허용되는 최대 재시도 횟수입니다. `0`은 첫 번째 거부 후 사용자를 차단합니다."
          },
          "retry_window_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "nullable": true,
            "default": 7,
            "description": "재시도 횟수를 계산하는 데 사용되는 롤링 윈도우 일수. `null`은 전체 기간 제한을 적용합니다."
          },
          "face_liveness_max_attempts": {
            "type": "integer",
            "minimum": 1,
            "maximum": 3,
            "default": 3,
            "description": "세션당 최대 라이브니스 제출 횟수입니다. 기본값은 3(초기 시도 1회 + 재시도 2회)입니다. 기능 수준 구성에서 이를 재정의하지 않는 한, 이 값은 생성된 라이브니스 및 연령 추정 워크플로 노드에도 복사됩니다."
          },
          "face_match_max_attempts": {
            "type": "integer",
            "minimum": 1,
            "maximum": 3,
            "default": 3,
            "description": "세션당 최대 얼굴 대조 제출 횟수입니다. 기본값은 3(초기 시도 1회 + 재시도 2회)입니다. 기능 수준 구성에서 이를 재정의하지 않는 한, 이 값은 생성된 얼굴 대조 워크플로 노드에도 복사됩니다."
          },
          "session_expiration_time": {
            "type": "integer",
            "minimum": 3600,
            "maximum": 2419200,
            "default": 604800,
            "description": "완료되지 않은 세션이 만료되기까지 남은 시간(초)입니다. 최소 1시간(3600), 최대 4주(2419200)."
          }
        }
      },
      "SimpleWorkflowUpdateRequest": {
        "type": "object",
        "description": "워크플로 메타데이터를 업데이트하거나 전체 선형 기능 목록을 대체합니다. 엄격한 필드 화이트리스트가 적용됩니다. 여기에 나열되지 않은 키는 400 오류와 함께 거부됩니다.",
        "properties": {
          "workflow_label": {
            "type": "string",
            "maxLength": 50,
            "description": "워크플로의 표시 이름(최대 50자)입니다."
          },
          "is_default": {
            "type": "boolean",
            "description": "이 워크플로를 새 세션의 기본값으로 설정합니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ],
            "description": "버전 관리를 제어합니다. 현재 버전을 즉시 업데이트하려면 생략하십시오(초안은 자동 게시됨). 이미 게시된 버전에 대해 `published`를 지정하면 새 버전을 생성하여 반환합니다. `draft`는 해당 버전이 아직 초안 상태일 때만 유효합니다."
          },
          "features": {
            "type": "array",
            "minItems": 1,
            "description": "제공된 경우 전체 기능 순서 및 구성을 대체합니다.",
            "items": {
              "$ref": "#/components/schemas/SimpleWorkflowFeature"
            }
          },
          "is_white_label_enabled": {
            "type": "boolean",
            "description": "이 워크플로로 생성된 세션에 화이트 라벨 맞춤 설정을 활성화합니다."
          },
          "is_desktop_allowed": {
            "type": "boolean",
            "description": "데스크톱 브라우저에서 인증 워크플로가 실행되도록 허용합니다."
          },
          "max_retry_attempts": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10,
            "description": "거부된 인증 후 허용되는 최대 재시도 횟수입니다. `0`은 첫 번째 거부 후 사용자를 차단합니다."
          },
          "retry_window_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "nullable": true,
            "description": "재시도 횟수를 계산하는 데 사용되는 롤링 윈도우 일수. `null`은 전체 기간 제한을 적용합니다."
          },
          "face_liveness_max_attempts": {
            "type": "integer",
            "minimum": 1,
            "maximum": 3,
            "description": "세션당 최대 라이브니스 제출 횟수입니다. 기능 수준 구성에서 이를 재정의하지 않는 한, 이 값은 생성된 라이브니스 및 연령 추정 워크플로 노드에도 복사됩니다."
          },
          "face_match_max_attempts": {
            "type": "integer",
            "minimum": 1,
            "maximum": 3,
            "description": "세션당 최대 얼굴 대조 제출 횟수입니다. 기능 수준 구성에서 이를 재정의하지 않는 한, 이 값은 생성된 얼굴 대조 워크플로 노드에도 복사됩니다."
          },
          "session_expiration_time": {
            "type": "integer",
            "minimum": 3600,
            "maximum": 2419200,
            "description": "완료되지 않은 세션이 만료되기까지 남은 시간(초)입니다. 최소 1시간(3600), 최대 4주(2419200)."
          }
        }
      },
      "SimpleWorkflowFeature": {
        "type": "object",
        "required": [
          "feature"
        ],
        "properties": {
          "feature": {
            "type": "string",
            "description": "실행할 기능입니다. 여기에 표시된 대문자 값을 사용하십시오.",
            "enum": [
              "OCR",
              "NFC",
              "LIVENESS",
              "FACE_MATCH",
              "PROOF_OF_ADDRESS",
              "QUESTIONNAIRE",
              "DOCUMENT_AI",
              "PHONE_VERIFICATION",
              "EMAIL_VERIFICATION",
              "DATABASE_VALIDATION",
              "AML",
              "IP_ANALYSIS",
              "AGE_ESTIMATION",
              "KYB_REGISTRY",
              "KYB_DOCUMENTS",
              "KYB_KEY_PEOPLE",
              "SIGNATURE"
            ]
          },
          "config": {
            "type": "object",
            "description": "기능별 설정입니다. `QUESTIONNAIRE`의 경우 설문지 생성 endpoint에서 반환된 `questionnaire_id`와 함께 `questionnaire_uuid`를 포함합니다. `SIGNATURE`의 경우 라이브로 전환되는 워크플로에 서명할 문서가 필요합니다. 각 세션이 자체 문서를 가져올 수 있도록 `signature_documents_source`를 `session` 또는 `both`로 설정하거나, `status: \"draft\"`를 전송하고 게시하기 전에 문서를 추가하세요. 워크플로에서 `signature_availability.aes`가 `false`인 동안에는 `signature_level: \"aes\"`가 `aes_not_available` 오류와 함께 거부됩니다. `OCR`의 경우 `methods`는 각 국가에서 사용할 수 있는 신분증 인증 방법을 선택합니다(문서 촬영, 정부 또는 기타 공신력 있는 출처를 통한 비문서 조회, 디지털 신원 지갑). 생략할 경우 모든 국가는 문서 촬영 전용이 됩니다. `SIGNATURE`의 경우 [전자 서명 설정](/ko/management-api/workflows/feature-configs#전자-서명)을 참조하세요. 현재 `signature_level`은 `simple`(기본값, 신분증 인증, 이메일 또는 전화번호 불필요) 및 `aes`를 허용하며, 워크플로 문서 및 해당 필드는 콘솔에서 관리되므로 API를 통해 세션당 문서 및 필드를 `signature_documents_source: \"session\"`으로 전송하세요.",
            "additionalProperties": true
          },
          "label": {
            "type": "string",
            "description": "이 워크플로 노드에 대한 선택적 내부 라벨입니다."
          }
        }
      },
      "ReviewItem": {
        "type": "object",
        "description": "세션의 검토/활동 피드 항목 1개입니다. 상태 변경에는 `previous_status`, `new_status`, `previous_value`, `new_value`, `changed_fields`가 포함되고, 댓글에는 `comment` 및 (Console 댓글의 경우) `mentioned_emails`가 포함되며, 나머지 필드는 해당 활동 유형에 적용되지 않는 경우 `null`이거나 비어 있습니다.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "이 피드 항목의 고유 식별자입니다.",
            "example": "de0561bc-5583-4409-9171-1a31a4c8a5f4"
          },
          "activity_type": {
            "type": "string",
            "enum": [
              "COMMENT",
              "STATUS_UPDATED",
              "KYC_DATA_UPDATED",
              "POA_DATA_UPDATED",
              "FILE_ADDED",
              "FILE_REMOVED",
              "AML_ONGOING_MATCH",
              "AML_STATUS_UPDATED",
              "AML_HIT_STATUS_UPDATED",
              "KYB_DATA_UPDATED",
              "KYB_DOCUMENT_UPLOADED",
              "TAG_ADDED",
              "TAG_REMOVED",
              "FEATURE_OVERRIDE_PENDING",
              "FEATURE_OVERRIDE_APPLIED",
              "FEATURE_OVERRIDE_CANCELLED"
            ],
            "description": "이 항목이 기록하는 활동의 종류입니다. `STATUS_UPDATED` 행은 수동 결정(`PATCH /v3/session/{session_id}/update-status/`) 및 `POST …/reviews/`를 통해 추가된 항목(상태가 기록되지 않은 경우에도 기본적으로 이 유형이 됨)에서 생성됩니다. `COMMENT` 행은 Console 검토자로부터 생성되며, Console 상세 페이지 조회 또한 `metadata.system_event = \"DETAIL_VIEWED\"`로 표시된 `COMMENT` 행으로 저장됩니다. 나머지 유형은 데이터 수정, 파일 변경, 태그 및 AML 모니터링 활동을 추적합니다. STATUS_UPDATED 행은 update-status endpoint 및 수동 검토 게시물뿐만 아니라 시스템 주체(예: actor_type이 SYSTEM인 지속적인 AML 모니터링 및 자동 기능 상태 업데이트)에 의해서도 작성됩니다. `FEATURE_OVERRIDE_PENDING`, `FEATURE_OVERRIDE_APPLIED` 및 `FEATURE_OVERRIDE_CANCELLED`는 하나의 검사 상태에 대한 재정의(`PATCH /v3/session/{session_id}/features/{node_id}/update-status/`)를 기록합니다(워크플로가 완료될 때까지 대기하도록 요청됨, 적용됨 또는 취소됨). 이들은 검사의 상태를 `previous_value` / `new_value`(`{\"status\": ...}`)에 담고, `previous_status` 및 `new_status`는 `null`로 두며, `metadata`(`feature_override_id`, `node_id`, `feature_model`, `forced`, `state`, `cancel_reason`)에 재정의 정보를 명시합니다. 요청 항목에는 검토자의 `comment`가 포함되며, 워크플로 완료 시 적용된 재정의는 `SYSTEM`인 `actor_type`으로 기록됩니다.",
            "example": "STATUS_UPDATED"
          },
          "actor_display": {
            "type": "string",
            "description": "사람이 읽기 쉬운 작성자 라벨로, 작업자의 성명 → 콘솔 계정 식별자 → `actor_email`의 로컬 파트 → `\"API Client\"`(`API_KEY` 작업자의 경우) → `\"System\"`(`SYSTEM` 작업자의 경우) → `\"Unknown\"` 순으로 확인됩니다. `POST …/reviews/`를 통해 생성된 항목은 해당 endpoint가 작업자 귀속 정보를 기록하지 않으므로 항상 `\"Unknown\"`으로 표시됩니다.",
            "example": "API Client"
          },
          "actor_email": {
            "type": "string",
            "nullable": true,
            "description": "작업을 수행한 Console 사용자의 이메일입니다. API 키 및 시스템 행위자의 경우 `null`입니다.",
            "example": null
          },
          "actor_type": {
            "type": "string",
            "enum": [
              "API_KEY",
              "CONSOLE_USER",
              "SYSTEM"
            ],
            "description": "작업을 수행한 주체: API 키, 콘솔 사용자 또는 Didit 자체(`SYSTEM`, 예: 지속적인 AML 모니터링)입니다. `POST …/reviews/`를 통해 생성된 항목은 호출자와 관계없이 기본값 `CONSOLE_USER`를 갖습니다.",
            "example": "API_KEY"
          },
          "new_status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User"
            ],
            "description": "이 항목에 기록된 세션 상태입니다(상태 업데이트의 경우). 댓글 및 데이터 변경 항목의 경우 `null`입니다.",
            "example": "Approved"
          },
          "previous_status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User"
            ],
            "description": "변경 전 세션의 상태입니다. 상태 업데이트 endpoint가 작성한 `STATUS_UPDATED` 항목에 채워지며, `POST …/reviews/`를 통해 추가된 항목에서는 `null`입니다. 시스템이 작성한 STATUS_UPDATED 행에도 채워집니다.",
            "example": "In Review"
          },
          "comment": {
            "type": "string",
            "nullable": true,
            "description": "항목에 첨부된 자유 형식 메모 또는 `null`입니다.",
            "example": "Document re-checked manually; address matches."
          },
          "mentioned_emails": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            },
            "description": "댓글에서 `@email`로 언급된 콘솔 사용자입니다. 멘션 처리는 콘솔 전용 기능이므로 이 API를 통해 생성된 항목의 경우 항상 비어 있습니다.",
            "example": []
          },
          "previous_value": {
            "type": "object",
            "nullable": true,
            "description": "상태 변경 등 작업 전 변경 대상 데이터의 스냅샷입니다(예: `{\"status\": \"In Review\"}`). 변경된 사항이 없으면 `null`입니다.",
            "example": {
              "status": "In Review"
            }
          },
          "new_value": {
            "type": "object",
            "nullable": true,
            "description": "작업 후 변경된 데이터의 스냅샷입니다(예: `{\"status\": \"Approved\"}`). 변경된 사항이 없으면 `null`입니다.",
            "example": {
              "status": "Approved"
            }
          },
          "changed_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "이 활동에 의해 수정된 필드의 이름입니다(예: `[\"status\"]`). 댓글 및 `POST …/reviews/`를 통해 추가된 항목의 경우 비어 있습니다.",
            "example": [
              "status"
            ]
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "description": "시스템 생성 항목에 대한 추가 컨텍스트입니다. 콘솔 상세 페이지 조회는 알림 로직에서 제외할 수 있도록 `{\"system_event\": \"DETAIL_VIEWED\", \"detail_type\": \"verification\"}`을 전달합니다. 작성자가 콘솔에서 수정한 `COMMENT`는 마지막 수정 시점을 나타내는 ISO 8601 형식의 `edited_at`을 전달합니다(`comment` 및 `mentioned_emails`에는 수정된 텍스트와 멘션된 대상이 포함됩니다). 일반 항목의 경우 `null`입니다.",
            "example": null
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "항목이 작성된 시점(ISO 8601 UTC)입니다.",
            "example": "2026-06-12T00:19:31.918735Z"
          }
        }
      },
      "QuestionnaireListItem": {
        "type": "object",
        "description": "목록 보기에 표시되는 설문지 버전 하나입니다.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "버전별 UUID입니다. 조회/업데이트/삭제 시 `{questionnaire_uuid}`로 사용하고, 워크플로의 QUESTIONNAIRE 기능 구성에서 `questionnaire_uuid`로 사용합니다."
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "default_language": {
            "type": "string"
          },
          "is_active": {
            "type": "boolean"
          },
          "is_simple_questionnaire": {
            "type": "boolean",
            "description": "이 API를 통해 생성된 선형 설문지인 경우 true이고, 콘솔에서 빌드된 그래프 기반 설문지인 경우 false입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "question_types": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "답변 가능한 질문의 대문자 요소 유형(생성 순서, 예: `SHORT_TEXT`, `MULTIPLE_CHOICE`, `FILE_UPLOAD`)입니다. 구조 요소인 `SECTION_HEADER` 및 `SEPARATOR`는 제외됩니다. 질문당 하나의 항목이므로 값이 중복될 수 있습니다."
          },
          "workflow_names": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "이 설문지를 사용하는 워크플로의 이름입니다. 현재 이 endpoint에서는 항상 `[]`입니다(Console 목록에만 채워짐)."
          },
          "questionnaire_group_id": {
            "type": "string",
            "format": "uuid",
            "description": "동일한 설문지의 모든 버전을 그룹화하는 고정 식별자입니다."
          },
          "version": {
            "type": "integer",
            "description": "그룹 내의 버전 번호로, 1부터 시작합니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ]
          },
          "published_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "이 버전이 게시된 시점입니다. 초안의 경우 `null`입니다."
          },
          "is_editable": {
            "type": "boolean",
            "description": "이 버전이 `draft`인 경우 true입니다."
          }
        }
      },
      "SimpleQuestionnaireRequest": {
        "type": "object",
        "description": "단순한 선형 설문지를 생성합니다. API는 `form_elements`를 내부 설문지 그래프로 변환합니다.",
        "required": [
          "title",
          "languages",
          "form_elements"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "설문지의 내부 이름입니다."
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "languages": {
            "type": "array",
            "description": "모든 라벨에 포함된 언어입니다. `en`이 반드시 포함되어야 합니다.",
            "items": {
              "type": "string"
            },
            "example": [
              "en"
            ]
          },
          "default_language": {
            "type": "string",
            "description": "기본 언어입니다. `languages`에 포함되어 있어야 합니다.",
            "example": "en"
          },
          "is_active": {
            "type": "boolean",
            "default": true
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ],
            "description": "워크플로에 사용할 수 있는 게시된 설문지를 생성하려면 이 필드를 생략하세요."
          },
          "form_elements": {
            "type": "array",
            "minItems": 1,
            "description": "사용자에게 표시되어야 하는 정확한 순서의 질문 목록입니다. 분기 및 조건부 필드는 지원되지 않습니다.",
            "items": {
              "$ref": "#/components/schemas/SimpleQuestionnaireElement"
            }
          }
        }
      },
      "SimpleQuestionnaireUpdateRequest": {
        "type": "object",
        "description": "설문지 메타데이터를 업데이트하거나 전체 선형 `form_elements` 목록을 대체합니다.",
        "properties": {
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "default_language": {
            "type": "string"
          },
          "is_active": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ]
          },
          "form_elements": {
            "type": "array",
            "minItems": 1,
            "description": "제공된 경우 전체 선형 질문 목록을 대체합니다.",
            "items": {
              "$ref": "#/components/schemas/SimpleQuestionnaireElement"
            }
          }
        }
      },
      "SimpleQuestionnaireElement": {
        "type": "object",
        "required": [
          "element_type",
          "label"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "선택 사항인 안정적인 질문 ID입니다. 생략하면 API가 `q1`, `q2` 등을 생성합니다. 가독성을 위해 소문자, 숫자, 밑줄을 사용하세요.",
            "example": "source_of_funds"
          },
          "element_type": {
            "type": "string",
            "description": "질문 유형입니다. API는 이러한 소문자 값 및 이에 해당하는 대문자 값을 허용합니다.",
            "enum": [
              "short_text",
              "long_text",
              "dropdown",
              "single_choice",
              "multiple_choice",
              "number",
              "image",
              "file_upload",
              "time",
              "email",
              "address",
              "phone",
              "country",
              "date_picker",
              "consent",
              "section_header",
              "separator",
              "heading",
              "paragraph"
            ]
          },
          "label": {
            "type": "object",
            "description": "언어 코드별 질문 라벨(예: `{ \"en\": \"Source of funds\" }`).",
            "additionalProperties": {
              "type": "string"
            }
          },
          "description": {
            "type": "object",
            "nullable": true,
            "additionalProperties": {
              "type": "string"
            }
          },
          "placeholder": {
            "type": "object",
            "nullable": true,
            "additionalProperties": {
              "type": "string"
            }
          },
          "is_required": {
            "type": "boolean",
            "default": false
          },
          "options": {
            "type": "array",
            "description": "`dropdown`, `single_choice`, `multiple_choice`에 사용합니다. `value`를 생략하면 API가 옵션 레이블을 기반으로 값을 생성합니다.",
            "items": {
              "type": "object",
              "required": [
                "label"
              ],
              "properties": {
                "value": {
                  "type": "string"
                },
                "label": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "max_files": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5,
            "description": "`file_upload` 또는 `image`와 함께 사용합니다."
          },
          "validation": {
            "type": "object",
            "nullable": true,
            "description": "`short_text`, `long_text` 또는 `number`에 대한 선택적 형식 유효성 검사입니다. 사용자가 필드를 채우는 동안 적용되며(통과할 때까지 계속 진행할 수 없음), 제출 시 API를 통해 다시 확인됩니다.",
            "properties": {
              "pattern": {
                "type": "string",
                "description": "값이 완전히 일치해야 하는 정규식(ECMA-262 하위 집합)입니다. `short_text` 및 `long_text`용입니다. ^/$ 앵커를 추가하지 마십시오. 전체 값과 일치합니다."
              },
              "min_length": {
                "type": "integer",
                "minimum": 0,
                "description": "최소 글자 수입니다. `short_text` 및 `long_text`에 사용됩니다."
              },
              "max_length": {
                "type": "integer",
                "minimum": 0,
                "description": "최대 문자 수입니다. `short_text` 및 `long_text`에 사용됩니다."
              },
              "min": {
                "type": "number",
                "description": "최소 숫자 값입니다. `number`에 사용됩니다."
              },
              "max": {
                "type": "number",
                "description": "최대 숫자 값입니다. `number`에 사용됩니다."
              },
              "error_message": {
                "type": "object",
                "description": "검증 실패 시 표시되는 번역된 메시지이며, 언어 코드로 키가 지정됩니다.",
                "additionalProperties": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "QuestionnaireDetail": {
        "type": "object",
        "description": "GET, POST(생성) 및 PATCH(업데이트) endpoint에서 반환되는 설문지 전체 세부정보입니다.",
        "properties": {
          "questionnaire_id": {
            "type": "string",
            "format": "uuid",
            "description": "설문지의 고유 식별자입니다. 워크플로에서 설문지를 참조하거나 이후 업데이트/삭제 요청 시 이 id를 사용합니다."
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "default_language": {
            "type": "string"
          },
          "is_active": {
            "type": "boolean"
          },
          "is_simple_questionnaire": {
            "type": "boolean"
          },
          "graph": {
            "type": "object",
            "description": "start_node 및 노드 맵이 포함된 그래프 구조입니다."
          },
          "sections": {
            "type": "array",
            "description": "섹션별로 그룹화된 설문지 내용(그래프에서 파생됨).",
            "items": {
              "type": "object"
            }
          },
          "questionnaire_group_id": {
            "type": "string",
            "format": "uuid",
            "description": "동일한 설문지의 모든 버전을 그룹화하는 고정 식별자입니다."
          },
          "version": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ]
          },
          "published_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "is_editable": {
            "type": "boolean",
            "description": "설문지를 직접 계속 편집할 수 있는 경우 true입니다(초안 버전)."
          }
        }
      },
      "UserListItem": {
        "type": "object",
        "description": "인증된 사용자입니다.",
        "properties": {
          "didit_internal_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 사용자에 대한 Didit의 고유 내부 UUID입니다."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "귀하가 지정한 해당 사용자의 고유 식별자입니다(세션 생성 시 전달됨). 벤더 식별자가 제공되지 않은 경우 null일 수 있습니다."
          },
          "display_name": {
            "type": "string",
            "nullable": true,
            "description": "직접 설정한 커스텀 표시 이름"
          },
          "full_name": {
            "type": "string",
            "nullable": true,
            "description": "인증된 문서에서 추출된 성명"
          },
          "date_of_birth": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "effective_name": {
            "type": "string",
            "nullable": true,
            "description": "사용 가능한 최적의 이름: display_name이 설정된 경우 해당 값, 그렇지 않으면 full_name"
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "FLAGGED",
              "BLOCKED"
            ],
            "description": "사용자 레코드의 수명 주기 상태입니다(세션 상태가 아님). 기본값은 `ACTIVE`이며, `FLAGGED`는 사용자를 수동 확인 필요로 표시하고, `BLOCKED`는 해당 `vendor_data`에 대한 새 세션을 방지합니다."
          },
          "portrait_image_url": {
            "type": "string",
            "nullable": true,
            "description": "사용자의 사전 서명된 인물 사진 URL(몇 시간 후 만료됨)"
          },
          "session_count": {
            "type": "integer",
            "description": "해당 사용자의 총 인증 세션 수"
          },
          "approved_count": {
            "type": "integer",
            "description": "승인된 세션 수"
          },
          "declined_count": {
            "type": "integer",
            "description": "거부된 세션 수"
          },
          "in_review_count": {
            "type": "integer",
            "description": "검토 중인 세션 수"
          },
          "issuing_states": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "이 사용자의 승인된 신분증 문서에서 확인된 발급 국가의 ISO 3166-1 alpha-3 코드 목록입니다(예: `[\"USA\", \"ESP\"]`). 없는 경우 빈 배열입니다."
          },
          "approved_emails": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "이 사용자의 승인된 세션에서 수집된 인증된 이메일 주소입니다(예: `[\"john@example.com\"]`)."
          },
          "approved_phones": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "이 사용자의 승인된 세션에서 수집된 인증된 전화번호입니다(예: `[\"+14155551234\"]`)."
          },
          "features": {
            "type": "object",
            "description": "이 사용자의 모든 세션에 걸쳐 집계된 기능별 상태입니다. 가능한 키: `ID_VERIFICATION`, `NFC`, `LIVENESS`, `FACE_MATCH`, `POA`, `QUESTIONNAIRE`, `EMAIL_VERIFICATION`, `PHONE`, `AML`, `IP_ANALYSIS`, `AGE_ESTIMATION`, `DATABASE_VALIDATION`. 가능한 값: `Approved`, `Declined`, `In Review`, `Not Finished`, `Resub Requested`."
          },
          "features_list": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "feature": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                }
              }
            },
            "description": "`features`와 동일한 데이터로, `{feature, status}` 객체의 정렬된 배열입니다."
          },
          "last_session_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "가장 최근 세션의 타임스탬프"
          },
          "first_session_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "첫 번째 세션의 타임스탬프"
          },
          "last_activity_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "이 사용자에 대한 가장 최근 활동(세션, 거래, 상태 변경, 데이터 편집 등)의 타임스탬프입니다."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": "string"
                }
              }
            },
            "description": "이 사용자에게 할당된 태그"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BlocklistItem": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "face",
              "document",
              "phone",
              "email"
            ]
          },
          "session_id": {
            "type": "string",
            "format": "uuid"
          },
          "session_number": {
            "type": "integer"
          },
          "blocklisted_at": {
            "type": "string",
            "format": "date-time"
          },
          "face_image": {
            "type": "string",
            "nullable": true
          },
          "document_type": {
            "type": "string",
            "nullable": true
          },
          "document_number": {
            "type": "string",
            "nullable": true
          },
          "phone_number": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "UserDetailItem": {
        "type": "object",
        "description": "전체 사용자 세부정보입니다. UserListItem을 메타데이터, 댓글 및 updated_at으로 확장합니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/UserListItem"
          },
          {
            "type": "object",
            "properties": {
              "metadata": {
                "type": "object",
                "description": "이 사용자에 첨부한 커스텀 메타데이터 JSON입니다. 기본값은 `{}`입니다."
              },
              "tags": {
                "type": "array",
                "description": "태그 할당입니다. 참고: 목록 응답에 사용되는 플랫한 `{uuid, name, color}` 형태와 달리, 상세 응답의 각 항목은 태그 *링크* 객체(`{uuid, tag: {...}, added_by_email, added_by_name, created_at}`)입니다.",
                "items": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "태그 할당의 UUID입니다(태그 자체의 UUID가 아님)."
                    },
                    "tag": {
                      "type": "object",
                      "properties": {
                        "uuid": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string"
                        },
                        "color": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "source": {
                          "type": "string",
                          "enum": [
                            "didit",
                            "custom"
                          ]
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    },
                    "added_by_email": {
                      "type": "string",
                      "nullable": true
                    },
                    "added_by_name": {
                      "type": "string",
                      "nullable": true
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              },
              "comments": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "comment_type": {
                      "type": "string",
                      "enum": [
                        "COMMENT",
                        "STATUS_CHANGED",
                        "METADATA_UPDATED",
                        "TAG_ADDED",
                        "TAG_REMOVED",
                        "PROFILE_UPDATED"
                      ]
                    },
                    "comment": {
                      "type": "string",
                      "nullable": true
                    },
                    "actor_email": {
                      "type": "string",
                      "nullable": true
                    },
                    "actor_name": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous_status": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "ACTIVE",
                        "FLAGGED",
                        "BLOCKED",
                        null
                      ]
                    },
                    "new_status": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "ACTIVE",
                        "FLAGGED",
                        "BLOCKED",
                        null
                      ]
                    },
                    "previous_value": {
                      "type": "object",
                      "nullable": true,
                      "description": "PROFILE_UPDATED 항목의 이전 필드 값입니다."
                    },
                    "new_value": {
                      "type": "object",
                      "nullable": true,
                      "description": "PROFILE_UPDATED 항목의 새 필드 값입니다."
                    },
                    "changed_fields": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "PROFILE_UPDATED 항목에 의해 변경된 필드의 이름입니다."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true
                    },
                    "mentioned_emails": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "description": "이 사용자의 활동 로그 및 댓글입니다(상태 변경, 프로필 수정, 수동 메모)."
              },
              "updated_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          }
        ]
      },
      "BusinessListItem": {
        "type": "object",
        "description": "인증된 기업입니다.",
        "properties": {
          "didit_internal_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 기업에 대한 Didit의 고유 내부 UUID입니다."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "귀하가 지정한 해당 기업의 고유 식별자입니다(세션 생성 시 전달됨). 벤더 식별자가 제공되지 않은 경우 null일 수 있습니다."
          },
          "display_name": {
            "type": "string",
            "nullable": true,
            "description": "직접 설정한 커스텀 표시 이름"
          },
          "legal_name": {
            "type": "string",
            "nullable": true,
            "description": "등기부 또는 직접 입력에서 가져온 공식 법인명"
          },
          "registration_number": {
            "type": "string",
            "nullable": true,
            "description": "기업 등록번호 또는 법인 설립 번호"
          },
          "country_code": {
            "type": "string",
            "nullable": true,
            "description": "설립 국가(ISO 3166-1 alpha-2, 예: `GB`, `US`)."
          },
          "effective_name": {
            "type": "string",
            "nullable": true,
            "description": "사용 가능한 최적의 이름: display_name이 설정된 경우 해당 값, 그렇지 않으면 legal_name"
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "FLAGGED",
              "BLOCKED"
            ],
            "description": "기업 레코드의 수명 주기 상태입니다(세션 상태가 아님). 기본값은 `ACTIVE`이며, `FLAGGED`는 수동 확인 필요로 표시하고, `BLOCKED`는 해당 `vendor_data`에 대한 새 세션을 방지합니다."
          },
          "session_count": {
            "type": "integer",
            "description": "해당 기업의 총 인증 세션 수"
          },
          "approved_count": {
            "type": "integer",
            "description": "승인된 세션 수"
          },
          "declined_count": {
            "type": "integer",
            "description": "거부된 세션 수"
          },
          "in_review_count": {
            "type": "integer",
            "description": "검토 중인 세션 수"
          },
          "features": {
            "type": "object",
            "description": "이 기업의 모든 KYB 세션에 걸쳐 집계된 기능별 상태입니다. 현재 유일한 키는 `KYB`(법인 등기부 기업 확인 상태)입니다. 가능한 값: `Approved`, `Declined`, `In Review`, `Not Finished`, `Resub Requested`."
          },
          "features_list": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "feature": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                }
              }
            },
            "description": "`features`와 동일한 데이터로, `{feature, status}` 객체의 정렬된 배열입니다."
          },
          "last_session_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "가장 최근 세션의 타임스탬프"
          },
          "first_session_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "첫 번째 세션의 타임스탬프"
          },
          "last_activity_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "가장 최근 활동(상태 변경, 세션 업데이트 등)의 타임스탬프"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": "string"
                }
              }
            },
            "description": "이 기업에 할당된 태그"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BusinessDetailItem": {
        "type": "object",
        "description": "전체 기업 상세 정보입니다. 메타데이터 및 updated_at으로 BusinessListItem을 확장합니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/BusinessListItem"
          },
          {
            "type": "object",
            "properties": {
              "metadata": {
                "type": "object",
                "description": "이 기업에 첨부한 커스텀 메타데이터 JSON입니다. 기본값은 `{}`입니다."
              },
              "updated_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          }
        ]
      },
      "TransactionDetail": {
        "type": "object",
        "description": "`GET /v3/transactions/{transaction_id}/` 및 `POST /v3/transactions/`에서 반환되는 단일 거래에 대한 전체 모니터링 기록입니다.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Didit 고유 거래 식별자입니다. 후속 호출 시 `{transaction_id}`로 사용합니다."
          },
          "environment": {
            "type": "string",
            "enum": [
              "live",
              "sandbox"
            ],
            "description": "거래를 소유한 애플리케이션의 환경. `sandbox` 거래는 저장되지만 평가, 스크리닝, 알림 또는 결제가 이루어지지 않으므로, 비어 있는 `rule_runs`는 \"평가되지 않음\"을 의미합니다."
          },
          "transaction_number": {
            "type": "integer",
            "description": "Console에 표시되는 애플리케이션별 순차 거래 번호(예: `4123`)입니다."
          },
          "txn_id": {
            "type": "string",
            "description": "생성 시 제공한 `transaction_id`입니다(최대 128자). 애플리케이션별로 고유합니다."
          },
          "txn_date": {
            "type": "string",
            "format": "date-time",
            "description": "거래가 발생한 시점입니다(`transaction_at` 기준, 기본값은 제출 시간)."
          },
          "zone_id": {
            "type": "string",
            "nullable": true,
            "description": "생성 시 제공된 IANA 표준 시간대 식별자입니다."
          },
          "transaction_type": {
            "type": "string",
            "description": "저장된 최상위 카테고리: `finance`, `kyc`, `travelRule`, `userPlatformEvent`, `gamblingBet`, `gamblingLimitChange`, `gamblingBonusChange`, `auditTrailEvent`. 여러 단어로 된 값은 snake_case로 제출하더라도 camelCase로 반환됩니다."
          },
          "action_type": {
            "type": "string",
            "description": "카테고리 내 하위 유형입니다(예: `deposit`, `withdrawal`, `transfer`). 제공되지 않은 경우 카테고리로 기본 설정됩니다."
          },
          "direction": {
            "type": "string",
            "enum": [
              "INBOUND",
              "OUTBOUND"
            ],
            "description": "주체 기준의 방향입니다. 제출된 대소문자에 관계없이 대문자로 저장됩니다(입력 시 `in`/`out`/`inbound`/`outbound` 허용)."
          },
          "status": {
            "type": "string",
            "enum": [
              "APPROVED",
              "IN_REVIEW",
              "DECLINED",
              "AWAITING_USER"
            ],
            "description": "현재 모니터링 판정 결과입니다. 거래는 `APPROVED` 상태로 생성되며, 규칙에 따라 동기식으로 `IN_REVIEW`/`DECLINED` 상태로 변경될 수 있습니다."
          },
          "source": {
            "type": "string",
            "enum": [
              "LIVE",
              "IMPORTED"
            ],
            "description": "기록이 생성된 방식입니다. API 또는 SDK를 통해 제출된 거래는 `LIVE`, 콘솔 가져오기를 통해 로드된 거래는 `IMPORTED`입니다."
          },
          "amount": {
            "type": "string",
            "description": "끝자리의 0이 제거된 십진수 문자열 형태의 거래 금액(예: `\"1500\"`, `\"0.5\"`, `\"0.123456789012345678\"`)입니다. 소수점 이하 최대 18자리입니다."
          },
          "currency": {
            "type": "string",
            "description": "`amount`의 통화 코드입니다. 암호화폐 자산 심볼(예: `BTC`)뿐만 아니라 모든 ISO 4217 알파벳 코드(예: `EUR`, `USD`, `NGN`)를 사용할 수 있습니다. 현재 유통 중인 코드를 사용하는 것이 좋습니다. 지원되는 모든 코드에 환율이 제공되는 것은 아닙니다. 해당 코드의 환율을 사용할 수 없는 경우(예: ISO 회계 단위 `XSU` 또는 Didit에서 가격을 책정하지 않는 암호화폐 심볼), 자동 변환이 실패하며 요청에 사전 변환된 `amount_in_default_currency`가 제공되지 않는 한 `preferred_currency_amount`는 null로 반환됩니다."
          },
          "currency_type": {
            "type": "string",
            "nullable": true,
            "description": "`currency_kind`로 제출된 `fiat` 또는 `crypto`."
          },
          "amount_in_default_currency": {
            "type": "string",
            "nullable": true,
            "description": "사용자가 제공한 사전 환산 금액으로, 뒤따르는 0이 제거된 십진수 문자열입니다."
          },
          "default_currency_code": {
            "type": "string",
            "nullable": true
          },
          "preferred_currency_amount": {
            "type": "string",
            "nullable": true,
            "description": "제공되는 경우 애플리케이션의 선호 통화로 변환된 `amount`입니다."
          },
          "preferred_currency_code": {
            "type": "string",
            "nullable": true
          },
          "payment_details": {
            "type": "string",
            "nullable": true,
            "description": "제출된 자유 형식 결제 참조 또는 메모입니다."
          },
          "payment_txn_id": {
            "type": "string",
            "nullable": true,
            "description": "`payment_reference_id`에서 가져온 외부 결제 시스템 참조(예: 블록체인 거래 해시)입니다."
          },
          "score": {
            "type": "integer",
            "description": "규칙에 의해 누적된 위험 점수(일반적으로 0–100). 높을수록 위험합니다."
          },
          "severity": {
            "type": "string",
            "nullable": true,
            "enum": [
              "UNKNOWN",
              "LOW",
              "MEDIUM",
              "HIGH",
              "CRITICAL"
            ],
            "description": "규칙/제공업체에서 설정한 범주형 위험 심각도(`UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`). 설정되기 전까지는 `null`입니다."
          },
          "decision_reason_code": {
            "type": "string",
            "nullable": true,
            "description": "현재 `status`에 대한 기계 판독 가능한 사유."
          },
          "decision_reason_label": {
            "type": "string",
            "nullable": true,
            "description": "`decision_reason_code`에 대한 사람이 읽기 쉬운 라벨입니다."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "신청자의 `vendor_data`에 대한 편의 사본입니다."
          },
          "metadata": {
            "type": "object",
            "description": "생성 시점에 제출된 `subject` 및 `counterparty` payload의 스냅샷입니다."
          },
          "props": {
            "type": "object",
            "description": "생성 시 제공한 `custom_properties`입니다. 각 키는 규칙 조건에서 `custom_values.<key>`로 참조할 수 있습니다."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": "string"
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "didit",
                    "custom"
                  ],
                  "description": "태그가 Didit 프리셋인지 커스텀 태그인지 여부입니다."
                }
              }
            },
            "description": "거래에 연결된 태그(수동 또는 규칙에 의해)입니다."
          },
          "parties": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "role": {
                  "type": "string",
                  "enum": [
                    "APPLICANT",
                    "REMITTER",
                    "BENEFICIARY",
                    "COUNTERPARTY"
                  ],
                  "description": "당사자 역할입니다. 생성 endpoint는 `APPLICANT`(대상자) 및 `COUNTERPARTY`를 할당합니다."
                },
                "entity_type": {
                  "type": "string",
                  "enum": [
                    "individual",
                    "company",
                    "external",
                    "unhostedWallet"
                  ]
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "USER",
                    "BUSINESS",
                    "EXTERNAL"
                  ],
                  "description": "`USER`/`BUSINESS` 당사자는 `vendor_data`를 통해 Didit 소유 엔티티로 다시 연결됩니다. `EXTERNAL` 당사자는 연결된 Didit 엔티티가 없습니다."
                },
                "vendor_data": {
                  "type": "string",
                  "nullable": true,
                  "description": "귀하의 내부 사용자/기업 식별자입니다."
                },
                "full_name": {
                  "type": "string",
                  "nullable": true
                },
                "first_name": {
                  "type": "string",
                  "nullable": true
                },
                "last_name": {
                  "type": "string",
                  "nullable": true
                },
                "country_code": {
                  "type": "string",
                  "nullable": true,
                  "description": "제출된 `address.country`의 국가 코드입니다(일반적으로 ISO 3166-1 alpha-3)."
                },
                "dob": {
                  "type": "string",
                  "format": "date",
                  "nullable": true,
                  "description": "제출된 `date_of_birth`에서 가져온 생년월일입니다."
                },
                "address": {
                  "type": "object",
                  "description": "제출된 주소 객체입니다. 생략된 경우 `{}`입니다."
                },
                "institution_info": {
                  "type": "object",
                  "description": "제출된 기관 세부 정보입니다. 생략 시 `{}`입니다."
                },
                "device": {
                  "type": "object",
                  "description": "IP가 제공된 경우 network_context 하위의 서버 측 IP 보강(지리적 위치, VPN/데이터 센터 플래그)을 포함한 정규화된 기기 컨텍스트입니다.",
                  "properties": {
                    "fingerprint": {
                      "type": "string",
                      "description": "고유 기기 핑거프린트입니다."
                    },
                    "persistent_device_id": {
                      "type": "string",
                      "description": "세션 간 유지되는 고유 기기 식별자(v2 핑거프린트 스키마)입니다."
                    },
                    "user_agent": {
                      "type": "string",
                      "description": "브라우저 또는 앱 사용자 에이전트 문자열입니다."
                    },
                    "browser_family": {
                      "type": "string",
                      "description": "브라우저 계열(예: Chrome, Firefox, Safari)입니다."
                    },
                    "browser_version": {
                      "type": "string",
                      "description": "브라우저 버전 문자열입니다."
                    },
                    "platform": {
                      "type": "string",
                      "description": "플랫폼 식별자(web, ios, android, macos, windows, linux)입니다."
                    },
                    "os_family": {
                      "type": "string",
                      "description": "운영체제 제품군(예: iOS, Android, Windows)."
                    },
                    "os_version": {
                      "type": "string",
                      "description": "운영체제 버전 문자열입니다."
                    },
                    "accept_language": {
                      "type": "string",
                      "description": "Accept-Language 헤더 값입니다."
                    },
                    "session_id": {
                      "type": "string",
                      "description": "세션 식별자(메타데이터에 저장됨)입니다."
                    },
                    "session_age_ms": {
                      "type": "number",
                      "description": "밀리초 단위의 세션 경과 시간입니다."
                    },
                    "network_context": {
                      "type": "object",
                      "description": "IP 주소 및 지리적 위치가 포함된 네트워크 컨텍스트입니다.",
                      "properties": {
                        "ip_address": {
                          "type": "string",
                          "description": "클라이언트 IP 주소입니다."
                        },
                        "ip_country_code": {
                          "type": "string",
                          "description": "IP의 지리적 위치로 확인된 국가(ISO 3166-1 alpha-3)입니다."
                        },
                        "latitude": {
                          "type": "number",
                          "description": "IP의 지리적 위도입니다."
                        },
                        "longitude": {
                          "type": "number",
                          "description": "IP의 지리적 경도입니다."
                        }
                      }
                    }
                  }
                },
                "external_party_snapshot": {
                  "type": "object",
                  "nullable": true,
                  "description": "`EXTERNAL` 당사자에 대한 당사자 데이터의 동결 사본입니다. 당사자가 Didit 사용자 또는 기업에 연결되어 있는 동안에는 `null`입니다."
                }
              }
            },
            "description": "거래 당사자(신청인, 거래 상대방)입니다."
          },
          "payment_methods": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "payment_method_type": {
                  "type": "string",
                  "enum": [
                    "bank_card",
                    "bank_account",
                    "e_wallet",
                    "crypto_wallet",
                    "unhosted_wallet",
                    "other"
                  ]
                },
                "label": {
                  "type": "string",
                  "nullable": true
                },
                "fingerprint": {
                  "type": "string",
                  "nullable": true,
                  "description": "`type:account_id:issuing_country`에 대한 SHA-256 — 동일한 수단의 재사용을 연계하기 위한 안정적인 식별자입니다."
                },
                "account_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "계정 식별자(IBAN, 지갑 주소, 카드 token 등)."
                },
                "issuing_country": {
                  "type": "string",
                  "nullable": true
                },
                "owner_kind": {
                  "type": "string",
                  "enum": [
                    "USER",
                    "BUSINESS",
                    "EXTERNAL"
                  ]
                },
                "vendor_data": {
                  "type": "string",
                  "nullable": true,
                  "description": "소유한 사용자/기업에 대한 귀하의 식별자입니다."
                },
                "owner_name": {
                  "type": "string",
                  "nullable": true
                },
                "institution_info": {
                  "type": "object"
                },
                "details": {
                  "type": "object",
                  "description": "제출된 원시 `payment_method` 객체입니다."
                },
                "external_owner_snapshot": {
                  "type": "object",
                  "nullable": true
                },
                "role": {
                  "type": "string",
                  "enum": [
                    "SOURCE",
                    "DESTINATION",
                    "FUNDING",
                    "BENEFICIARY"
                  ],
                  "description": "거래에서 이 방법이 사용된 방식입니다. 생성 endpoint는 방향에 따라 `SOURCE`/`DESTINATION`을 할당합니다(발신: 주체 = SOURCE, 수신: 주체 = DESTINATION)."
                }
              }
            },
            "description": "거래에 연결된 결제 수단입니다."
          },
          "documents": {
            "type": "array",
            "description": "콘솔에서 거래에 첨부된 파일입니다. 없는 경우 `[]`입니다.",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "label": {
                  "type": "string",
                  "nullable": true
                },
                "note": {
                  "type": "string",
                  "nullable": true
                },
                "uploaded_by": {
                  "type": "string",
                  "nullable": true
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "files": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "uuid": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "file_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "유효 기간이 짧은 서명된 다운로드 URL입니다. 저장하지 말고 필요할 때 가져오세요."
                      },
                      "original_filename": {
                        "type": "string",
                        "nullable": true
                      },
                      "file_size": {
                        "type": "integer",
                        "nullable": true
                      }
                    }
                  }
                }
              }
            }
          },
          "activities": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "activity_type": {
                  "type": "string",
                  "description": "예: `TRANSACTION_CREATED`, `TRANSACTION_NOTE_ADDED`, `TRANSACTION_STATUS_CHANGED`."
                },
                "source": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "nullable": true
                },
                "title": {
                  "type": "string",
                  "nullable": true
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "metadata": {
                  "type": "object"
                },
                "occurred_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "description": "활동 로그 항목입니다(생성, 메모, 수동 검토, 상태 변경)."
          },
          "alerts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "title": {
                  "type": "string"
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "severity": {
                  "type": "string",
                  "enum": [
                    "UNKNOWN",
                    "LOW",
                    "MEDIUM",
                    "HIGH",
                    "CRITICAL"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "OPEN",
                    "INVESTIGATING",
                    "AWAITING_USER",
                    "PENDING_SAR",
                    "SAR_FILED",
                    "RESOLVED",
                    "DISMISSED"
                  ]
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "RULE",
                    "PROVIDER",
                    "MANUAL"
                  ]
                },
                "metadata": {
                  "type": "object"
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "due_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true
                }
              }
            },
            "description": "현재는 항상 비어 있습니다. 미해결 알림은 상태가 `IN_REVIEW` 또는 `AWAITING_USER`인 거래입니다."
          },
          "rule_runs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "rule": {
                  "type": "string",
                  "format": "uuid",
                  "description": "실행된 규칙의 UUID입니다."
                },
                "rule_title": {
                  "type": "string"
                },
                "rule_description": {
                  "type": "string",
                  "nullable": true
                },
                "rule_category": {
                  "type": "string"
                },
                "matched": {
                  "type": "boolean",
                  "description": "규칙의 조건이 이 거래와 일치했는지 여부입니다. 일치하는 규칙에 대해서만 실행이 기록되므로, 실시간 평가에서는 항상 `true`를 갖습니다."
                },
                "is_test": {
                  "type": "boolean",
                  "description": "규칙이 TEST 모드에서 실행된 경우 true입니다(상태/점수에 영향 없음)."
                },
                "mode": {
                  "type": "string",
                  "enum": [
                    "ACTIVE",
                    "DISABLED",
                    "TEST"
                  ]
                },
                "severity": {
                  "type": "string",
                  "nullable": true
                },
                "score_delta": {
                  "type": "integer",
                  "description": "이 규칙의 `add_score` 작업으로 추가된 점수입니다."
                },
                "status_target": {
                  "type": "string",
                  "nullable": true,
                  "description": "`change_status` 작업에 의해 설정된 상태(있는 경우)입니다."
                },
                "action_summary": {
                  "type": "string",
                  "nullable": true,
                  "description": "규칙이 실행한 작업의 요약으로, `; `로 연결됩니다(예: `score +30; change_status:IN_REVIEW; add_tag:high_risk_country`). 구성 요소: `score +N`, `change_status:<STATUS>`, `add_tag:<name>`, `add_note`, `add_to_list`, `open_case`. 규칙이 아무런 작업도 실행하지 않은 경우 `null`입니다."
                },
                "metadata": {
                  "type": "object",
                  "description": "평가 세부 정보: `scope_match`, `conditions[]` 및 `aggregations[]`. 각 조건 항목은 `field`, `operator`, `expected_value`, 거래에서 읽은 `current_value`, `matched`, `group_index` 및 `group_logic`을 포함합니다. 각 집계 항목(속도 / 건수 / 합계)은 `metric`, `field`, `operator`, `expected_value`, 집계 결과인 `computed_value`, `window`, `filters`, `matched` 및 `sample_references`를 포함합니다. 지연된 비동기 집계는 `computed_value: null` 및 `deferred: true`를 가집니다. 중첩 조건 그룹은 `operator`가 `any_of` 또는 `all_of`이고, `field`가 null이며, 해당 멤버들의 결과가 자체 `conditions` 아래에 있는 하나의 `conditions[]` 항목입니다."
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "description": "규칙별 실행 결과 — 어떤 규칙이 실행되었는지와 점수에 미친 영향입니다."
          },
          "provider_results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "provider": {
                  "type": "string"
                },
                "result_type": {
                  "type": "string",
                  "enum": [
                    "FIAT_MONITORING",
                    "WALLET_SCREENING",
                    "TRANSACTION_SCREENING",
                    "TRAVEL_RULE",
                    "NETWORK_GRAPH",
                    "CUSTOM"
                  ]
                },
                "status": {
                  "type": "string"
                },
                "severity": {
                  "type": "string",
                  "nullable": true
                },
                "score": {
                  "type": "integer"
                },
                "summary": {
                  "type": "string",
                  "nullable": true
                },
                "payload": {
                  "type": "object",
                  "description": "원시 제공자 응답 payload입니다."
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "description": "원시 제공자 payload(AML 스크리닝, 블록체인 분석 등)입니다."
          },
          "travel_rule": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/TransactionTravelRule"
              }
            ],
            "description": "Travel Rule 이체 또는 확인입니다. `travel_rule_details`가 제출되었을 때, 그리고 Travel Rule이 활성화되어 있고 `transaction_category: travelRule`로 거래가 생성되었을 때 채워집니다(Didit은 `travel_rule_details` 없이도 정보 교환을 직접 시작합니다). 이체 또는 확인이 존재하지 않는 경우 `null`입니다. 인바운드 이체에서는 지갑 소유권이 확인될 때까지 거래 상대방의 `originator_data` 및 `beneficiary_data`가 마스킹된 상태(`data_masked: true`)로 유지됩니다."
          },
          "network_snapshot": {
            "type": "object",
            "nullable": true,
            "description": "규칙 엔진에서 사용하는 관련 거래/당사자의 그래프 스냅샷입니다. 거래와 함께 제출된 `network_snapshot` 또는 Didit이 성공한 AML 지갑 스크리닝에서 빌드하는 그래프(제출된 그래프를 대체함) 중 하나입니다. 둘 다 존재하지 않는 경우 `null`입니다.",
            "properties": {
              "uuid": {
                "type": "string",
                "format": "uuid"
              },
              "nodes": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "edges": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "metrics": {
                "type": "object"
              }
            }
          },
          "remediation": {
            "type": "object",
            "nullable": true,
            "description": "재인증이 필요할 때 사용자에게 제공되는 개선 세션입니다. 표준 블록인 `action_required`로 대체되었으며, 이전 버전과의 호환성을 위해 유지됩니다.",
            "properties": {
              "session_id": {
                "type": "string"
              },
              "session_token": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              },
              "status": {
                "type": "string"
              }
            }
          },
          "action_required": {
            "type": "object",
            "nullable": true,
            "description": "이 거래를 완료하는 데 필요한 대기 중인 최종 사용자 작업이며, 없는 경우 null입니다. Didit SDK는 기본적으로 작업을 자동으로 실행하고 완료 시 거래를 새로고침합니다. `type`으로 구분되는 두 가지 변형이 있습니다. `verification_session`(규칙 작업에 의해 생성된 호스팅 인증 세션)과 `wallet_ownership`(지갑 제어 증명이 필요한 Travel Rule 이체에 대해 자동 생성되는 지갑 소유권 위젯 세션으로, `auto_wallet_verification` Travel Rule 설정에 따라 제어됨)입니다. 둘 다 적용될 수 있는 경우 Travel Rule 교환을 차단하므로 `wallet_ownership`이 우선 적용됩니다.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/TransactionVerificationSessionAction"
              },
              {
                "$ref": "#/components/schemas/TransactionWalletOwnershipAction"
              }
            ],
            "discriminator": {
              "propertyName": "type",
              "mapping": {
                "verification_session": "#/components/schemas/TransactionVerificationSessionAction",
                "wallet_ownership": "#/components/schemas/TransactionWalletOwnershipAction"
              }
            }
          },
          "cost_breakdown": {
            "type": "object",
            "nullable": true,
            "description": "이 거래의 비용입니다. `total_price`와 청구 항목별 `usage_type`, `price`, `details`, `created_at`이 포함된 `items`로 구성됩니다. 동일한 거래를 다시 스크리닝하면 새 항목이 생성됩니다."
          }
        }
      },
      "TravelRuleSettingsDetail": {
        "type": "object",
        "properties": {
          "is_enabled": {
            "type": "boolean",
            "description": "이 애플리케이션에서 아웃바운드 `travelRule` 거래에 대한 관리형 Travel Rule 협상 플로우가 활성화되어 있는지 여부입니다."
          },
          "jurisdiction": {
            "type": "string",
            "maxLength": 8,
            "description": "귀하 VASP의 운영 관할권 코드입니다. 기본값은 `\"EU\"`입니다. Didit은 이를 귀하의 Travel Rule 거래에 `travel_rule_regime`으로 표기하는 규제 체제(예: `EU` 또는 EU 회원국 코드는 `eu`가 됨)에 매핑하며, 거래 규칙에서 이를 기준으로 활용할 수 있습니다. Didit 네트워크에 귀하의 프로필이 등록되면 다른 Didit 고객에게 귀하의 관할권으로 표시됩니다."
          },
          "name_matching_strictness": {
            "type": "string",
            "enum": [
              "NONE",
              "STRICT",
              "CONTAINS",
              "DEFAULT",
              "FUZZY"
            ],
            "description": "이체가 COMPLETED 상태에 도달하기 위해 수취인 이름이 얼마나 엄격하게 일치해야 하는지를 나타냅니다. `CONTAINS`는 한 이름의 단어가 다른 이름에 모두 포함되어 있는 경우를 허용합니다."
          },
          "confirmation_timeout_hours": {
            "type": "integer",
            "minimum": 1,
            "description": "주기적 청소 작업(sweeper)이 만료 처리하기 전까지 AWAITING_COUNTERPARTY 전송이 미확인 상태로 유지될 수 있는 시간입니다. 기본값은 48입니다."
          },
          "timeout_outcome": {
            "type": "string",
            "enum": [
              "HOLD",
              "REJECT",
              "PROCEED"
            ],
            "description": "전송이 만료될 때 해당 거래에 수행되는 작업입니다. 기본값은 HOLD입니다. sunrise_policy 및 non_responsive_policy가 적용되고 설정된 경우 해당 정책이 우선합니다."
          },
          "threshold_amount": {
            "type": "string",
            "description": "애플리케이션의 기본 통화로 표시된 십진수 문자열입니다. 관리형 교환을 트리거하는 최소 거래 금액이며, 이 금액 미만의 거래는 NOT_APPLICABLE로 바로 처리됩니다. Didit은 기본 통화로 환산된 거래 금액 또는 사용자가 전송한 `amount_in_default_currency`를 비교합니다. 환산된 금액을 사용할 수 없는 경우 임계값이 적용되지 않습니다. 기본값은 \"0.00\"입니다(EU TFR은 최소 금액을 적용하지 않음)."
          },
          "ownership_validation_mode": {
            "type": "string",
            "enum": [
              "FULL",
              "SIMPLIFIED",
              "AUTOMATED"
            ],
            "description": "지갑 소유권에 필요한 증명의 수준입니다. `FULL`은 항상 증명(서명된 메시지, 테스트 입금 또는 검토된 스크린샷)이 필요하며 최종 사용자의 구두 진술만으로는 불가합니다. `SIMPLIFIED`는 `simplified_validation_threshold` 미만에서는 자체 선언을 허용하고 그 이상에서는 증명을 요구합니다. `AUTOMATED`는 주소록 및 이전 증명을 통해 자체적으로 판별하며, `allow_self_declaration`이 true인 동안에는 자체 선언도 포함됩니다. 기본값은 `AUTOMATED`입니다."
          },
          "simplified_validation_threshold": {
            "type": "string",
            "description": "십진수 문자열이며 기본값은 \"0.00\"입니다. `SIMPLIFIED` 모드에서는 이 금액(임계값 통화 기준) 미만의 거래에 대해 자체 신고를 허용합니다. 해당 통화 기준 금액이 없는 거래는 이 금액을 초과하는 것으로 간주됩니다."
          },
          "data_sharing_fields": {
            "$ref": "#/components/schemas/TravelRuleDataSharingFields"
          },
          "matching_rules": {
            "$ref": "#/components/schemas/TravelRuleMatchingRules"
          },
          "legal_name": {
            "type": "string",
            "description": "귀하의 VASP의 법인명입니다. is_enabled를 true로 설정하려면 필수(공백 불가)입니다."
          },
          "lei": {
            "type": "string",
            "description": "VASP 디렉터리에 노출되는 법인 식별자(LEI)입니다."
          },
          "compliance_email": {
            "type": "string",
            "format": "email",
            "description": "VASP 프로필의 컴플라이언스 담당자 연락처 이메일입니다. 이 주소가 이메일로 발송된 링크(POST /v3/travel-rule/settings/compliance-email/confirmation/)를 통해 확인된 경우에만 Didit 네트워크에 프로필이 등록됩니다. 주소를 변경하면 새로 확인해야 합니다."
          },
          "is_discoverable": {
            "type": "boolean",
            "description": "귀하의 VASP 프로필이 Didit 네트워크에 등록될 수 있는지 여부입니다. 다른 Didit 고객이 GET /v3/travel-rule/vasps/에서 찾을 수 있으며 INTERNAL 레일을 통해 연결됩니다. 등록하려면 프로덕션 애플리케이션, Travel Rule 활성화, 법인명 및 확인된 컴플라이언스 이메일도 필요합니다. didit_network에 누락된 항목이 표시됩니다. 기본값은 true입니다."
          },
          "inbound_auto_accept": {
            "type": "boolean",
            "description": "true인 경우, 수취인 지갑이 이름이 일치하는 인증된 주소록 항목인 수신 TRP 문의가 자동으로 승인됩니다. false인 경우, 해당 문의는 ON_HOLD 상태로 대기하며 소유권 endpoint를 통해 승인하거나 거부해야 합니다. INTERNAL 레일 및 입금 후 이체는 영향을 받지 않습니다. 기본값은 true입니다."
          },
          "allow_self_declaration": {
            "type": "boolean",
            "description": "true인 경우, 지갑 소유권 위젯에서 대체 증명 방법으로 자체 선언을 제공합니다. 기본값은 true입니다."
          },
          "allow_screenshot_proof": {
            "type": "boolean",
            "description": "true인 경우, 지갑 소유권 위젯에서 소유권 증빙 방법으로 스크린샷 업로드를 제공합니다. 기본값은 true입니다."
          },
          "auto_wallet_verification": {
            "type": "boolean",
            "description": "true인 경우, 최종 사용자의 지갑 제어 증명이 필요한 발신 Travel Rule 이체를 제출하면 해당 거래에 바인딩된 지갑 소유권 위젯 세션이 자동으로 발행되어 거래의 action_required 블록에 노출됩니다. 기본값은 true입니다."
          },
          "vasp_attribution_enabled": {
            "type": "boolean",
            "description": "true인 경우, 어떤 레일로도 라우팅할 수 없는 발신 Travel Rule 이체는 블록체인 분석을 통해 귀속 처리됩니다. 목적지 지갑이 소유 VASP로 식별되고, 해당 엔티티가 이체 기록 및 VASP 디렉터리에 기록되며, 귀속된 이름을 사용하여 레일이 한 번 더 다시 실행됩니다. 기본값은 true입니다."
          },
          "counterparty_screening_enabled": {
            "type": "boolean",
            "description": "거래 상대방 VASP에 대한 선택적 제재 및 부정적 언론 보도 스크리닝으로, 기업 AML 스크리닝 가격에 따라 스크리닝 건당 청구됩니다. 활성화하면 Didit은 발신 거래가 도달하는 거래 상대방을 스크리닝하며(30일 미만의 스크리닝 결과 재사용), POST /v3/travel-rule/vasps/{vasp_id}/screening/을 통해 직접 스크리닝할 수도 있습니다. 기본값은 false이며, 스크리닝되거나 결제되지 않습니다."
          },
          "sunrise_policy": {
            "type": "string",
            "enum": [
              "",
              "HOLD",
              "REJECT",
              "PROCEED"
            ],
            "description": "거래 상대방이 아직 Travel Rule을 시행하지 않는 sunrise_jurisdictions 관할 구역의 디렉터리 항목일 때 만료된 전송이 해당 거래에 미치는 영향: HOLD는 검토 중으로 이동하고, REJECT는 거부하며, PROCEED는 상태를 변경하지 않고 그대로 둡니다. 비어 있는 경우(기본값) timeout_outcome을 따릅니다. non_responsive_policy보다 먼저 적용됩니다."
          },
          "sunrise_jurisdictions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "readOnly": true,
            "description": "읽기 전용입니다. Didit이 sunrise_policy가 적용되는 Travel Rule sunrise 기간(일출 기간)에 있는 것으로 처리하는 국가(ISO 3166 alpha-2) 목록입니다. 현재 CO, KH, VN이 해당됩니다. 그 외의 모든 관할 구역이나 비어 있거나 알 수 없는 관할 구역은 timeout_outcome을 따릅니다."
          },
          "non_responsive_policy": {
            "type": "string",
            "enum": [
              "",
              "HOLD",
              "REJECT",
              "PROCEED"
            ],
            "description": "거래 상대방의 응답 상태가 UNRESPONSIVE인 디렉터리 항목일 때 만료된 전송이 해당 거래에 미치는 영향: timeout_outcome과 마찬가지로 HOLD, REJECT 또는 PROCEED입니다. 비어 있는 경우(기본값) timeout_outcome을 따릅니다. 둘 다 해당하는 경우 sunrise_policy가 먼저 적용됩니다."
          },
          "travel_address": {
            "type": "string",
            "description": "읽기 전용입니다. 귀사 VASP의 자체 Travel Address입니다. 다른 VASP가 귀사에 접근하는 데 사용하는 인코딩된 인바운드 TRP 문의 endpoint입니다. `is_enabled`가 false인 동안에는 비어 있습니다."
          },
          "disabled_networks": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "GTR",
                "TRUST",
                "VERIFYVASP",
                "SYGNA"
              ]
            },
            "description": "플랫폼 멤버십에 참여하지 않기로 한 네트워크입니다. 연결된 자체 멤버십을 비활성화하거나 사용할 수 없는 네트워크를 프로비저닝하지 않습니다.",
            "default": []
          },
          "networks": {
            "type": "object",
            "readOnly": true,
            "description": "네트워크별로 이 애플리케이션이 전송하는 방식과 전송할 수 없는 이유를 나타냅니다. GTR을 포함한 어떤 네트워크도 기본으로 포함되지 않습니다. 네트워크는 연결된 자체 멤버십을 통해 도달하거나, 해당 네트워크에 대한 Didit의 멤버십이 활성화되고 자체 참가자가 활성 상태가 되면 Didit 멤버십을 통해 도달할 수 있습니다. 실시간 상태 또는 전송 확인 검사가 아닙니다.",
            "properties": {
              "gtr": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              },
              "trust": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              },
              "verifyvasp": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              },
              "sygna": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              }
            }
          },
          "didit_network": {
            "type": "object",
            "readOnly": true,
            "description": "Didit 네트워크가 귀하의 VASP 프로필을 나열하여 다른 Didit 고객이 디렉터리에서 이를 찾고 INTERNAL 레일로 도달할 수 있는지 여부 및 아직 충족되지 않은 각 조건입니다.",
            "properties": {
              "listed": {
                "type": "boolean"
              },
              "missing": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "travel_rule_off",
                    "sandbox_application",
                    "not_discoverable",
                    "legal_name_missing",
                    "compliance_email_missing",
                    "compliance_email_unconfirmed",
                    "excluded_by_staff",
                    "internal_organization"
                  ]
                },
                "description": "목록에 표시된 경우 비어 있습니다. compliance_email_unconfirmed: POST /v3/travel-rule/settings/compliance-email/confirmation/으로 확인 요청을 전송하고 이메일로 받은 링크를 여세요. excluded_by_staff: Didit에서 해당 애플리케이션을 테스트, 데모 또는 내부용으로 표시했습니다."
              },
              "compliance_email_confirmed": {
                "type": "boolean",
                "description": "현재 compliance_email이 이메일로 발송된 링크를 통해 확인되었는지 여부입니다."
              }
            }
          }
        }
      },
      "TravelRuleSettingsUpdate": {
        "type": "object",
        "properties": {
          "is_enabled": {
            "type": "boolean"
          },
          "legal_name": {
            "type": "string",
            "maxLength": 255
          },
          "lei": {
            "type": "string",
            "maxLength": 20
          },
          "jurisdiction": {
            "type": "string",
            "maxLength": 8
          },
          "name_matching_strictness": {
            "type": "string",
            "enum": [
              "NONE",
              "STRICT",
              "CONTAINS",
              "DEFAULT",
              "FUZZY"
            ],
            "description": "`CONTAINS`는 한 이름의 단어가 모두 다른 이름에 나타나는 경우를 허용합니다."
          },
          "confirmation_timeout_hours": {
            "type": "integer",
            "minimum": 1
          },
          "timeout_outcome": {
            "type": "string",
            "enum": [
              "HOLD",
              "REJECT",
              "PROCEED"
            ]
          },
          "compliance_email": {
            "type": "string",
            "format": "email",
            "description": "VASP 프로필의 컴플라이언스 담당자 연락처 이메일입니다. 이 주소가 이메일로 발송된 링크(POST /v3/travel-rule/settings/compliance-email/confirmation/)를 통해 확인된 경우에만 Didit 네트워크에 프로필이 등록됩니다. 주소를 변경하면 새로 확인해야 합니다."
          },
          "is_discoverable": {
            "type": "boolean",
            "description": "귀하의 VASP 프로필이 Didit 네트워크에 등록될 수 있는지 여부입니다. 다른 Didit 고객이 GET /v3/travel-rule/vasps/에서 찾을 수 있으며 INTERNAL 레일을 통해 연결됩니다. 등록하려면 프로덕션 애플리케이션, Travel Rule 활성화, 법인명 및 확인된 컴플라이언스 이메일도 필요합니다. didit_network에 누락된 항목이 표시됩니다. 기본값은 true입니다."
          },
          "threshold_amount": {
            "type": "string",
            "description": "애플리케이션의 기본 통화로 표시된 0 이상의 십진수 문자열입니다. 관리형 교환을 트리거하는 최소 거래 금액입니다."
          },
          "ownership_validation_mode": {
            "type": "string",
            "enum": [
              "FULL",
              "SIMPLIFIED",
              "AUTOMATED"
            ],
            "description": "동일한 이름의 응답 필드를 참조하세요."
          },
          "simplified_validation_threshold": {
            "type": "string",
            "description": "0 이상의 십진수 문자열입니다."
          },
          "data_sharing_fields": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleDataSharingFields"
              }
            ],
            "description": "엔터티 유형별로 병합됩니다. 생략된 엔터티 유형은 현재 선택 항목을 유지합니다. 빈 목록을 포함하여 해당 `jurisdiction` 규정 체계(EU TFR 또는 FATF 권고안 16)의 송금인 의무를 충족할 수 없는 선택 항목은 `400`으로 거부됩니다."
          },
          "matching_rules": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleMatchingRules"
              }
            ],
            "description": "엔터티 유형별, 그리고 그 내부의 필드별로 병합됩니다. 해당 엔터티 유형에서 비교하지 않는 필드(예: `company`의 `date_of_birth`)는 `400`으로 거부됩니다."
          },
          "inbound_auto_accept": {
            "type": "boolean"
          },
          "allow_self_declaration": {
            "type": "boolean"
          },
          "allow_screenshot_proof": {
            "type": "boolean",
            "description": "true인 경우, 지갑 소유권 위젯에서 소유권 증빙 방법으로 스크린샷 업로드를 제공합니다. 기본값은 true입니다."
          },
          "auto_wallet_verification": {
            "type": "boolean"
          },
          "vasp_attribution_enabled": {
            "type": "boolean"
          },
          "counterparty_screening_enabled": {
            "type": "boolean",
            "description": "거래 상대방 VASP에 대한 선택적 제재 및 부정적 언론 보도 스크리닝으로, 기업 AML 스크리닝 가격에 따라 스크리닝 건당 청구됩니다. 활성화하면 Didit은 발신 거래가 도달하는 거래 상대방을 스크리닝하며(30일 미만의 스크리닝 결과 재사용), POST /v3/travel-rule/vasps/{vasp_id}/screening/을 통해 직접 스크리닝할 수도 있습니다. 기본값은 false이며, 스크리닝되거나 결제되지 않습니다."
          },
          "sunrise_policy": {
            "type": "string",
            "enum": [
              "",
              "HOLD",
              "REJECT",
              "PROCEED"
            ],
            "description": "HOLD, REJECT, PROCEED 또는 timeout_outcome을 따르기 위한 빈 값입니다. 동일한 이름의 응답 필드를 참조하십시오."
          },
          "non_responsive_policy": {
            "type": "string",
            "enum": [
              "",
              "HOLD",
              "REJECT",
              "PROCEED"
            ],
            "description": "HOLD, REJECT, PROCEED 또는 timeout_outcome을 따르기 위한 빈 값입니다. 동일한 이름의 응답 필드를 참조하십시오."
          },
          "disabled_networks": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "GTR",
                "TRUST",
                "VERIFYVASP",
                "SYGNA"
              ]
            },
            "description": "플랫폼 멤버십에 참여하지 않기로 한 네트워크입니다. 연결된 자체 멤버십을 비활성화하거나 사용할 수 없는 네트워크를 프로비저닝하지 않습니다.",
            "default": []
          }
        },
        "description": "모든 필드는 선택 사항이며, PUT은 부분 업데이트를 적용합니다."
      },
      "WalletAddressEntry": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "address": {
            "type": "string",
            "description": "지갑 주소입니다. 해시로만 가져온 항목의 경우 `\"\"`입니다. 대소문자를 구분하지 않고 주소를 비교하며, 애플리케이션, 체인, 메모별로 고유합니다. 항목을 삭제한 후 동일한 주소를 다시 등록할 수 있습니다."
          },
          "chain": {
            "type": "string",
            "description": "주소에 대한 체인 token(예: `ETH` 또는 `BTC`). Didit이 이체를 라우팅하거나 등록할 때 지갑 주소를 기준으로 주소록 항목을 매칭하며, 이체에 체인이 포함된 경우 대소문자를 무시하고 이 값도 기준으로 매칭합니다. 이체의 체인은 `beneficiary_data.chain`이며, 직접 전송하지 않은 경우 거래의 암호화폐 체인 또는 통화 기호(예: `ETH`)에서 채워지거나 입금 후 등록의 `chain`에서 채워지므로 모든 곳에서 동일한 token을 사용하십시오. 체인이 비어 있는 항목은 모든 체인과 일치합니다. 비트코인에 등록된 Lightning 수취인(노드 id 또는 Lightning Address)은 `LIGHTNING`에 소문자로 저장되며, 여기서 Lightning 이체가 매칭됩니다. 알려진 체인은 어떤 철자로 전송하든 하나의 표준 식별자로 저장됩니다. \"ethereum\", \"Ethereum\", \"ERC20\"은 모두 ETH로 저장되고, \"BNB Smart Chain\" 및 \"BEP20\"은 BNB로, \"tron\"은 TRX로 저장됩니다. 알 수 없는 체인 이름은 입력된 그대로 유지됩니다."
          },
          "holder_vendor_data": {
            "type": "string",
            "description": "보유자에 대한 귀하의 내부 식별자입니다."
          },
          "holder_name": {
            "type": "string",
            "description": "수취인 이름 대조에 사용되는 지갑 보유자 이름입니다."
          },
          "entity_type": {
            "type": "string",
            "description": "자유 형식 텍스트이며 기본값은 \"individual\"입니다."
          },
          "is_ownership_verified": {
            "type": "boolean",
            "description": "읽기 전용입니다. 이 주소의 소유권이 증명되었는지 여부입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "travel_address": {
            "type": "string",
            "description": "알려진 경우, 이 지갑에 대한 거래 상대방 VASP의 Travel Address입니다. Didit이 TRP가 지원하는 자산(BTC, ETH 및 지정된 네트워크의 USDC)에 대해 TRP 레일을 통해 이 수취인의 이체를 라우팅할 수 있도록 합니다."
          },
          "address_hash": {
            "type": "string",
            "description": "읽기 전용입니다. 소문자로 변환된 주소의 SHA-256 해시값(소문자 16진수)입니다. 해시만으로 가져온 항목은 이 값을 기준으로 매칭됩니다."
          },
          "memo": {
            "type": "string",
            "description": "메모 네트워크(XRP, XLM, EOS, ATOM, HBAR)의 지갑 일부인 대상 태그 또는 메모입니다. 주소 전체인 경우 `\"\"`입니다. 메모가 있는 항목은 해당 메모를 지정한 전송과만 일치하며, 메모가 없는 항목은 전체 주소와 일치합니다."
          },
          "receiving_travel_address": {
            "type": "string",
            "readOnly": true,
            "description": "이 지갑에 대한 지갑별 Travel Address입니다. 송금 VASP에 제공하여 해당 TRP 조회에서 이 지갑을 지정할 수 있도록 합니다. 다른 VASP의 지갑으로 기록되어 있거나, Travel Rule이 비활성화되어 있는 동안, 그리고 VASP 프로필이 저장되기 전에는 비어 있습니다."
          }
        }
      },
      "WalletAddressEntryCreate": {
        "type": "object",
        "required": [
          "address"
        ],
        "properties": {
          "address": {
            "type": "string",
            "maxLength": 128,
            "description": "지갑 주소입니다. XRP X-address는 클래식 주소와 태그로 저장되므로 두 형식 중 어느 쪽을 지정한 전송과도 일치합니다."
          },
          "chain": {
            "type": "string",
            "maxLength": 32,
            "description": "해당 주소의 체인 token(예: `ETH` 또는 `BTC`)입니다. Didit이 이체를 라우팅하거나 등록할 때 지갑 주소를 기준으로 주소록 항목과 일치 여부를 대조하며, 이체에 체인 정보가 포함되어 있는 경우 대소문자를 구분하지 않고 이 값도 함께 대조합니다. 이체의 체인은 `beneficiary_data.chain`이며, 직접 전송하지 않은 경우 거래의 암호화폐 체인 또는 통화 심볼(예: `ETH`)에서 채워지거나 입금 후 등록의 `chain`에서 채워지므로 모든 곳에서 동일한 token을 사용하십시오. 체인 값이 비어 있는 항목은 모든 체인과 일치합니다. 알려진 체인은 어떤 철자로 전송하든 하나의 표준 식별자로 저장됩니다. \"ethereum\", \"Ethereum\", \"ERC20\"은 모두 ETH로 저장되고, \"BNB Smart Chain\"과 \"BEP20\"은 BNB로, \"tron\"은 TRX로 저장됩니다. 알 수 없는 체인 이름은 제공된 그대로 유지됩니다."
          },
          "holder_vendor_data": {
            "type": "string",
            "maxLength": 255
          },
          "holder_name": {
            "type": "string",
            "maxLength": 255
          },
          "entity_type": {
            "type": "string",
            "default": "individual",
            "maxLength": 16
          },
          "self_declared": {
            "type": "boolean",
            "default": false,
            "description": "쓰기 전용입니다. true인 경우 항목이 SELF_DECLARATION 증명을 통해 이미 소유 구조가 확인된 상태로 생성됩니다. Travel Rule 설정에서 `allow_self_declaration`이 꺼져 있으면 400을 반환합니다."
          },
          "travel_address": {
            "type": "string",
            "description": "선택 사항입니다. 이 지갑에 대한 거래 상대방 VASP의 Travel Address로, TRP가 지원하는 자산(BTC, ETH 및 지정된 네트워크의 USDC)에 대한 TRP 라우팅을 활성화합니다. 잘못된 Travel Address는 400을 반환합니다.",
            "maxLength": 512
          },
          "memo": {
            "type": "string",
            "maxLength": 256,
            "description": "선택 사항입니다. 지갑의 일부인 대상 태그 또는 메모입니다. XRP: 대상 태그, 0부터 4294967295까지의 정수(JSON 숫자가 허용됨). XLM: 최대 28바이트의 텍스트 메모, 64비트 ID 또는 16진수 형태의 32바이트 해시. EOS: 최대 256바이트. ATOM: 최대 256자. HBAR: 최대 100바이트. Bitcoin, EVM, Solana, Tron, Litecoin, Bitcoin Cash, Dogecoin 및 Lightning 지갑은 메모를 받지 않으며, 포함 시 `400`이 반환됩니다. 별칭: `destinationTag` 또는 `destination_tag`."
          }
        }
      },
      "WalletAddressEntryUpdate": {
        "type": "object",
        "properties": {
          "holder_name": {
            "type": "string",
            "maxLength": 255
          },
          "holder_vendor_data": {
            "type": "string",
            "maxLength": 255
          },
          "entity_type": {
            "type": "string",
            "maxLength": 16
          },
          "travel_address": {
            "type": "string",
            "maxLength": 512
          }
        },
        "description": "PATCH는 부분 업데이트입니다. 응답에는 holder_name, holder_vendor_data, entity_type, travel_address, receiving_travel_address, label, owner_type만 반환됩니다."
      },
      "TravelRuleTransferDetail": {
        "type": "object",
        "description": "소유권 확인 및 완료/취소 endpoint에서 반환되는 전체 전송 객체입니다. 인바운드 전송의 지갑 소유권이 확인되지 않은 동안에는 상대방의 `originator_data` 및 `beneficiary_data`가 마스킹되어 반환되며(각 단어의 첫 글자만 유지되고 지갑, 체인 및 VASP 라우팅은 읽을 수 있는 상태로 유지됨), `data_masked`는 true가 됩니다.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "AWAITING_COUNTERPARTY",
              "ON_HOLD",
              "COMPLETED",
              "FINISHED",
              "CANCELLED",
              "EXPIRED",
              "COUNTERPARTY_MISMATCHED_DATA",
              "COUNTERPARTY_VASP_NOT_FOUND",
              "COUNTERPARTY_VASP_NOT_REACHABLE",
              "UNCONFIRMED_OWNERSHIP",
              "COUNTERPARTY_VASP_GENERAL_DECLINE",
              "NOT_ENOUGH_COUNTERPARTY_DATA",
              "NOT_APPLICABLE"
            ]
          },
          "direction": {
            "type": "string",
            "enum": [
              "INBOUND",
              "OUTBOUND"
            ]
          },
          "rail": {
            "type": "string",
            "nullable": true,
            "enum": [
              "INTERNAL",
              "TRP",
              "GTR",
              "TRUST",
              "VERIFYVASP",
              "SYGNA",
              "EMAIL",
              "TEST_VASP",
              null
            ],
            "description": "이체가 라우팅된 레일이거나 레일이 선택되지 않은 경우(예: 임계값 미만, 자체 보관 거래 상대방 지갑, 입금 후 등록 또는 도달 가능한 거래 상대방 없음) null입니다. INTERNAL은 양측 모두 Didit 애플리케이션임을 의미하며, EMAIL은 거래 상대방에게 수령 링크를 이메일로 전송하여 도달했음을 의미합니다. TEST_VASP는 Didit Test VASP가 샌드박스 이체에 응답했음을 의미합니다. GTR, VERIFYVASP 및 SYGNA의 경우, Didit은 네트워크 응답을 통해 또는 5분마다 폴링하여 거래 상대방의 응답을 읽습니다. TRUST는 전송만 수행하므로 TRUST 이체는 만료될 때까지 AWAITING_COUNTERPARTY 상태로 유지됩니다. 네트워크 레일은 해당 네트워크에 대한 자체 멤버십을 연결한 경우에만 사용됩니다. 거래 생성이 반환된 후에 선택되므로 해당 응답에서는 null입니다."
          },
          "protocol": {
            "type": "string",
            "nullable": true
          },
          "ivms_version": {
            "type": "string",
            "example": "ivms101.2023"
          },
          "required": {
            "type": "boolean"
          },
          "ownership_confirmed": {
            "type": "boolean",
            "nullable": true
          },
          "deadline_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "timeline": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "string"
                },
                "at": {
                  "type": "string",
                  "format": "date-time"
                },
                "detail": {
                  "type": "string"
                },
                "name_match": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/TravelRuleNameMatch"
                    }
                  ],
                  "nullable": true,
                  "description": "이 항목이 결정한 `detail` 옆의 이름 비교입니다. 이름을 비교하지 않은 항목에는 없습니다."
                },
                "reason": {
                  "type": "string",
                  "description": "전송 실패로 인해 발생한 전환 항목에만 표시됩니다: `email_undeliverable` 또는 `delivery_failed`(전송의 `reason`이 보고하는 값)."
                }
              }
            }
          },
          "counterparty_vasp": {
            "type": "object",
            "nullable": true,
            "properties": {
              "name": {
                "type": "string"
              },
              "lei": {
                "type": "string"
              },
              "dd_score": {
                "type": "integer",
                "description": "0부터 100까지의 실사 점수이며, 높을수록 좋습니다. VASP 디렉터리와 동일한 척도입니다."
              },
              "dd_score_breakdown": {
                "type": "object",
                "description": "dd_score에 대한 구성 요소별 기여도로, VASP 디렉터리와 같이 구성 요소(jurisdiction, verification, protocol, lei, history, essentials, responsiveness)당 하나의 객체이며 각각 {points, max, reason, detail}을 포함합니다. 거래 상대방 평가가 완료될 때까지는 {}입니다.",
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "points": {
                      "type": "number",
                      "description": "이 컴포넌트에 부여된 점수입니다."
                    },
                    "max": {
                      "type": "integer",
                      "description": "이 컴포넌트가 부여할 수 있는 최대 점수입니다."
                    },
                    "reason": {
                      "type": "string",
                      "description": "구성 요소 판정의 기계 판독 가능한 코드."
                    },
                    "detail": {
                      "type": "string",
                      "description": "부여된 점수에 대해 사람이 읽을 수 있는 이유입니다."
                    }
                  }
                }
              },
              "dd_assessed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "실사 평가가 마지막으로 실행된 시점입니다. 거래 상대방이 평가될 때까지는 null입니다."
              }
            }
          },
          "originator_data": {
            "type": "object",
            "description": "송금인 당사자 정보입니다. 인바운드 전송의 경우 소유 구조가 확인될 때까지 거래 상대방의 값이 마스킹됩니다."
          },
          "beneficiary_data": {
            "type": "object",
            "description": "수취인 당사자 정보입니다. 입금 거래의 경우 소유 구조가 확인될 때까지 거래 상대방의 값이 마스킹됩니다."
          },
          "name_match": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleNameMatch"
              }
            ],
            "nullable": true,
            "description": "이체를 결정한 이름 비교이거나, 실행되기 전까지는 null입니다. 당사자가 마스킹되어 있는 동안, 그리고 INTERNAL 교환의 다른 고객 사본에서는 `transfer_name`, `compared_name`, `matched_names`, `mismatched_names`가 숨겨집니다. `score`와 `matched`는 일치하지 않을 수 있습니다. `matched`는 엄격도를 따르고, `score`는 두 전체 성명의 유사도입니다."
          },
          "data_match": {
            "$ref": "#/components/schemas/TravelRuleDataMatch"
          },
          "mismatched_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "`data_match.mismatched_fields`의 바로가기입니다. 일치하지 않는 항목이 없으면 비어 있습니다."
          },
          "data_unmasked": {
            "$ref": "#/components/schemas/TravelRuleDataUnmasked"
          },
          "data_masked": {
            "type": "boolean",
            "description": "이 응답에서 거래 상대방의 개인 데이터가 마스킹되어 있는 동안 true입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "delivery": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleDelivery"
              }
            ],
            "description": "이 이체가 상대방에게 보내야 하는 최신 메시지의 현재 상태입니다. 이체에서 메시지를 보낼 필요가 없었던 경우(예: `threshold_amount` 미만, 신고된 자체 보관 지갑, 선라이즈 등록)에는 null입니다."
          },
          "discovery": {
            "type": "array",
            "description": "Didit이 거래 상대방을 찾은 방식이며, 실행된 단계당 하나의 항목이 포함됩니다. 인바운드 전송과 같이 조회가 실행되지 않은 경우에는 비어 있습니다.",
            "items": {
              "$ref": "#/components/schemas/TravelRuleDiscoveryStep"
            }
          },
          "reason": {
            "type": "string",
            "description": "`COUNTERPARTY_VASP_NOT_FOUND` 또는 `COUNTERPARTY_VASP_NOT_REACHABLE` 전송이 지연된 이유이며, 다른 모든 상태의 경우 `\"\"`입니다. `COUNTERPARTY_VASP_NOT_REACHABLE`에서만 전송 실패가 먼저 결정됩니다: `email_undeliverable`(메일 제공업체가 컴플라이언스 이메일을 거부했고 시도할 주소가 남아있지 않음: 전송 시, 알림 시, 또는 나중에 보고된 영구 반송 시) 또는 `delivery_failed`(전송 중이던 레일이 완전히 실패함: 네트워크 레일이 메시지를 거부했거나 재시도 횟수를 모두 소진함, `TRP` 신원 호스트가 응답하지 않음, 또는 거래 상대방의 `TRP` 호스트가 조회를 수락하지 않음). 그렇지 않으면 `discovery` 추적이 이를 결정합니다: `awaiting_end_user`(Didit이 도달할 수 있는 거래 상대방을 지정한 단계가 없음), `directory_match_no_route`(경로가 없는 디렉터리 VASP를 지정한 단계임), `picked_member_without_proven_wallet`(최종 사용자가 지갑 제어권을 증명하지 않은 Didit 고객을 선택함), 또는 추적에서 다른 이유를 제공하지 않는 경우 `no_directory_match`. 재전송하면 전송이 진행되므로 이유가 초기화됩니다. [전송이 지연되는 이유](/ko/transaction-monitoring/travel-rule#전송이-멈춘-이유)를 참조하십시오."
          },
          "next_actions": {
            "type": "array",
            "description": "전송을 진행시키는 작업입니다. `COUNTERPARTY_VASP_NOT_FOUND` 또는 `COUNTERPARTY_VASP_NOT_REACHABLE` 이외의 상태에서는 `[]`입니다. `email_undeliverable`은 `update_compliance_email`, 그 다음 `resend`를 제공합니다. `delivery_failed`는 `resend`를 제공합니다. 발견 사유는 `select_counterparty_vasp`, `declare_self_hosted`, `add_vasp_hint` 및 `resend`를 제공합니다.",
            "items": {
              "$ref": "#/components/schemas/TravelRuleNextAction"
            }
          },
          "chain_details": {
            "$ref": "#/components/schemas/TravelRuleChainDetails"
          }
        }
      },
      "TravelRuleOwnershipConfirmRequest": {
        "type": "object",
        "required": [
          "confirmed"
        ],
        "properties": {
          "confirmed": {
            "type": "boolean",
            "description": "소유권을 확인하려면 true, 거부하려면 false입니다."
          },
          "wallet_address": {
            "type": "string",
            "default": "",
            "description": "인바운드 TRP 전송: 승인 시 Didit이 송금인 VASP에 반환하는 결제 주소입니다. 기본값은 일치하는 주소록 항목의 주소이며, 그다음은 beneficiary_data.wallet_address입니다. 거래 상대방 지갑이 지정되지 않은 신고된 자체 보관 지갑 전송의 경우 소유 구조를 검증한 지갑이어야 하며, 해당 지갑이 없으면 요청이 400으로 거부됩니다. 다른 전송에서는 무시됩니다."
          }
        }
      },
      "TravelRuleTransferPatchRequest": {
        "type": "object",
        "description": "payment_txn_id(finish), action=cancel, action=resend, compliance_email을 포함한 action=update_compliance_email, wallet_address를 포함한 action=update_originator_wallet, beneficiary_vasp를 포함한 action=beneficiary_vasp 중 정확히 하나만 제공하세요.",
        "properties": {
          "payment_txn_id": {
            "type": "string",
            "description": "온체인 거래 해시입니다. 이체가 COMPLETED 상태인 출금 이체여야 합니다."
          },
          "action": {
            "type": "string",
            "enum": [
              "cancel",
              "resend",
              "update_compliance_email",
              "update_originator_wallet",
              "beneficiary_vasp"
            ],
            "description": "\"cancel\"은 최종 상태가 아닌 전송을 취소합니다. \"resend\"는 COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE 또는 NOT_ENOUGH_COUNTERPARTY_DATA 상태로 정체된 아웃바운드 전송의 라우팅을 다시 실행합니다. \"update_compliance_email\"은 이 세 가지 상태 중 하나에 있는 아웃바운드 전송에서 요청이 전송되는 컴플라이언스 이메일을 교체하며, 이후 \"resend\"를 보내야 합니다. \"update_originator_wallet\"은 실제로 자금이 인출된 지갑(`wallet_address`, `memo`)을 기록합니다. \"beneficiary_vasp\"는 해당 상태 중 하나에 있는 아웃바운드 전송에 대해 거래 상대방 VASP를 직접 지정(`beneficiary_vasp` 필요)하며, 해당 VASP로 라우팅되어 다시 전송됩니다."
          },
          "compliance_email": {
            "type": "string",
            "format": "email",
            "maxLength": 254,
            "description": "`action: update_compliance_email`인 경우 필수입니다. 이 전송의 `beneficiary_data.counterparty_vasp_email`로 유지되며, 해당 전송에만 속하고 디렉터리 항목이나 연락처 목록에 추가되지 않습니다."
          },
          "wallet_address": {
            "type": "string",
            "maxLength": 128,
            "description": "`action: update_originator_wallet`인 경우: 자금이 출금된 지갑입니다. 전송의 UTXO 입력값을 알 수 있는 경우 그중 하나여야 합니다."
          },
          "memo": {
            "type": "string",
            "maxLength": 256,
            "description": "`action: update_originator_wallet`인 경우: 메모 네트워크에서의 지갑 메모 또는 태그입니다. 선택 사항입니다."
          },
          "beneficiary_vasp": {
            "type": "string",
            "format": "uuid",
            "description": "action=beneficiary_vasp인 경우 필수: `GET /v3/travel-rule/vasps/`에서 가져온 디렉터리 VASP의 `id`입니다. 직접 선택한 값이 모든 자동 감지 단계보다 우선하며, 자동 감지 단계에서 이를 덮어쓰지 않습니다."
          }
        }
      },
      "VaspDirectoryEntry": {
        "type": "object",
        "description": "디렉터리의 VASP 또는 Didit 네트워크의 멤버이며, 애플리케이션이 해당 대상과 연결된 경로를 포함합니다. 고객은 애플리케이션이 활성 상태이고, Travel Rule이 켜져 있으며, 프로필이 검색 가능하고, 법적 이름과 확인된 컴플라이언스 이메일이 있으며, Didit이 해당 애플리케이션을 테스트, 데모 또는 내부용으로 표시하지 않은 경우에만 Didit 네트워크의 멤버가 됩니다. 각 행에는 공유 실사 평가(dd_score, risk_level, responsiveness, essential_checks)와 다른 고객에게는 표시되지 않는 애플리케이션 자체의 결정, 엔티티 스크리닝 및 설문지도 포함됩니다.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "GET /v3/travel-rule/vasps/{vasp_id}/ 호출을 위한 항목의 id입니다."
          },
          "kind": {
            "type": "string",
            "enum": [
              "directory",
              "didit"
            ],
            "description": "공유 디렉터리의 항목인 경우 directory, Didit 네트워크 멤버인 경우 didit입니다."
          },
          "name": {
            "type": "string"
          },
          "lei": {
            "type": "string"
          },
          "jurisdiction": {
            "type": "string",
            "description": "소스에서 제공한 ISO 3166 국가 코드입니다."
          },
          "domains": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "VASP의 웹 도메인입니다. Didit 네트워크 멤버의 경우 항상 비어 있습니다."
          },
          "reachable": {
            "type": "boolean",
            "description": "애플리케이션에 이 VASP 또는 해당 브랜드의 엔터티 중 하나로 연결 가능한 경로가 있는지 여부입니다. Didit 네트워크 멤버의 경우 항상 true이지만, 모든 행이 false인 샌드박스 애플리케이션은 예외입니다."
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "trading_name",
                    "other_legal_name",
                    "network_name",
                    "attribution",
                    "merged",
                    "staff"
                  ],
                  "description": "trading_name, other_legal_name(글로벌 LEI 등록부의), network_name(Travel Rule 네트워크상의 이름), attribution(블록체인 분석에서 VASP의 지갑에 부여한 엔티티 이름), merged(이 항목에 병합된 중복 항목의 이름) 또는 staff."
                }
              }
            },
            "description": "VASP가 검색되는 다른 이름입니다."
          },
          "networks": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Travel Rule 네트워크의 멤버 디렉터리에 등록된 이 VASP의 현재 목록입니다. TRISA 목록은 TRISA에서 해당 VASP가 누구인지를 나타냅니다. Didit에는 TRISA 레일이 없으므로 경로가 될 수 없습니다.",
              "properties": {
                "network": {
                  "type": "string",
                  "enum": [
                    "GTR",
                    "TRUST",
                    "VERIFYVASP",
                    "SYGNA",
                    "TRISA"
                  ]
                },
                "code": {
                  "type": "string",
                  "description": "해당 네트워크에서 VASP의 식별자입니다."
                },
                "listed_name": {
                  "type": "string",
                  "description": "네트워크가 VASP를 등록한 이름입니다."
                },
                "country": {
                  "type": "string",
                  "description": "네트워크에 명시된 국가(제공된 경우)입니다."
                },
                "verified_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true,
                  "description": "Didit 직원이 목록을 확인한 시점입니다. 공개 디렉터리에서 읽어온 목록의 경우 null입니다."
                },
                "last_seen_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true,
                  "description": "소스가 마지막으로 해당 등재 정보를 표시한 시점입니다. 소스가 3주 동안 표시하지 않은 등재 정보는 삭제됩니다."
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "trisa_directory",
                    "staff"
                  ],
                  "description": "해당 목록의 출처: 공개 TRISA 디렉터리 또는 Didit 직원."
                }
              }
            }
          },
          "routes": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "애플리케이션이 이 VASP에 Travel Rule 데이터를 전송할 수 있는 방법 1개이며, 디스패치가 시도하는 순서대로 나열됩니다. 네트워크 경로는 해당 네트워크의 멤버십(Marketplace에서 연결된 자체 멤버십 또는 Didit이 보유한 경우 Didit의 멤버십)이 필요합니다. 멤버십이 없으면 해당 경로는 VASP에 도달할 수 있는 방법이 아니라 사유와 함께 사용 불가로 표시됩니다.",
              "properties": {
                "rail": {
                  "type": "string",
                  "enum": [
                    "INTERNAL",
                    "TRP",
                    "GTR",
                    "TRUST",
                    "VERIFYVASP",
                    "SYGNA",
                    "EMAIL"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "available",
                    "unavailable"
                  ]
                },
                "reason": {
                  "type": "string",
                  "enum": [
                    "",
                    "no_membership",
                    "network_switched_off",
                    "sandbox_application"
                  ],
                  "description": "사용할 수 없는 경로를 사용할 수 없는 이유: no_membership(귀사와 Didit 모두 해당 네트워크의 멤버십을 보유하고 있지 않음), network_switched_off(설정에서 해당 네트워크를 끔) 또는 sandbox_application(샌드박스 애플리케이션은 Didit Test VASP로만 전송하므로 사용 가능한 경로가 없음). 경로를 사용할 수 있는 경우 비어 있습니다."
                },
                "via": {
                  "type": "string",
                  "enum": [
                    "",
                    "own_membership",
                    "didit_membership",
                    "directory",
                    "contact",
                    "didit_network"
                  ],
                  "description": "사용 가능한 경로에 도달하는 방식입니다. 네트워크 레일의 경우 own_membership 또는 didit_membership, 디렉터리가 검증한 TRP endpoint의 경우 directory, EMAIL 레일의 경우 contact, Didit 네트워크 멤버의 경우 didit_network입니다. 경로를 사용할 수 없는 경우 비어 있습니다."
                }
              }
            }
          },
          "umbrella": {
            "type": "object",
            "nullable": true,
            "description": "이 항목이 규제 대상 법인으로 속한 브랜드입니다. 속해 있지 않은 경우 null입니다.",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "entities": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "브랜드의 규제 대상 엔티티: 이체를 수취하는 법인 엔티티입니다.",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "lei": {
                  "type": "string"
                },
                "jurisdiction": {
                  "type": "string"
                },
                "reachable": {
                  "type": "boolean",
                  "description": "애플리케이션에 해당 VASP로 연결 가능한 경로가 있는지 여부입니다."
                }
              }
            },
            "description": "브랜드의 경우 해당 브랜드의 전송을 수취하는 규제 대상 법인입니다. 브랜드를 지정한 전송은 명시된 관할권(beneficiary_data.counterparty_vasp_jurisdiction) 내 도달 가능한 법인으로 전달되며, 그렇지 않은 경우 블록체인 분석 귀속 정보가 대상 지갑에 연결된 법인으로 전달되고, 관할권이 명시되지 않은 경우 도달 가능한 유일한 법인으로 전달됩니다. 조건에 동일하게 부합하는 두 법인 사이에서 임의로 추정하지 않습니다."
          },
          "contacts": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "EMAIL 레일이 발송할 수 있는 컴플라이언스 담당자 연락처입니다.",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "email": {
                  "type": "string",
                  "format": "email"
                },
                "name": {
                  "type": "string"
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "staff",
                    "application",
                    "learned"
                  ],
                  "description": "staff: Didit이 관리함, application: 귀하의 애플리케이션에서 추가함, learned: 응답 링크를 통해 Travel Rule 요청에 응답한 주소."
                },
                "scope": {
                  "type": "string",
                  "enum": [
                    "platform",
                    "application"
                  ],
                  "description": "platform 연락처는 모든 Didit 고객의 전송에 사용됩니다. application 연락처는 해당 애플리케이션 전용이며 자체 연락처만 볼 수 있습니다."
                },
                "verified_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true,
                  "description": "이 주소의 누군가가 요청에 응답한 시점입니다. 아직 응답하지 않은 경우 null입니다."
                }
              }
            },
            "description": "이 VASP를 위한 플랫폼의 연락처 및 애플리케이션 자체의 연락처입니다."
          },
          "dd_status": {
            "type": "string",
            "enum": [
              "NOT_STARTED",
              "IN_PROGRESS",
              "COMPLETED",
              "REJECTED"
            ],
            "description": "dd_score의 검증 구성 요소에 의해 점수가 매겨진 항목의 Didit 인증 상태입니다. Didit 네트워크 멤버의 경우 항상 COMPLETED입니다."
          },
          "dd_score": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "maximum": 100,
            "description": "디렉터리 항목의 공유 실사 점수(0~100, 높을수록 안전함, dd_score_semantic 참조)로, dd_score_breakdown에 포함된 점수의 합계입니다. 점수가 매겨지지 않는 Didit 네트워크 멤버의 경우 null입니다. 아직 평가되지 않은 항목(dd_assessed_at이 null)은 risk_level이 비어 있는 상태로 0을 표시하므로, 원시 점수 대신 risk_level을 확인하십시오."
          },
          "reachable_rails": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "INTERNAL",
                "TRP",
                "GTR",
                "TRUST",
                "VERIFYVASP",
                "SYGNA",
                "EMAIL"
              ]
            },
            "description": "엔트리에 기록된 레일입니다. 현재 애플리케이션에서 사용할 수 있는 항목은 경로를 확인하십시오."
          },
          "is_didit_customer": {
            "type": "boolean",
            "description": "Didit 네트워크 멤버(이들의 경우 dd_status는 항상 COMPLETED이고 dd_score는 null이며 risk_level은 비어 있음) 및 Didit 고객과 연결된 디렉터리 항목의 경우 true입니다."
          },
          "dd_score_breakdown": {
            "type": "object",
            "description": "dd_score의 각 구성 요소당 하나의 객체입니다. 구성 요소, 가중치(최대) 및 사유 코드: jurisdiction, 25(jurisdiction_not_high_risk, jurisdiction_high_risk, jurisdiction_unknown), verification, 15(dd_status_completed, dd_status_in_progress, dd_status_not_started, dd_status_rejected), protocol, 15(native_rail, email_only, no_rail), lei, 10(lei_valid, lei_missing), history, 10(history, no_history), essentials, 15(essential_checks, no_essential_checks), responsiveness, 10(responsive, unresponsive, responsiveness_unknown). Didit 네트워크 멤버의 경우 비어 있습니다.",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "points": {
                  "type": "number",
                  "description": "컴포넌트가 기여한 점수로, 소수점 첫째 자리로 반올림됩니다."
                },
                "max": {
                  "type": "integer",
                  "description": "컴포넌트의 가중치입니다. 최대 기여 점수를 나타냅니다."
                },
                "reason": {
                  "type": "string",
                  "description": "구성 요소 판정의 기계 판독 가능한 코드."
                },
                "detail": {
                  "type": "string",
                  "description": "한 줄로 된 영어 설명입니다."
                }
              }
            }
          },
          "dd_assessed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "dd_score, risk_level, responsiveness가 마지막으로 계산된 시점: 항목과의 교환이 완료, 종료, 만료, 불일치 또는 거부된 후, Didit이 항목을 새로고침하거나 큐레이션할 때, 그리고 주간 디렉터리 새로고침 시입니다. Didit 네트워크 멤버인 경우 null입니다."
          },
          "dd_score_semantic": {
            "type": "string",
            "enum": [
              "higher_is_safer"
            ],
            "description": "dd_score가 가리키는 방향: 항상 higher_is_safer입니다."
          },
          "risk_level": {
            "type": "string",
            "enum": [
              "LOW",
              "MEDIUM",
              "HIGH",
              ""
            ],
            "description": "dd_score가 속하는 범위: LOW(70 이상), MEDIUM(40~69) 또는 HIGH(40 미만)입니다. Didit 네트워크 멤버 및 아직 평가되지 않은 항목의 경우 비어 있습니다. risk로 이를 필터링할 수 있습니다. 직접 플래그를 지정한 스크리닝은 이 공유 값을 변경하지 않으며, 대신 규칙에서 counterparty_risk_level을 HIGH로 만듭니다."
          },
          "responsiveness": {
            "type": "object",
            "description": "VASP의 Travel Rule 요청 응답 여부: 지난 90일 동안 Didit 고객이 해당 VASP를 대상으로 시작한 요청 중 VASP가 응답한 비율입니다. 네트워크나 프로토콜 레일을 통해 전송되었거나, 공유 주소(항목의 컴플라이언스 주소 또는 플랫폼 연락처)로 이메일 전송된 요청만 집계에 포함됩니다. 고객이 직접 입력한 주소나 고객의 개인 연락처로 전송된 요청은 포함되지 않습니다. 만료된 요청은 미응답으로 처리되며, 완료된 교환, 거부 또는 데이터 불일치는 응답으로 처리됩니다. 취소된 요청이나 도달할 수 없는 레일은 어느 쪽에도 해당하지 않습니다. Didit 네트워크 멤버의 경우 항상 카운트가 0인 UNKNOWN입니다.",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "RESPONSIVE",
                  "UNRESPONSIVE",
                  "UNKNOWN"
                ],
                "description": "해당 기간 내 결정된 요청이 5개 미만인 경우 UNKNOWN, 그중 응답된 요청이 10퍼센트 미만인 경우 UNRESPONSIVE, 그 외의 경우 RESPONSIVE입니다."
              },
              "answered": {
                "type": "integer",
                "description": "해당 기간 동안 VASP가 응답하여 결정이 완료된 요청입니다."
              },
              "total": {
                "type": "integer",
                "description": "해당 기간 동안 결정이 완료된 요청(응답 완료 및 만료 포함)입니다."
              },
              "computed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          },
          "essential_checks": {
            "type": "object",
            "description": "플랫폼의 검증된 출처만으로 생성된 디렉터리 항목의 필수 검사 보고서입니다: 등록(EU의 임시 MiCA 등록부, 공개 TRISA 디렉터리 또는 글로벌 LEI 등록부 등 공식 등록부에 VASP가 등재되어 있는지 여부), 라이선스(MiCA 인가가 기록되어 있고 유효한지 여부), 도메인(해당 항목의 도메인이 TRP endpoint 또는 등록부에 기재된 웹사이트와 일치하는지 여부), LEI(LEI 기록이 활성 상태이고 발급되었으며 항목의 명칭 및 국가와 일치하는지 여부). dd_score의 필수 구성 요소는 판정이 완료된 검사 중 통과된 비율입니다. 주간 디렉터리 갱신을 통해 해당 항목이 처음 검사될 때까지 비어 있으며, Didit 네트워크 멤버의 경우 항상 비어 있습니다.",
            "properties": {
              "level": {
                "type": "string",
                "enum": [
                  "essential"
                ]
              },
              "checked_at": {
                "type": "string",
                "format": "date-time"
              },
              "checks": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "enum": [
                        "registration",
                        "licence",
                        "domain",
                        "lei"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pass",
                        "fail",
                        "unknown"
                      ],
                      "description": "등록된 출처 중 검사 결과를 결정할 수 있는 출처가 없을 때 unknown입니다."
                    },
                    "reason": {
                      "type": "string",
                      "description": "판정의 기계 판독 가능한 코드."
                    },
                    "detail": {
                      "type": "string",
                      "description": "한 줄로 된 영어 설명입니다."
                    }
                  }
                }
              },
              "passed": {
                "type": "integer"
              },
              "failed": {
                "type": "integer"
              },
              "unknown": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              }
            }
          },
          "decision": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleCounterpartyDecision"
              }
            ],
            "nullable": true,
            "description": "해당 VASP에 대한 귀하 애플리케이션의 결정이며, 자체 결정이 없는 엔티티의 경우 해당 브랜드의 결정(inherited_from에 브랜드 이름 명시)을 따릅니다. 없는 경우 null입니다. 귀하의 애플리케이션에만 비공개로 유지됩니다."
          },
          "entity_screening": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleCounterpartyScreening"
              }
            ],
            "nullable": true,
            "description": "해당 VASP에 대한 귀하 애플리케이션의 최근 제재 및 부정적 언론 보도 스크리닝 결과입니다. 스크리닝한 적이 없으면 null입니다. 귀하의 애플리케이션에만 비공개로 유지됩니다."
          },
          "questionnaires": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TravelRuleCounterpartyQuestionnaire"
            },
            "description": "해당 VASP와의 실사 설문지로, 최신순으로 정렬됩니다. 귀하의 애플리케이션에만 비공개로 유지됩니다."
          }
        },
        "example": {
          "id": "0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91",
          "kind": "directory",
          "name": "Example Counterparty VASP",
          "lei": "529900EXAMPLECPTY001",
          "jurisdiction": "DE",
          "domains": [
            "counterparty.example"
          ],
          "reachable": true,
          "aliases": [
            {
              "name": "Example Counterparty",
              "kind": "trading_name"
            }
          ],
          "networks": [
            {
              "network": "GTR",
              "code": "EXAMPLE01",
              "listed_name": "Example Counterparty VASP",
              "country": "DE",
              "verified_at": "2026-10-12T09:30:00Z",
              "last_seen_at": "2026-10-12T09:30:00Z",
              "source": "staff"
            }
          ],
          "routes": [
            {
              "rail": "GTR",
              "status": "unavailable",
              "reason": "no_membership",
              "via": ""
            },
            {
              "rail": "EMAIL",
              "status": "available",
              "reason": "",
              "via": "contact"
            }
          ],
          "umbrella": null,
          "entities": [],
          "contacts": [
            {
              "id": "6c1f9b8e-2d4a-4f7e-8b3c-5a9d0e1f2a3b",
              "email": "travelrule@counterparty.example",
              "name": "Travel Rule desk",
              "source": "staff",
              "scope": "platform",
              "verified_at": null
            }
          ],
          "dd_status": "NOT_STARTED",
          "dd_score": 62,
          "dd_score_breakdown": {
            "jurisdiction": {
              "points": 25.0,
              "max": 25,
              "reason": "jurisdiction_not_high_risk",
              "detail": "DEU is not on the high-risk jurisdiction list"
            },
            "verification": {
              "points": 3.8,
              "max": 15,
              "reason": "dd_status_not_started",
              "detail": "due diligence status NOT_STARTED"
            },
            "protocol": {
              "points": 6.0,
              "max": 15,
              "reason": "email_only",
              "detail": "reachable over the email fallback only"
            },
            "lei": {
              "points": 10.0,
              "max": 10,
              "reason": "lei_valid",
              "detail": "valid LEI on record"
            },
            "history": {
              "points": 5.0,
              "max": 10,
              "reason": "no_history",
              "detail": "no exchange history"
            },
            "essentials": {
              "points": 7.5,
              "max": 15,
              "reason": "no_essential_checks",
              "detail": "no decided essential check yet"
            },
            "responsiveness": {
              "points": 5.0,
              "max": 10,
              "reason": "responsiveness_unknown",
              "detail": "0 decided recent requests, too few to judge"
            }
          },
          "dd_assessed_at": "2026-10-12T09:30:00Z",
          "dd_score_semantic": "higher_is_safer",
          "risk_level": "MEDIUM",
          "responsiveness": {
            "status": "UNKNOWN",
            "answered": 0,
            "total": 0,
            "computed_at": "2026-10-12T09:30:00Z"
          },
          "essential_checks": {},
          "reachable_rails": [
            "GTR",
            "EMAIL"
          ],
          "is_didit_customer": false,
          "decision": {
            "decision": "APPROVED",
            "reason": "Licensed in DE, questionnaire reviewed",
            "decided_by": "",
            "updated_at": "2026-10-14T10:05:00Z",
            "inherited_from": null
          },
          "entity_screening": {
            "id": "7a1d2c3b-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
            "status": "Approved",
            "total_hits": 0,
            "score": null,
            "screened_at": "2026-10-14T09:58:00Z",
            "fresh": true,
            "flagged": false
          },
          "questionnaires": [
            {
              "id": "8b7a6c5d-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
              "status": "ANSWERED",
              "form_version": "1",
              "sent_to": "travelrule@counterparty.example",
              "sent_at": "2026-09-02T08:00:00Z",
              "expires_at": "2026-10-02T08:00:00Z",
              "answered_at": "2026-09-04T15:20:00Z",
              "valid_until": "2027-09-04T15:20:00Z",
              "current": true,
              "answers": {
                "legal_name": "Example Counterparty VASP, incorporated in the example jurisdiction.",
                "licensing": "Crypto-asset service provider authorised under MiCA by its national regulator, licence active.",
                "jurisdictions": "EU and EEA. We do not serve the United States.",
                "aml_program": "Written AML/CFT policy, annual independent review, last completed in March 2026.",
                "compliance_officer": "Head of Compliance, reachable at compliance@counterparty.example.",
                "sanctions_screening": "Customers at onboarding and daily; counterparties on every transfer.",
                "transaction_monitoring": "Rule-based monitoring with analyst review; suspicious activity reports filed with the FIU.",
                "travel_rule": "TRP and email; we answer requests within one business day.",
                "custody": "Segregated customer wallets held with a qualified custodian, insured.",
                "ownership": "No shareholder holds 25 percent or more; parent company Example Holding Group.",
                "record_keeping": "Five-year record-keeping for Travel Rule and transaction data, as our regulator requires.",
                "data_protection": "Encrypted at rest and in transit, stored in the EU."
              }
            }
          ]
        }
      },
      "TravelRuleCounterpartyDecision": {
        "type": "object",
        "description": "거래 상대방 VASP에 대한 귀하 애플리케이션의 결정입니다. 귀하의 애플리케이션에만 비공개로 유지됩니다. 공유 디렉터리 항목을 절대 변경하지 않으며 다른 고객에게 표시되지 않습니다. 오직 귀하의 거래 규칙(counterparty_dd_status 규칙 필드 및 travel-rule-counterparty-blocked, travel-rule-counterparty-restricted 프리셋)을 통해서만 작동하며, 전송 라우팅 방식은 절대 변경하지 않습니다.",
        "properties": {
          "decision": {
            "type": "string",
            "enum": [
              "APPROVED",
              "RESTRICTED",
              "BLOCKED"
            ],
            "description": "APPROVED: 귀하의 팀이 거래 상대방을 승인했습니다. RESTRICTED: 검토 후 해당 상대방으로의 전송이 진행될 수 있습니다. BLOCKED: 귀하의 팀이 거부했습니다."
          },
          "reason": {
            "type": "string",
            "maxLength": 255,
            "description": "입력한 자유 형식 사유이며, 없는 경우 비어 있습니다."
          },
          "decided_by": {
            "type": "string",
            "description": "결정을 내렸거나 마지막으로 변경한 콘솔 사용자입니다. API 키가 결정한 경우 비어 있습니다."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "inherited_from": {
            "type": "object",
            "nullable": true,
            "description": "엔터티 자체에 대해 결정을 내리지 않아 이 엔터티가 따르는 결정을 내린 브랜드입니다. 결정이 거래 상대방 자체의 결정인 경우 null입니다.",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            }
          }
        }
      },
      "TravelRuleCounterpartyDecisionResponse": {
        "type": "object",
        "properties": {
          "decision": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleCounterpartyDecision"
              }
            ],
            "nullable": true,
            "description": "애플리케이션의 거래 상대방에게 적용되는 결정입니다. 자체 결정이며, 자체 결정이 없고 거래 상대방이 브랜드의 엔터티인 경우에는 해당 브랜드의 결정입니다. 없는 경우 null입니다."
          }
        }
      },
      "TravelRuleCounterpartyDecisionRequest": {
        "type": "object",
        "required": [
          "decision"
        ],
        "properties": {
          "decision": {
            "type": "string",
            "enum": [
              "APPROVED",
              "RESTRICTED",
              "BLOCKED"
            ]
          },
          "reason": {
            "type": "string",
            "maxLength": 255,
            "description": "선택 사항입니다. 이전 사유를 대체하며, 지우려면 생략하세요."
          }
        }
      },
      "TravelRuleCounterpartyScreening": {
        "type": "object",
        "description": "귀하의 애플리케이션을 위해 실행되고 비용이 청구된 거래 상대방 엔터티의 제재 및 부정적 언론 보도 스크리닝 1건입니다. 귀하의 애플리케이션에만 비공개로 유지되며, 다른 고객에게는 절대 표시되지 않습니다.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "In Review",
              "Declined"
            ],
            "description": "승인됨: 주의가 필요한 일치 가능성이 없습니다. 검토 중 또는 거부됨: 잠재적 제재 또는 부정적 언론 보도 일치 항목이 있습니다."
          },
          "total_hits": {
            "type": "integer",
            "description": "스크리닝에서 반환된 일치 가능 항목 수입니다."
          },
          "score": {
            "type": "number",
            "nullable": true,
            "description": "가능한 일치 항목 중 가장 높은 위험 점수입니다. 일치하는 항목이 없으면 null입니다."
          },
          "screened_at": {
            "type": "string",
            "format": "date-time"
          },
          "fresh": {
            "type": "boolean",
            "description": "스크리닝이 fresh_days(30일)보다 최신인지 여부입니다. 최신 스크리닝은 다시 청구되지 않고 재사용됩니다."
          },
          "flagged": {
            "type": "boolean",
            "description": "스크리닝이 최신 상태이고 상태가 검토 중(In Review) 또는 거부됨(Declined)인 동안 true입니다. 최신 스크리닝에 플래그가 지정되어 있고 거래 상대방 스크리닝이 켜져 있는 동안 귀하의 규칙에서 counterparty_risk_level은 HIGH입니다."
          }
        }
      },
      "TravelRuleCounterpartyScreeningStatus": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "귀하의 counterparty_screening_enabled Travel Rule 설정입니다. 기본값은 비활성화이며, 비활성화된 동안에는 아무것도 스크리닝되거나 결제 청구되지 않습니다."
          },
          "price": {
            "type": "string",
            "description": "USD 단위의 십진수 문자열: 귀하의 조직에 부과되는 1회 스크리닝 비용(기업 AML 스크리닝 가격)입니다."
          },
          "fresh_days": {
            "type": "integer",
            "description": "스크리닝 결과가 유효한 상태로 유지되어 재사용되는 일수입니다."
          },
          "screening": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleCounterpartyScreening"
              }
            ],
            "nullable": true,
            "description": "거래 상대방에 대한 귀하의 최근 스크리닝 결과입니다. 스크리닝을 진행한 적이 없는 경우 null입니다."
          }
        }
      },
      "TravelRuleCounterpartyScreeningRequest": {
        "type": "object",
        "properties": {
          "refresh": {
            "type": "boolean",
            "default": false,
            "description": "true이면 유효한 최신 스크리닝이 있더라도 다시 스크리닝합니다(요금도 다시 청구됩니다)."
          }
        }
      },
      "TravelRuleCounterpartyScreeningResult": {
        "type": "object",
        "properties": {
          "outcome": {
            "type": "string",
            "enum": [
              "screened",
              "reused"
            ],
            "description": "screened: 새로운 스크리닝이 실행되고 청구되었습니다(201). reused: 유효한 최신 스크리닝이 반환되었으며 청구되지 않았습니다(200)."
          },
          "screening": {
            "$ref": "#/components/schemas/TravelRuleCounterpartyScreening"
          }
        }
      },
      "TravelRuleCounterpartyQuestionnaire": {
        "type": "object",
        "description": "애플리케이션이 거래 상대방에게 전송한 실사 설문지 1개입니다. 기록된 컴플라이언스 주소로 일회용 응답 링크와 함께 이메일로 전송되는 Didit 표준 설문지이며, 애플리케이션에만 비공개로 유지됩니다.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "SENT",
              "ANSWERED",
              "EXPIRED"
            ],
            "description": "SENT: 답변 대기 중입니다. ANSWERED: 거래 상대방이 모든 질문에 답변했습니다. EXPIRED: 답변 링크가 답변되지 않은 상태로 닫혔거나(기한 초과 또는 최신 설문지로 대체됨) 답변이 valid_until을 지났습니다."
          },
          "form_version": {
            "type": "string",
            "description": "답변이 속한 Didit 표준 설문지의 버전입니다. 현재는 1입니다."
          },
          "sent_to": {
            "type": "string",
            "format": "email"
          },
          "sent_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "전송 후 30일인 답변 마감일입니다. 마감일 이후에는 링크가 작동하지 않습니다."
          },
          "answered_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "valid_until": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "답변이 최신 상태로 유지되는 기간입니다. 답변 후 365일입니다. 답변하기 전까지는 null입니다."
          },
          "current": {
            "type": "boolean",
            "description": "설문지가 ANSWERED 상태이고 valid_until이 지나지 않은 동안 true입니다."
          },
          "answers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "질문 ID별 답변입니다: legal_name, licensing, jurisdictions, aml_program, compliance_officer, sanctions_screening, transaction_monitoring, travel_rule, custody, ownership, record_keeping, data_protection. 각 답변은 최대 2,000자입니다. 답변하기 전까지는 비어 있습니다."
          }
        }
      },
      "TravelRuleCounterpartyQuestionnaireRequest": {
        "type": "object",
        "properties": {
          "sent_to": {
            "type": "string",
            "format": "email",
            "description": "선택 사항입니다. 거래 상대방에 대해 기록된 컴플라이언스 주소입니다. 디렉터리 항목의 경우 컴플라이언스 주소 또는 애플리케이션에 표시되는 연락처이며, Didit 네트워크 멤버의 경우 확인된 컴플라이언스 이메일입니다. 기본값: 거래 상대방에게 전송되는 Travel Rule 이메일의 수신 주소(자체 연락처 우선, 그다음 플랫폼 연락처, 마지막으로 항목의 컴플라이언스 주소)."
          }
        }
      },
      "TravelRuleCounterpartyQuestionnaireList": {
        "type": "object",
        "properties": {
          "questionnaires": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TravelRuleCounterpartyQuestionnaire"
            },
            "description": "최신순입니다."
          }
        }
      },
      "TravelRulePickupInfo": {
        "type": "object",
        "description": "거래 상대방의 응답 페이지에 표시되는, 이메일로 전송된 수령 링크 뒤의 대기 중인 교환입니다.",
        "properties": {
          "reference": {
            "type": "string",
            "format": "uuid",
            "description": "송금 VASP 콘솔에 표시되는 전송의 uuid입니다."
          },
          "requested_at": {
            "type": "string",
            "format": "date-time"
          },
          "originator_vasp_name": {
            "type": "string"
          },
          "originator_vasp_lei": {
            "type": "string"
          },
          "recipient_vasp_name": {
            "type": "string",
            "description": "요청 대상인 거래 상대방 VASP입니다."
          },
          "language": {
            "type": "string",
            "description": "거래 상대방의 관할권에 따른 요청 이메일 및 응답 페이지의 언어입니다."
          },
          "amount": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "fiat_amount": {
            "type": "string",
            "description": "송금인이 제공한 변환된 값 또는 빈 값입니다."
          },
          "fiat_currency": {
            "type": "string"
          },
          "chain": {
            "type": "string"
          },
          "beneficiary_wallet": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "ivms_version": {
            "type": "string"
          },
          "deadline_at": {
            "type": "string",
            "format": "date-time",
            "description": "링크의 응답이 중단되는 시점입니다."
          },
          "reminders_sent": {
            "type": "integer"
          },
          "contact": {
            "type": "string",
            "description": "링크의 `?contact=` 값으로 그대로 반환됩니다. 링크에 해당 값이 없으면 비어 있습니다."
          },
          "decline_reasons": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "data_mismatch",
                "not_our_customer",
                "wallet_not_hosted",
                "sanctions",
                "risk_appetite",
                "jurisdiction",
                "insufficient_data",
                "other"
              ]
            },
            "description": "`decline_reason`에 허용되는 값입니다."
          },
          "join_invitation": {
            "type": "object",
            "description": "거래 상대방이 Didit에 무료로 가입할 수 있는 유효한 초대를 보유하고 있는지 여부입니다. 초대 링크는 초대된 주소로 발송되는 이메일로만 전달되므로 여기에서 `url`은 비어 있습니다.",
            "properties": {
              "eligible": {
                "type": "boolean"
              },
              "url": {
                "type": "string"
              }
            }
          },
          "originator_data": {
            "type": "object",
            "description": "송금 VASP가 공유하는 송금인 필드입니다(`data_sharing_fields`). 이름과 지갑은 항상 포함됩니다."
          },
          "beneficiary_data": {
            "type": "object"
          },
          "ivms_request": {
            "type": "object",
            "description": "IVMS 101 객체와 동일한 요청입니다. `data_masked`가 true인 동안에는 생략됩니다."
          },
          "data_masked": {
            "type": "boolean",
            "description": "이 endpoint에서는 항상 false입니다. 이메일 요청은 아웃바운드이며, 발신자 본인의 사용자는 마스킹되지 않습니다."
          }
        }
      },
      "TravelRulePickupRespondRequest": {
        "type": "object",
        "required": [
          "decision"
        ],
        "properties": {
          "decision": {
            "type": "string",
            "enum": [
              "accept",
              "decline"
            ]
          },
          "beneficiary_name": {
            "type": "string",
            "description": "기록에 보관된 수취인 이름으로, 송금 VASP의 이름 규칙을 통과한 값입니다. 수취인 이름이 지정된 경우 `ivms_response`가 우선합니다.",
            "maxLength": 255
          },
          "decline_reason": {
            "type": "string",
            "enum": [
              "",
              "data_mismatch",
              "not_our_customer",
              "wallet_not_hosted",
              "sanctions",
              "risk_appetite",
              "jurisdiction",
              "insufficient_data",
              "other"
            ],
            "description": "거부하는 이유입니다. 송신 VASP의 전송 타임라인에 기록됩니다. 사유를 제공하지 않은 경우 비어 있습니다(기본값)."
          },
          "decline_detail": {
            "type": "string",
            "maxLength": 512,
            "description": "자유 형식 텍스트입니다. `decision`이 `decline`이고 `decline_reason`이 `other`일 때 필수입니다."
          },
          "ivms_response": {
            "type": "object",
            "description": "귀하의 전체 IVMS 101 응답입니다. 해당 수취인 이름이 `beneficiary_name`보다 우선 적용됩니다."
          },
          "contact": {
            "type": "string",
            "format": "uuid",
            "description": "링크의 `?contact=` 값에서 가져온, 링크가 전송된 연락처입니다. 본문에서 생략된 경우 `contact` 쿼리 파라미터가 사용됩니다."
          }
        }
      },
      "TravelRuleInboundRequest": {
        "type": "object",
        "required": [
          "chain",
          "txid",
          "wallet_address",
          "amount",
          "currency"
        ],
        "properties": {
          "chain": {
            "type": "string",
            "description": "입금이 정산된 체인(예: `ETH`). 소문자로 저장되며 지갑 주소록 항목과 대소문자를 구분하지 않고 비교되므로, 주소록에서도 동일한 체인 token을 사용하십시오.",
            "maxLength": 32
          },
          "txid": {
            "type": "string",
            "description": "온체인 거래 해시입니다. wallet_address와 함께 중복 제거됩니다.",
            "maxLength": 128
          },
          "wallet_address": {
            "type": "string",
            "description": "입금을 수령한 대상 지갑입니다. XRP X-address는 기본 클래식 주소와 태그로 분리됩니다.",
            "maxLength": 128
          },
          "amount": {
            "type": "string",
            "description": "0 이상, 소수점 이하 최대 18자리의 10진수 문자열로 표시된 입금 금액입니다."
          },
          "currency": {
            "type": "string",
            "description": "입금 자산(예: \"USDC\")입니다.",
            "maxLength": 16
          },
          "originator_data": {
            "type": "object",
            "description": "알려진 경우 발송 VASP의 송금인 세부 정보이며, `{\"name\": \"...\"}`와 같은 평면 객체입니다. Didit은 여기에서 name(또는 full_name), first_name, last_name 및 vendor_data를 읽습니다.",
            "additionalProperties": true
          },
          "beneficiary_data": {
            "type": "object",
            "description": "`{\"name\": \"...\"}`와 같은 단일 계층 객체 형태의 수취인 세부 정보(귀사 고객)입니다. Didit은 일치하는 주소록 항목의 holder_name과 name을 대조하고, 요청에 따라 wallet_address 및 chain을 설정합니다.",
            "additionalProperties": true
          },
          "originating_vasp": {
            "type": "object",
            "description": "송금 VASP에 대한 선택적 설명입니다. 이 전송에만 유지되며(`metadata.originating_vasp`, 그리고 GET /v3/travel-rule/transfers/의 해당 전송의 송금인 VASP), 공유 VASP 디렉터리 항목을 생성, 수정 또는 연결하지 않습니다.",
            "properties": {
              "name": {
                "type": "string",
                "maxLength": 255
              },
              "lei": {
                "type": "string",
                "maxLength": 20,
                "description": "선택 사항입니다. 유효한 20자 ISO 17442 LEI 또는 빈 값입니다."
              },
              "travel_address": {
                "type": "string",
                "description": "이번 전송 건에 기록된 송금인의 Travel Address입니다.",
                "maxLength": 512
              }
            }
          },
          "memo": {
            "type": "string",
            "maxLength": 256,
            "description": "선택 사항입니다. 메모 네트워크에서의 입금 대상 데스티네이션 태그 또는 메모입니다. 공유 입금 주소에서 고객을 구분하는 기준이 되며, 해당 메모에 대한 주소록 항목과 일치합니다. XRP: 데스티네이션 태그, 0에서 4294967295 사이의 정수(JSON 숫자 허용). XLM: 최대 28바이트의 텍스트 메모, 64비트 ID 또는 16진수 32바이트 해시. EOS: 최대 256바이트. ATOM: 최대 256자. HBAR: 최대 100바이트. Bitcoin, EVM, Solana, Tron, Litecoin, Bitcoin Cash, Dogecoin 및 Lightning 지갑은 메모를 받지 않으며, 입력 시 `400`이 반환됩니다. 별칭: `destinationTag` 또는 `destination_tag`."
          },
          "utxo": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleUtxo"
              }
            ],
            "description": "선택 사항이며 UTXO 체인 전용입니다. 입금 거래의 입력 및 출력입니다. 보낸 사람의 지갑은 선언된 `originator_data.wallet_address`이며, 그렇지 않은 경우 가장 큰 입력입니다."
          }
        }
      },
      "TravelRuleInboundResponse": {
        "type": "object",
        "properties": {
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "description": "인바운드 입금에 대한 Didit 거래 UUID입니다."
          },
          "txn_id": {
            "type": "string",
            "description": "인바운드 거래의 txn_id: Didit이 거래를 생성했을 때는 Didit 생성 ID, 클레임되지 않은 입금이 재사용되었을 때는 자체 ID입니다."
          },
          "created": {
            "type": "boolean",
            "description": "이 호출로 이체가 등록된 경우(HTTP 201) true, 동일한 txid 및 wallet_address에 대한 이체가 이미 존재하는 경우(HTTP 200) false입니다."
          },
          "travel_rule": {
            "$ref": "#/components/schemas/TravelRuleTransferDetail"
          }
        }
      },
      "TravelRuleTestVaspInboundRequest": {
        "type": "object",
        "required": [
          "beneficiary_wallet_address"
        ],
        "properties": {
          "beneficiary_wallet_address": {
            "type": "string",
            "description": "대상 지갑 주소입니다. Didit Test VASP가 해당 자산의 블록체인상에 있는 회원님의 지갑 주소록과 대조하여 이 주소로 전송합니다. 일치하는 항목이 없는 지갑은 허용되며 수신 거래는 ON_HOLD로 처리됩니다."
          },
          "scenario": {
            "type": "string",
            "enum": [
              "accept",
              "name_mismatch"
            ],
            "default": "accept",
            "description": "Didit Test VASP가 수취인으로 신고하는 내용입니다. `accept`는 소유자 본인의 이름을 신고하며, `name_mismatch`는 어떤 소유자도 동의하지 않는 이름을 신고합니다. 결정 자체는 항상 귀하의 몫입니다."
          },
          "chain": {
            "type": "string",
            "default": "ETH",
            "description": "자산의 체인."
          },
          "amount": {
            "type": "string",
            "default": "1",
            "description": "십진수 문자열 형태의 금액입니다."
          },
          "currency": {
            "type": "string",
            "default": "ETH",
            "description": "자산 코드입니다."
          },
          "reference": {
            "type": "string",
            "description": "선택적 멱등성 키입니다. 동일한 값으로 반복 호출하면 첫 번째 호출에서 예약한 이체를 반환합니다."
          }
        }
      },
      "TravelRuleTestVaspInboundResponse": {
        "type": "object",
        "properties": {
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "description": "인바운드 이체에 대한 Didit 거래 UUID입니다."
          },
          "txn_id": {
            "type": "string",
            "description": "Didit에서 생성된 txn_id입니다."
          },
          "scenario": {
            "type": "string",
            "description": "실행된 시나리오입니다."
          },
          "travel_rule_status": {
            "type": "string",
            "description": "애플리케이션 자체의 결정으로 확정된 상태입니다."
          },
          "detail": {
            "type": "string",
            "description": "전송이 해당 상태로 처리된 이유입니다."
          },
          "test_vasp": {
            "type": "boolean",
            "description": "항상 true입니다. 발신자는 Didit Test VASP였습니다."
          },
          "travel_rule": {
            "$ref": "#/components/schemas/TravelRuleTransferDetail"
          }
        }
      },
      "TravelRuleWidgetSessionCreate": {
        "type": "object",
        "properties": {
          "wallet_address": {
            "type": "string",
            "description": "검증할 지갑 주소입니다. 선택 사항이며, 비어 있는 경우 증명을 시작할 때 주소를 제공해야 합니다.",
            "maxLength": 128
          },
          "chain": {
            "type": "string",
            "description": "해당 주소의 체인 token(예: `ETH`, `BTC` 또는 `SOL`)입니다. 지갑 주소록에서 사용하는 것과 동일한 token을 사용하십시오. 메시지 서명 및 사토시 테스트는 지원되는 체인에 대해서만 제공됩니다. 증명이 검증하는 주소록 항목은 표준 식별자(ETH, BTC, SOL, TRX)로 이를 저장합니다.",
            "maxLength": 32
          },
          "holder_name": {
            "type": "string",
            "description": "수취인 이름 대조에 사용되는 지갑 보유자 이름입니다.",
            "maxLength": 255
          },
          "vendor_data": {
            "type": "string",
            "description": "보유자에 대한 귀하의 내부 식별자이며, 생성된 주소록 항목으로 전달됩니다.",
            "maxLength": 255
          },
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "description": "선택 사항입니다. 증명이 검증될 때 진행할 Travel Rule 전송의 Didit 거래 UUID입니다.",
            "nullable": true
          },
          "satoshi_deposit_address": {
            "type": "string",
            "description": "선택 사항입니다. 귀하가 관리하는 입금 주소이며, 이를 제공하면 SATOSHI_TEST 증명 방법이 활성화됩니다.",
            "maxLength": 128
          },
          "callback_url": {
            "type": "string",
            "description": "선택 사항입니다. 완료 후 위젯이 고객을 리디렉션할 절대 http(s) URL입니다.",
            "maxLength": 512
          },
          "expires_in_minutes": {
            "type": "integer",
            "description": "선택 사항입니다. 발급된 링크의 유효 기간(분 단위)입니다. SATOSHI_TEST가 제공되는 경우 사토시 테스트 기간을 포함하도록 자동으로 연장됩니다.",
            "default": 60,
            "minimum": 5,
            "maximum": 10080
          }
        }
      },
      "TravelRuleWidgetSessionResponse": {
        "type": "object",
        "properties": {
          "widget_session_id": {
            "type": "string",
            "format": "uuid"
          },
          "token": {
            "type": "string",
            "description": "위젯 URL에 포함된 불투명 세션 token입니다."
          },
          "url": {
            "type": "string",
            "description": "호스팅 지갑 소유권 위젯 URL입니다. 시스템 브라우저에서 그대로 엽니다(모바일 SDK 웹뷰 내에서는 절대 열지 마세요)."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TravelRuleWidgetContext": {
        "type": "object",
        "properties": {
          "vasp_name": {
            "type": "string",
            "description": "VASP 프로필의 법인명으로, 위젯에서 고객에게 표시됩니다. 프로필이 없으면 비어 있습니다."
          },
          "wallet_address": {
            "type": "string"
          },
          "chain": {
            "type": "string",
            "description": "전송한 그대로 세션이 발행된 체인입니다."
          },
          "chain_family": {
            "type": "string",
            "nullable": true,
            "enum": [
              "EVM",
              "BTC",
              "SOL",
              "TRON",
              null
            ],
            "description": "체인에 사용되는 키 제품군입니다. EVM(Ethereum, BNB Chain, Polygon, Arbitrum, Base, Optimism, Avalanche, Linea 및 기타 EVM 체인), BTC, SOL 또는 TRON입니다. 하나의 EVM 키가 모든 EVM 체인에서 동일한 주소를 제어합니다. 체인에서 서명을 검증할 수 없는 경우 null입니다."
          },
          "holder_name": {
            "type": "string"
          },
          "allowed_methods": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "MESSAGE_SIGNING",
                "SCREENSHOT",
                "SATOSHI_TEST",
                "SELF_DECLARATION"
              ]
            },
            "description": "이 세션에서 사용 가능한 증명 방법입니다. MESSAGE_SIGNING에는 chain_family가 있는 체인이 필요하고, SATOSHI_TEST에는 세션의 satoshi_deposit_address 및 Didit이 입금을 다시 읽을 수 있는 체인이 필요하며, SCREENSHOT에는 allow_screenshot_proof 설정이 필요하고, SELF_DECLARATION에는 allow_self_declaration 설정이 필요합니다."
          },
          "transfer_status": {
            "type": "string",
            "nullable": true,
            "description": "연결된 Travel Rule 전송의 상태입니다. 세션이 transaction_id 없이 생성된 경우 null입니다."
          },
          "callback_url": {
            "type": "string",
            "description": "완료 후 위젯이 고객을 다시 보낼 위치입니다. 설정되지 않은 경우 비어 있습니다."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "증명이 검증되면 null이 아닙니다."
          },
          "proofs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TravelRuleWidgetProofSummary"
            }
          },
          "max_attempts": {
            "type": "integer",
            "description": "이 세션에서 허용하는 거부된 지갑 증명입니다."
          },
          "attempts_used": {
            "type": "integer",
            "description": "지금까지 거부된 증명입니다."
          },
          "attempts_remaining": {
            "type": "integer",
            "description": "0인 경우 다른 증명을 시작하면 409를 응답하며 새로운 위젯 세션을 생성합니다."
          },
          "customization": {
            "type": "object",
            "nullable": true,
            "description": "화이트 라벨이 활성화된 경우 애플리케이션의 화이트 라벨 맞춤 설정(색상, 로고, 글꼴 모음)입니다. 위젯은 인증 흐름과 동일한 브랜딩으로 렌더링됩니다. 그렇지 않은 경우 null입니다."
          }
        }
      },
      "TravelRuleWidgetProofSummary": {
        "type": "object",
        "properties": {
          "proof_id": {
            "type": "string",
            "format": "uuid"
          },
          "method": {
            "type": "string",
            "enum": [
              "MESSAGE_SIGNING",
              "SATOSHI_TEST",
              "SCREENSHOT",
              "SELF_DECLARATION"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "VERIFIED",
              "REJECTED",
              "EXPIRED"
            ],
            "description": "PENDING: 최종 사용자가 이 방식을 선택했으며 증명이 아직 결정되지 않았습니다. 실패한 서명 또는 아직 읽을 수 없거나 확인되지 않은 테스트 입금은 failure_reason과 함께 증명을 PENDING 상태로 유지하므로 최종 사용자가 다시 시도할 수 있습니다. 제출된 SATOSHI_TEST 입금은 유효 기간이 닫힐 때까지 자동으로 재확인되며, 제출된 SCREENSHOT은 검토를 대기합니다. VERIFIED: 소유권이 증명되었습니다. REJECTED: 테스트 입금이 확실히 잘못되었거나(다른 발신자, 입금 주소로 전송된 예상치 않은 금액, 챌린지보다 이전 시점, 또는 이미 다른 지갑을 증명한 거래) 검토자가 스크린샷을 거부했습니다. failure_reason에 구체적인 사유가 표시됩니다. 거부된 증명은 최종적이며 세션 시도 횟수 중 하나를 사용합니다. EXPIRED: 증명을 더 이상 결정할 수 없습니다(유효 기간 만료, 최종 사용자가 방식 변경, 위젯 세션 만료, 또는 지갑 보유자 변경). failure_reason에 구체적인 사유가 표시됩니다."
          },
          "wallet_address": {
            "type": "string"
          },
          "chain": {
            "type": "string",
            "description": "증명이 대상인 주소록 항목의 표준 체인 식별자입니다(예: ETH, BTC, SOL, TRX)."
          },
          "deposit_address": {
            "type": "string",
            "nullable": true,
            "description": "고객이 사토시 테스트 금액을 보내야 하는 입금 주소입니다. SATOSHI_TEST 증명에만 존재합니다."
          },
          "expected_amount": {
            "type": "string",
            "nullable": true,
            "description": "Satoshi 테스트 입금과 일치해야 하는 입금의 고유 통화로 표시된 정확한 온체인 금액입니다. SATOSHI_TEST 증명에만 존재합니다."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "해당 증명 자체의 사토시 테스트 기간 마감 시한입니다. SATOSHI_TEST 증명에만 존재하며, SATOSHI_TEST가 제공될 경우 위젯 세션 자체의 expires_at이 이를 포함하도록 연장됩니다."
          },
          "challenge": {
            "type": "string",
            "nullable": true,
            "description": "고객이 자신의 지갑으로 서명하는 Didit 발행 메시지입니다. MESSAGE_SIGNING 증명에만 존재합니다."
          },
          "rejection_reason": {
            "type": "string",
            "description": "증명이 거부된 이유(최종 사용자를 위한 영어 문장)입니다. `status`가 REJECTED일 때만 존재하며, 검토자가 스크린샷을 거부한 경우에는 비어 있습니다(검토자 메모는 외부에 공개되지 않음)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "attempts": {
            "type": "integer",
            "description": "이 증명을 위해 증빙 자료(서명, 거래 ID, 업로드)가 제출된 횟수입니다."
          },
          "failure_reason": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason"
              }
            ],
            "description": "마지막 시도가 실패한 이유 또는 증명이 종료된 이유입니다. 실패한 항목이 없으면 비어 있습니다."
          }
        }
      },
      "CaseSubject": {
        "type": "object",
        "nullable": true,
        "description": "케이스가 연결된 단일 사용자 또는 기업입니다.",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "user",
              "business"
            ]
          },
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "external_id": {
            "type": "string",
            "nullable": true,
            "description": "대상자의 vendor_data입니다."
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "주체의 3자리 국가 코드(ISO 3166-1 alpha-3)이며, 알 수 없는 경우 null입니다. 기업의 경우 법인 설립 국가입니다. 개인의 경우 인증에서 확인된 신분증의 발급 국가입니다. 여러 국가의 신분증을 보유한 개인은 그중 하나가 표시되며, `XXA`와 같은 ICAO 문서 코드가 나타날 수 있습니다.",
            "example": "ESP"
          },
          "portrait": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "해당 인물의 인물 사진 이미지에 대한 유효 기간이 짧은 서명된 URL입니다. 기업의 경우 항상 null이며, 인물 사진이 없는 개인의 경우에도 null입니다. URL이 만료되므로 URL을 저장하지 말고 케이스를 조회할 때 이미지를 다운로드하세요."
          }
        }
      },
      "CaseAssignee": {
        "type": "object",
        "nullable": true,
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "full_name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          }
        }
      },
      "CaseBlueprintSummary": {
        "type": "object",
        "nullable": true,
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "maxLength": 24
          }
        }
      },
      "CaseContentConfig": {
        "type": "object",
        "description": "케이스 페이지에 표시될 탭과 필드를 결정하는 6개의 토글 가능한 섹션입니다. 알 수 없는 섹션이나 키는 거부됩니다.",
        "properties": {
          "checklist": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "optional": {
                "type": "boolean",
                "description": "true인 경우, 체크리스트 항목이 완료되지 않아도 케이스를 해결할 수 있습니다."
              },
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string",
                      "maxLength": 255
                    },
                    "order": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "aml_control": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "financial": {
                "type": "boolean"
              },
              "identity": {
                "type": "boolean"
              }
            }
          },
          "identity": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "personal_information": {
                "type": "boolean"
              },
              "applicant_tags": {
                "type": "boolean"
              },
              "contact_information": {
                "type": "boolean"
              },
              "risk_overview": {
                "type": "boolean"
              },
              "poi_documents": {
                "type": "boolean"
              },
              "poa_documents": {
                "type": "boolean"
              }
            }
          },
          "verifications": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "summary": {
                "type": "boolean"
              }
            }
          },
          "reporting": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "fiu_reports": {
                "type": "boolean"
              }
            }
          },
          "financial": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "payment_methods": {
                "type": "boolean"
              },
              "transactions": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "CaseNote": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "comment": {
            "type": "string"
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "actor_name": {
            "type": "string",
            "nullable": true
          },
          "mentioned_emails": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            }
          },
          "is_internal": {
            "type": "boolean"
          },
          "attachments": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "s3_key": {
                  "type": "string"
                },
                "filename": {
                  "type": "string"
                },
                "file_size": {
                  "type": "integer"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CaseEvent": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "event_type": {
            "type": "string",
            "enum": [
              "CREATED",
              "STATUS_CHANGED",
              "ASSIGNED",
              "UNASSIGNED",
              "RESOLVED",
              "REOPENED",
              "LINK_ADDED",
              "LINK_REMOVED",
              "NOTE_ADDED",
              "NOTE_PINNED",
              "NOTE_UNPINNED",
              "PRIORITY_CHANGED",
              "DUE_DATE_CHANGED",
              "TAG_ADDED",
              "TAG_REMOVED",
              "ESCALATED",
              "TRANSFERRED",
              "CHECKLIST_COMPLETED",
              "REPORT_CREATED",
              "REPORT_FINALIZED",
              "SUBMITTED_FOR_APPROVAL",
              "APPROVAL_GRANTED",
              "APPROVAL_REJECTED",
              "ENTITY_ACTION",
              "APPROVAL_INVALIDATED",
              "CUSTOMER_REQUEST",
              "STAGE_CHANGED",
              "TEAM_CHANGED",
              "CHECKER_ASSIGNED",
              "CHECKER_UNASSIGNED"
            ]
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "actor_name": {
            "type": "string",
            "nullable": true
          },
          "previous_status": {
            "type": "string",
            "enum": [
              "OPEN",
              "AWAITING_USER",
              "RESOLVED"
            ],
            "nullable": true
          },
          "new_status": {
            "type": "string",
            "enum": [
              "OPEN",
              "AWAITING_USER",
              "RESOLVED"
            ],
            "nullable": true
          },
          "metadata": {
            "type": "object"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CaseLink": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "linked_entity_type": {
            "type": "string",
            "enum": [
              "session",
              "business_session",
              "transaction"
            ],
            "nullable": true
          },
          "linked_entity_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "linked_entity_summary": {
            "type": "object",
            "nullable": true,
            "description": "세션 및 business_session 링크의 경우 session_id/session_number/status, 거래 링크의 경우 uuid/txn_id/status입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CaseChecklistItem": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": "string",
            "maxLength": 255
          },
          "is_completed": {
            "type": "boolean"
          },
          "completed_by": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "order": {
            "type": "integer"
          }
        }
      },
      "CaseBlueprintListItem": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "maxLength": 24
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "assignment_method": {
            "type": "string",
            "enum": [
              "MANUAL",
              "AUTOMATIC"
            ]
          },
          "assignee_pool": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "max_active_cases": {
            "type": "integer",
            "nullable": true
          },
          "escalation_enabled": {
            "type": "boolean"
          },
          "transfer_enabled": {
            "type": "boolean"
          },
          "require_resolution_note": {
            "type": "boolean"
          },
          "is_active": {
            "type": "boolean"
          },
          "preset_key": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer",
            "readOnly": true
          },
          "default_deadline_hours": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 8760
          }
        }
      },
      "CaseBlueprintDetail": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "maxLength": 24
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "assignment_method": {
            "type": "string",
            "enum": [
              "MANUAL",
              "AUTOMATIC"
            ]
          },
          "assignee_pool": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "max_active_cases": {
            "type": "integer",
            "nullable": true
          },
          "escalation_enabled": {
            "type": "boolean"
          },
          "transfer_enabled": {
            "type": "boolean"
          },
          "require_resolution_note": {
            "type": "boolean"
          },
          "is_active": {
            "type": "boolean"
          },
          "preset_key": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "escalation_blueprint": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "escalation_blueprint_name": {
            "type": "string",
            "nullable": true
          },
          "four_eyes_checker_blueprint": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "four_eyes_checker_blueprint_name": {
            "type": "string",
            "nullable": true
          },
          "content_config": {
            "type": "object",
            "description": "케이스 페이지에 표시될 탭과 필드를 결정하는 6개의 토글 가능한 섹션입니다. 알 수 없는 섹션이나 키는 거부됩니다.",
            "properties": {
              "checklist": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "optional": {
                    "type": "boolean",
                    "description": "true인 경우, 체크리스트 항목이 완료되지 않아도 케이스를 해결할 수 있습니다."
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "label": {
                          "type": "string",
                          "maxLength": 255
                        },
                        "order": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              },
              "aml_control": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "financial": {
                    "type": "boolean"
                  },
                  "identity": {
                    "type": "boolean"
                  }
                }
              },
              "identity": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "personal_information": {
                    "type": "boolean"
                  },
                  "applicant_tags": {
                    "type": "boolean"
                  },
                  "contact_information": {
                    "type": "boolean"
                  },
                  "risk_overview": {
                    "type": "boolean"
                  },
                  "poi_documents": {
                    "type": "boolean"
                  },
                  "poa_documents": {
                    "type": "boolean"
                  }
                }
              },
              "verifications": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "summary": {
                    "type": "boolean"
                  }
                }
              },
              "reporting": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "fiu_reports": {
                    "type": "boolean"
                  }
                }
              },
              "financial": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "payment_methods": {
                    "type": "boolean"
                  },
                  "transactions": {
                    "type": "boolean"
                  }
                }
              }
            }
          },
          "creation_sources": {
            "type": "array",
            "description": "현재 새 케이스를 이 청사진으로 라우팅하는 커넥터입니다.",
            "items": {
              "type": "object",
              "properties": {
                "kind": {
                  "type": "string",
                  "enum": [
                    "aml",
                    "rule",
                    "workflow"
                  ]
                },
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "receives_escalation_from": {
            "type": "array",
            "description": "에스컬레이션 대상이 이 블루프린트를 가리키는 다른 블루프린트입니다.",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer",
            "readOnly": true
          },
          "default_deadline_hours": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 8760
          }
        }
      },
      "CaseListItem": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "case_number": {
            "type": "string",
            "nullable": true,
            "description": "자동 할당됨(예: CS-0001)."
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "OPEN",
              "AWAITING_USER",
              "RESOLVED"
            ]
          },
          "resolution": {
            "type": "string",
            "enum": [
              "FALSE_POSITIVE",
              "VALID_THREAT",
              "INCONCLUSIVE",
              "REQUIREMENTS_NOT_MET",
              "REQUIREMENTS_SATISFIED"
            ],
            "nullable": true
          },
          "pending_resolution": {
            "type": "object",
            "nullable": true,
            "description": "체커 블루프린트에서 승인 또는 거부 승인을 기다리며 4-eyes 해결 절차가 스테이징되는 동안에만 설정됩니다.",
            "properties": {
              "resolution": {
                "type": "string",
                "enum": [
                  "FALSE_POSITIVE",
                  "VALID_THREAT",
                  "INCONCLUSIVE",
                  "REQUIREMENTS_NOT_MET",
                  "REQUIREMENTS_SATISFIED"
                ]
              },
              "resolution_notes": {
                "type": "string",
                "nullable": true
              },
              "maker_email": {
                "type": "string",
                "format": "email",
                "nullable": true,
                "description": "결정을 제출한 담당자의 이메일입니다. API 키로 제출한 경우 null입니다. 해당 결정에는 기록된 작성자가 없으므로 모든 호출자에 대해 승인 및 승인 거부가 403을 반환합니다."
              },
              "maker_name": {
                "type": "string",
                "nullable": true
              },
              "maker_user_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true,
                "description": "해결 조치를 제출한 담당자의 멤버 사용자 uuid입니다. API 키가 제출한 경우 null입니다. 해당 멤버는 `checker`로 지정될 수 없습니다."
              },
              "maker_blueprint_id": {
                "type": "string",
                "format": "uuid"
              },
              "staged_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "checker": {
            "$ref": "#/components/schemas/CaseChecker"
          },
          "priority": {
            "type": "string",
            "enum": [
              "LOW",
              "MEDIUM",
              "HIGH"
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "MANUAL",
              "AML_SCREENING",
              "TRANSACTION_RULE",
              "WORKFLOW_BUILDER"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "subject": {
            "$ref": "#/components/schemas/CaseSubject"
          },
          "assigned_to": {
            "$ref": "#/components/schemas/CaseAssignee"
          },
          "assigned_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "team": {
            "$ref": "#/components/schemas/CaseTeamSummary"
          },
          "due_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "resolved_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_by_email": {
            "type": "string",
            "nullable": true
          },
          "created_by_name": {
            "type": "string",
            "nullable": true
          },
          "blueprint": {
            "$ref": "#/components/schemas/CaseBlueprintSummary"
          },
          "links_count": {
            "type": "integer"
          },
          "notes_count": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "application_id": {
            "type": "string",
            "format": "uuid"
          },
          "application_name": {
            "type": "string"
          },
          "organization_id": {
            "type": "string",
            "format": "uuid"
          },
          "organization_name": {
            "type": "string"
          }
        }
      },
      "CaseDetail": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "case_number": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "OPEN",
              "AWAITING_USER",
              "RESOLVED"
            ]
          },
          "resolution": {
            "type": "string",
            "enum": [
              "FALSE_POSITIVE",
              "VALID_THREAT",
              "INCONCLUSIVE",
              "REQUIREMENTS_NOT_MET",
              "REQUIREMENTS_SATISFIED"
            ],
            "nullable": true
          },
          "resolution_notes": {
            "type": "string",
            "nullable": true
          },
          "priority": {
            "type": "string",
            "enum": [
              "LOW",
              "MEDIUM",
              "HIGH"
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "MANUAL",
              "AML_SCREENING",
              "TRANSACTION_RULE",
              "WORKFLOW_BUILDER"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "subject": {
            "$ref": "#/components/schemas/CaseSubject"
          },
          "assigned_to": {
            "$ref": "#/components/schemas/CaseAssignee"
          },
          "assigned_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "team": {
            "$ref": "#/components/schemas/CaseTeamSummary"
          },
          "due_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "resolved_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "resolved_by_email": {
            "type": "string",
            "nullable": true
          },
          "pending_resolution": {
            "type": "object",
            "nullable": true,
            "description": "체커 블루프린트에서 승인 또는 거부 승인을 기다리며 4-eyes 해결 절차가 스테이징되는 동안에만 설정됩니다.",
            "properties": {
              "resolution": {
                "type": "string",
                "enum": [
                  "FALSE_POSITIVE",
                  "VALID_THREAT",
                  "INCONCLUSIVE",
                  "REQUIREMENTS_NOT_MET",
                  "REQUIREMENTS_SATISFIED"
                ]
              },
              "resolution_notes": {
                "type": "string",
                "nullable": true
              },
              "maker_email": {
                "type": "string",
                "format": "email",
                "nullable": true,
                "description": "결정을 제출한 담당자의 이메일입니다. API 키로 제출한 경우 null입니다. 해당 결정에는 기록된 작성자가 없으므로 모든 호출자에 대해 승인 및 승인 거부가 403을 반환합니다."
              },
              "maker_name": {
                "type": "string",
                "nullable": true
              },
              "maker_user_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true,
                "description": "해결 조치를 제출한 담당자의 멤버 사용자 uuid입니다. API 키가 제출한 경우 null입니다. 해당 멤버는 `checker`로 지정될 수 없습니다."
              },
              "maker_blueprint_id": {
                "type": "string",
                "format": "uuid"
              },
              "staged_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "checker": {
            "$ref": "#/components/schemas/CaseChecker"
          },
          "metadata": {
            "type": "object"
          },
          "blueprint": {
            "$ref": "#/components/schemas/CaseBlueprintDetail"
          },
          "notes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseNote"
            },
            "description": "최신 50개 메모입니다."
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseEvent"
            },
            "description": "최신 100개 이벤트입니다."
          },
          "links": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseLink"
            }
          },
          "links_count": {
            "type": "integer"
          },
          "notes_count": {
            "type": "integer"
          },
          "checklist_items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseChecklistItem"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ReportTemplateDetail": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "jurisdiction": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2,
            "description": "ISO 3166-1 alpha-2 국가 코드입니다."
          },
          "report_type": {
            "type": "string",
            "enum": [
              "SAR",
              "STR",
              "CTR",
              "TTR",
              "UTR",
              "IFT",
              "CBR",
              "TFR"
            ]
          },
          "report_type_display": {
            "type": "string"
          },
          "field_config": {
            "type": "object",
            "description": "재사용 가능한 goAML 헤더 기본값입니다. 템플릿 수준 필수 필드: rentity_id, submission_code 및 currency_code_local(3자리 문자). 선택 사항: enabled_fields(포함할 선택적 보고서 블록)와 reporting_person, location, reason 및 action 기본값. 제출 건별 헤더 필드(action, submission_date, transactions, jurisdiction)는 템플릿이 아닌 보고서가 검증되거나 완료될 때 적용됩니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "RegulatoryReportDetail": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "case_uuid": {
            "type": "string",
            "format": "uuid"
          },
          "case_number": {
            "type": "string",
            "nullable": true
          },
          "report_type": {
            "type": "string",
            "enum": [
              "SAR",
              "STR",
              "CTR",
              "TTR",
              "UTR",
              "IFT",
              "CBR",
              "TFR"
            ]
          },
          "report_type_display": {
            "type": "string"
          },
          "report_code": {
            "type": "string",
            "description": "report_type에서 파생된 goAML 보고서 코드(예: STR, CTR, BCR)입니다."
          },
          "report_number": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT",
              "VALIDATED",
              "FINALIZED"
            ]
          },
          "status_display": {
            "type": "string"
          },
          "jurisdiction": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2
          },
          "rentity_id": {
            "type": "string",
            "nullable": true,
            "description": "FIU에서 발급한 보고 기관 ID입니다."
          },
          "rentity_branch": {
            "type": "string",
            "nullable": true
          },
          "submission_code": {
            "type": "string",
            "enum": [
              "E",
              "M"
            ]
          },
          "entity_reference": {
            "type": "string",
            "nullable": true
          },
          "fiu_ref_number": {
            "type": "string",
            "nullable": true
          },
          "currency_code_local": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3,
            "nullable": true
          },
          "submission_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "reporting_person": {
            "type": "object"
          },
          "location": {
            "type": "object"
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "action": {
            "type": "string",
            "nullable": true
          },
          "activity": {
            "type": "string",
            "nullable": true
          },
          "narrative": {
            "type": "object",
            "description": "5W 서술형 섹션입니다.",
            "properties": {
              "who": {
                "type": "string"
              },
              "what": {
                "type": "string"
              },
              "when": {
                "type": "string"
              },
              "where": {
                "type": "string"
              },
              "why": {
                "type": "string"
              },
              "how": {
                "type": "string"
              }
            }
          },
          "report_indicators": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "included_fields": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "transactions": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "validation_errors": {
            "type": "array",
            "description": "가장 최근 검증의 결과입니다. 각 항목은 {field, message} 객체입니다.",
            "items": {
              "type": "object",
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          },
          "validated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "finalized_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_by_email": {
            "type": "string",
            "nullable": true
          },
          "created_by_name": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TransactionRuleCondition": {
        "type": "object",
        "required": [
          "field",
          "operator"
        ],
        "properties": {
          "field": {
            "type": "string",
            "description": "평가할 거래 필드 경로입니다. 핵심 필드: amount, currency, direction, action_type, score, severity, transaction_type, payment_details, preferred_currency_amount(amount_in_default_currency로 대체됨), default_currency_code, subject_country, counterparty_country, subject_vendor_data, counterparty_vendor_data, subject_device_fingerprint, counterparty_device_fingerprint, subject_browser_family, subject_browser_version, subject_platform, subject_accept_language, subject_session_age_ms, subject_ip_country, counterparty_ip_country, subject_ip_address, counterparty_ip_address, subject_payment_method_type, subject_payment_method_country, subject_payment_method_fingerprint, subject_payment_method_account_id(및 이에 상응하는 counterparty_payment_method_* 필드), travel_rule_status, travel_rule_required, travel_rule_obligations_count, counterparty_dd_status(Travel Rule 거래 상대방에 대한 귀하의 결정: APPROVED, RESTRICTED 또는 BLOCKED, 해당 브랜드의 결정을 따르는 엔티티), counterparty_risk_level(LOW, MEDIUM 또는 HIGH. 자체 거래 상대방 스크리닝에서 플래그가 지정된 동안에는 HIGH), counterparty_jurisdiction(상대방 VASP의 국가), counterparty_responsiveness(RESPONSIVE, UNRESPONSIVE 또는 UNKNOWN), subject_days_since_previous_transaction, tags, 그리고 거래 생성 시 custom_properties로 제출된 모든 키에 대한 custom_values.<key>입니다. 국가 코드 필드는 ISO-2 또는 ISO-3 형식을 허용하며, 비교 전에 양측 모두 ISO-3 형식으로 정규화됩니다."
          },
          "operator": {
            "type": "string",
            "enum": [
              "eq",
              "ne",
              "gt",
              "gte",
              "lt",
              "lte",
              "in",
              "not_in",
              "contains",
              "not_contains",
              "contains_any",
              "regex",
              "fuzzy_match",
              "exists",
              "is_not_empty",
              "is_not_null",
              "not_exists",
              "is_empty",
              "is_null"
            ],
            "description": "비교 연산자입니다. in/not_in은 포함 여부를 테스트합니다(값은 목록 또는 단일 스칼라일 수 있음). contains/not_contains는 문자열 값에 대한 대소문자를 구분하지 않는 하위 문자열 확인입니다. contains_any는 문자열 목록을 받아서 필드 값의 대소문자를 구분하지 않는 하위 문자열과 하나라도 일치하면 참이 됩니다. regex는 필드에 값 패턴을 대조합니다. fuzzy_match는 필수 `score` 임계값(0-100)을 사용하여 값 문자열과 비교합니다. gt/gte/lt/lte는 어느 한쪽이라도 누락된 경우 일치하지 않습니다. exists/is_not_empty/is_not_null(별칭) 및 not_exists/is_empty/is_null(별칭)은 `value`를 무시하는 존재 여부 확인입니다."
          },
          "value": {
            "description": "비교 값입니다. 형태는 연산자와 value_type에 따라 달라집니다. 존재 여부 확인 연산자에서는 생략하세요. 다른 모든 연산자에는 `null`이나 빈 목록이 아닌 값이 필요하며, 그렇지 않으면 규칙이 `400`으로 거부됩니다. `contains_any`에는 문자열 목록이 필요하고, `contains`, `not_contains`, `regex`에는 단일 문자열이 필요합니다."
          },
          "value_type": {
            "type": "string",
            "enum": [
              "list",
              "field",
              "relative_date"
            ],
            "description": "선택 사항인 값 해석 방식입니다. `list`: 값은 목록 UUID이며 목록의 항목이 비교 값이 됩니다. `field`: 값은 다른 필드 경로이며 필드 대 필드로 비교됩니다. `relative_date`: 값은 상대 날짜 객체입니다(예: {\"direction\": \"past\", \"unit\": \"days\", \"amount\": 30})."
          },
          "score": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "operator가 fuzzy_match일 때 필수: 0-100 유사도 임계값입니다."
          },
          "group_index": {
            "type": "integer",
            "description": "선택적 그룹화 로직입니다. 조건에 group_index가 포함되어 있으면 동일한 인덱스를 공유하는 조건들이 그룹을 형성하며, 그룹화된 평가가 evaluation_mode를 대체합니다."
          },
          "group_logic": {
            "type": "string",
            "enum": [
              "AND",
              "OR"
            ],
            "default": "AND",
            "description": "그룹 내에서 조건들이 결합되는 방식입니다."
          },
          "groups_logic": {
            "type": "string",
            "enum": [
              "AND",
              "OR"
            ],
            "default": "OR",
            "description": "그룹 간에 그룹 결과가 결합되는 방식입니다. 첫 번째 조건에서 읽습니다."
          }
        },
        "description": "조건은 평가 중인 거래만 읽으며, 집계 윈도우를 필터링하지 않습니다."
      },
      "TransactionRuleAggregation": {
        "type": "object",
        "required": [
          "value"
        ],
        "properties": {
          "metric": {
            "type": "string",
            "enum": [
              "count",
              "sum",
              "max",
              "min",
              "avg",
              "distinct_count"
            ],
            "default": "count",
            "description": "일치하는 과거 거래가 집계되는 방식입니다. unique_count는 distinct_count의 별칭으로 허용됩니다."
          },
          "field": {
            "type": "string",
            "default": "amount",
            "description": "sum/max/min/avg/distinct_count로 집계된 필드입니다. count의 경우 무시됩니다."
          },
          "operator": {
            "type": "string",
            "enum": [
              "eq",
              "ne",
              "gt",
              "gte",
              "lt",
              "lte"
            ],
            "default": "eq",
            "description": "계산된 지표에 적용된 비교입니다."
          },
          "value": {
            "type": "number",
            "description": "계산된 지표가 비교되는 임계값입니다."
          },
          "window": {
            "type": "string",
            "pattern": "^\\d+(m|h|d)$",
            "default": "1d",
            "description": "거래의 txn_date로 끝나는 룩백 윈도우: <N>m(월이 아닌 분 단위), <N>h(시간) 또는 <N>d(일), 예: 30m, 24h, 7d, 30d."
          },
          "filters": {
            "type": "object",
            "additionalProperties": true,
            "description": "집계할 과거 거래를 좁힙니다. 키는 조건 필드 카탈로그의 필드 경로이며, \"__current__\" 값은 평가 중인 거래의 동일한 필드 값으로 확인됩니다(예: {\"subject_vendor_data\": \"__current__\"}는 윈도우 범위를 동일한 주체로 한정함). 목록 값은 멤버십을 의미합니다. 그룹화된 값이 없는 레코드는 함께 그룹화되지 않습니다. 평가 중인 거래에 \"__current__\" 필드에 대한 값이 없는 경우(거래 상대방 없음, 기기 지문 없음), 연산자에 관계없이 집계가 일치하지 않습니다. 필터는 일치 여부 또는 멤버십으로만 비교합니다. lt/gte 필터가 없으므로 \"10,000 미만의 과거 거래\"와 같은 범위는 여기서 표현할 수 없습니다. 대신 메트릭에 범위를 지정하세요(연산자가 lt인 메트릭 max는 윈도우 내의 모든 거래를 임계값 미만으로 유지함)."
          }
        },
        "description": "윈도우 내 애플리케이션의 과거 거래에 대한 빈도 검사(velocity check)입니다. evaluation_mode와 관계없이 규칙이 일치하려면 모든 집계 항목이 일치해야 합니다. 집계는 윈도우만 제한하며, 평가 대상 거래는 범위와 조건에 의해 제한되므로 규칙에 필요한 경우 양쪽 모두에 direction, currency 또는 transaction_type을 반복해 지정해야 합니다."
      },
      "TransactionRuleScope": {
        "type": "object",
        "properties": {
          "transaction_types": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "finance, kyc, travel_rule, user_event 등 거래 유형으로 제한합니다. 비어 있거나 누락된 경우 = 제한 없음."
          },
          "directions": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "INBOUND",
                "OUTBOUND"
              ]
            },
            "description": "거래 방향으로 제한합니다(작성 시 대소문자 구분 없음)."
          },
          "action_types": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "withdrawal, deposit 등 action_type 값으로 제한합니다."
          }
        },
        "description": "규칙이 적용되는 거래입니다. 이 세 가지 키만 허용됩니다."
      },
      "TransactionRuleAction": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/TransactionRuleActionAddScore"
          },
          {
            "$ref": "#/components/schemas/TransactionRuleActionChangeStatus"
          },
          {
            "$ref": "#/components/schemas/TransactionRuleActionAddTags"
          },
          {
            "$ref": "#/components/schemas/TransactionRuleActionAddNote"
          },
          {
            "$ref": "#/components/schemas/TransactionRuleActionAddToList"
          },
          {
            "$ref": "#/components/schemas/TransactionRuleActionOpenCase"
          }
        ],
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "add_score": "#/components/schemas/TransactionRuleActionAddScore",
            "change_status": "#/components/schemas/TransactionRuleActionChangeStatus",
            "add_tags": "#/components/schemas/TransactionRuleActionAddTags",
            "add_note": "#/components/schemas/TransactionRuleActionAddNote",
            "add_to_list": "#/components/schemas/TransactionRuleActionAddToList",
            "open_case": "#/components/schemas/TransactionRuleActionOpenCase"
          }
        },
        "description": "규칙 작업 하나입니다. 하나의 규칙에 여러 작업이 포함될 수 있으며, 규칙이 일치할 때 모두 함께 적용됩니다. TEST 모드의 규칙은 어떤 작업도 적용하지 않고 수행되었을 내용만 기록합니다."
      },
      "TransactionRuleCreateRequest": {
        "type": "object",
        "required": [
          "title",
          "category",
          "mode"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "규칙 이름. 삭제되지 않은 규칙 중에서 애플리케이션당 고유해야 하며, 중복 시 400을 반환합니다."
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "type": "string",
            "description": "그룹화 및 보고에 사용되는 위험 테마(예: finance, aml_ctf, anomaly_detection, fatf, device_intelligence, crypto_monitoring, travel_rule, responsible_gaming, e_commerce)."
          },
          "mode": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "DISABLED",
              "TEST"
            ],
            "description": "ACTIVE는 실시간으로 평가합니다. TEST는 규칙 실행을 평가하고 기록하지만 점수나 상태는 변경하지 않는 권장 시작 모드입니다. DISABLED는 건너뜁니다."
          },
          "evaluation_mode": {
            "type": "string",
            "enum": [
              "ALL",
              "ANY"
            ],
            "default": "ALL",
            "description": "모든 조건이 일치해야 하는지(ALL), 아니면 하나 이상 일치해야 하는지(ANY) 여부입니다. 조건에 group_index가 사용된 경우 무시됩니다."
          },
          "scope": {
            "$ref": "#/components/schemas/TransactionRuleScope"
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleCondition"
            }
          },
          "aggregation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAggregation"
            }
          },
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAction"
            }
          },
          "metadata": {
            "type": "object",
            "description": "규칙에 저장된 자유 형식 메타데이터입니다."
          }
        },
        "description": "CUSTOM 규칙을 생성합니다. ACTIVE 모드의 규칙은 신규 거래에 즉시 적용됩니다. TEST 모드로 생성한 후 먼저 백테스트를 진행하세요."
      },
      "TransactionRuleUpdateRequest": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "규칙 이름. 삭제되지 않은 규칙 중에서 애플리케이션당 고유해야 하며, 중복 시 400을 반환합니다."
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "type": "string",
            "description": "그룹화 및 보고에 사용되는 위험 테마(예: finance, aml_ctf, anomaly_detection, fatf, device_intelligence, crypto_monitoring, travel_rule, responsible_gaming, e_commerce)."
          },
          "mode": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "DISABLED",
              "TEST"
            ],
            "description": "ACTIVE는 실시간으로 평가합니다. TEST는 규칙 실행을 평가하고 기록하지만 점수나 상태는 변경하지 않는 권장 시작 모드입니다. DISABLED는 건너뜁니다."
          },
          "evaluation_mode": {
            "type": "string",
            "enum": [
              "ALL",
              "ANY"
            ],
            "default": "ALL",
            "description": "모든 조건이 일치해야 하는지(ALL), 아니면 하나 이상 일치해야 하는지(ANY) 여부입니다. 조건에 group_index가 사용된 경우 무시됩니다."
          },
          "scope": {
            "$ref": "#/components/schemas/TransactionRuleScope"
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleCondition"
            }
          },
          "aggregation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAggregation"
            }
          },
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAction"
            }
          },
          "metadata": {
            "type": "object",
            "description": "규칙에 저장된 자유 형식 메타데이터입니다."
          }
        },
        "description": "부분 업데이트입니다. 커스텀 규칙은 모든 필드를 허용하지만, 라이브러리(PRESET) 규칙은 mode만 허용하며 그 외의 값은 400을 반환합니다."
      },
      "TransactionRuleDetail": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string",
            "description": "규칙 이름. 삭제되지 않은 규칙 중에서 애플리케이션당 고유해야 하며, 중복 시 400을 반환합니다."
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "type": "string",
            "description": "그룹화 및 보고에 사용되는 위험 테마(예: finance, aml_ctf, anomaly_detection, fatf, device_intelligence, crypto_monitoring, travel_rule, responsible_gaming, e_commerce)."
          },
          "mode": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "DISABLED",
              "TEST"
            ],
            "description": "ACTIVE는 실시간으로 평가합니다. TEST는 규칙 실행을 평가하고 기록하지만 점수나 상태는 변경하지 않는 권장 시작 모드입니다. DISABLED는 건너뜁니다."
          },
          "evaluation_mode": {
            "type": "string",
            "enum": [
              "ALL",
              "ANY"
            ],
            "default": "ALL",
            "description": "모든 조건이 일치해야 하는지(ALL), 아니면 하나 이상 일치해야 하는지(ANY) 여부입니다. 조건에 group_index가 사용된 경우 무시됩니다."
          },
          "scope": {
            "$ref": "#/components/schemas/TransactionRuleScope"
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleCondition"
            }
          },
          "aggregation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAggregation"
            }
          },
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAction"
            }
          },
          "metadata": {
            "type": "object",
            "description": "규칙에 저장된 자유 형식 메타데이터입니다."
          },
          "severity": {
            "type": "string",
            "enum": [
              "UNKNOWN",
              "LOW",
              "MEDIUM",
              "HIGH",
              "CRITICAL"
            ],
            "nullable": true,
            "description": "라이브러리 규칙에 의해 전달되는 정보 제공용 심각도이며, 사용자 지정 규칙에서는 설정할 수 없습니다."
          },
          "source": {
            "type": "string",
            "enum": [
              "PRESET",
              "CUSTOM"
            ],
            "description": "PRESET 규칙은 라이브러리에서 제공되며(설치/제거, 모드 전용 편집), CUSTOM 규칙은 전적으로 사용자가 정의합니다."
          },
          "library_key": {
            "type": "string",
            "nullable": true,
            "description": "고정 라이브러리 식별자입니다. 사용자 정의 규칙의 경우 null입니다."
          },
          "latest_triggered_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "run_count": {
            "type": "integer",
            "description": "이 규칙과 일치한 거래 수입니다."
          },
          "approved_count": {
            "type": "integer"
          },
          "reviewed_count": {
            "type": "integer"
          },
          "declined_count": {
            "type": "integer"
          },
          "awaiting_user_count": {
            "type": "integer"
          },
          "approved_pct": {
            "type": "number"
          },
          "reviewed_pct": {
            "type": "number"
          },
          "declined_pct": {
            "type": "number"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TransactionRuleBacktestRequest": {
        "type": "object",
        "properties": {
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleCondition"
            },
            "default": []
          },
          "aggregation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAggregation"
            },
            "default": []
          },
          "evaluation_mode": {
            "type": "string",
            "enum": [
              "ALL",
              "ANY"
            ],
            "default": "ALL"
          },
          "scope": {
            "$ref": "#/components/schemas/TransactionRuleScope"
          },
          "period_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "default": 90
          }
        },
        "description": "최근 거래에 대해 평가할 가상의 규칙 설정입니다. 읽기 전용이며 무료입니다. 아무것도 생성되거나 수정되지 않습니다. 활성화하려는 규칙과 동일한 conditions, aggregation, evaluation_mode 및 scope를 전송하세요. 생략된 conditions, aggregation 및 scope는 자체 제약 조건을 추가하지 않습니다. scope를 생략하면 저장된 규칙이 건너뛰는 방향이나 거래 유형이 포함될 수 있습니다. 생략된 evaluation_mode는 기본적으로 ALL로 설정되며(ANY 규칙에 대한 일치 건수가 줄어들 수 있음), 생략된 period_days는 무제한 기록이 아닌 기본값인 90일로 설정됩니다."
      },
      "TransactionRuleBacktestResult": {
        "type": "object",
        "properties": {
          "evaluated": {
            "type": "integer",
            "description": "평가된 거래(최신순, 제한됨)."
          },
          "matched": {
            "type": "integer",
            "description": "해당 구성과 일치했을 거래입니다."
          },
          "affected_entities": {
            "type": "integer",
            "description": "일치 항목 중 고유한 대상자(vendor_data 기준)입니다."
          },
          "period_days": {
            "type": "integer"
          }
        }
      },
      "TransactionRuleLibraryEntry": {
        "type": "object",
        "properties": {
          "library_key": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "type": "string"
          },
          "evaluation_mode": {
            "type": "string",
            "enum": [
              "ALL",
              "ANY"
            ]
          },
          "scope": {
            "$ref": "#/components/schemas/TransactionRuleScope"
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleCondition"
            }
          },
          "aggregation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAggregation"
            }
          },
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAction"
            }
          },
          "metadata": {
            "type": "object"
          },
          "bundle": {
            "type": "string",
            "nullable": true,
            "description": "기능군(예: finance, aml_ctf, crypto_monitoring, travel_rule, responsible_gaming)."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "industries": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "source": {
            "type": "string"
          },
          "is_installed": {
            "type": "boolean",
            "description": "이 프리셋이 현재 애플리케이션에 설치되어 있는지 여부입니다."
          }
        }
      },
      "TransactionRuleInstallRequest": {
        "type": "object",
        "properties": {
          "library_keys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "설치하거나 설치 제거할 특정 프리셋입니다."
          },
          "bundle": {
            "type": "string",
            "description": "대신 이 번들의 모든 프리셋을 설치하거나 제거합니다."
          }
        },
        "description": "library_keys 또는 bundle을 제공하세요."
      },
      "TransactionRuleInstallResult": {
        "type": "object",
        "properties": {
          "installed_library_keys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "POST (install) 전용: 이번 호출로 설치된 프리셋입니다."
          },
          "installed_count": {
            "type": "integer",
            "description": "POST (install) 전용입니다."
          },
          "uninstalled_count": {
            "type": "integer",
            "description": "DELETE(설치 해제) 전용: 이 호출로 제거된 프리셋입니다."
          }
        }
      },
      "WalletScreeningResult": {
        "type": "object",
        "properties": {
          "provider": {
            "type": "string",
            "description": "스크리닝을 수행한 제공자입니다(예: `merklescience`, `crystal`)."
          },
          "screening_type": {
            "type": "string",
            "enum": [
              "WALLET_SCREENING"
            ],
            "description": "이 endpoint의 경우 항상 `WALLET_SCREENING`입니다."
          },
          "risk_score": {
            "type": "integer",
            "description": "정규화된 0-100 위험 점수입니다. 높을수록 위험한 엔티티에 대한 노출도가 높음을 의미합니다. Merkle Science는 주소를 0-5로 등급을 매기며, 이는 0, 15, 35, 55, 75 또는 95에 매핑됩니다."
          },
          "severity": {
            "type": "string",
            "enum": [
              "UNKNOWN",
              "LOW",
              "MEDIUM",
              "HIGH",
              "CRITICAL"
            ],
            "description": "`risk_score`에서 파생된 위험 구간: `0-9` UNKNOWN, `10-39` LOW, `40-69` MEDIUM, `70-89` HIGH, `90-100` CRITICAL. `UNKNOWN`은 별도의 데이터 없음 상태가 아니라 가장 낮은 구간입니다. 즉, `risk_score` 0(일반적인 정상 주소 사례)은 부정적인 평가가 없음을 의미하는 반면, 1-9 범위의 0이 아닌 점수는 실제이지만 LOW 미만인 신호이므로 구간만 보지 말고 `risk_score`를 확인해야 합니다. `UNKNOWN`을 긍정적인 저위험 또는 무결격 등급으로 간주하지 마십시오. 통과로 표시해서는 안 됩니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "SCREENED",
              "PENDING",
              "ERROR"
            ],
            "description": "스크리닝 결과 상태입니다."
          },
          "summary": {
            "type": "string",
            "description": "스크리닝 결과에 대해 사람이 읽을 수 있는 요약입니다."
          },
          "wallet_address": {
            "type": "string",
            "description": "스크리닝된 주소로, 그대로 반환됩니다."
          },
          "transaction_hash": {
            "type": "string",
            "nullable": true,
            "description": "결과 형태와 공유되는 거래 스크리닝 필드입니다. 지갑 스크리닝 결과에서는 항상 `null`입니다."
          },
          "blockchain": {
            "type": "string",
            "description": "스크리닝된 블록체인입니다."
          },
          "block_timestamp": {
            "type": "string",
            "nullable": true,
            "description": "결과 형태와 공유되는 거래 스크리닝 필드입니다. 지갑 스크리닝 결과에서는 항상 `null`입니다."
          },
          "total_value_usd": {
            "type": "number",
            "nullable": true,
            "description": "결과 형태와 공유되는 거래 스크리닝 필드입니다. 지갑 스크리닝 결과에서는 항상 `null`입니다."
          },
          "fee_usd": {
            "type": "number",
            "nullable": true,
            "description": "결과 형태와 공유되는 거래 스크리닝 필드입니다. 지갑 스크리닝 결과에서는 항상 `null`입니다."
          },
          "sender_rows": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "결과 형태와 공유되는 거래 스크리닝 필드입니다. 지갑 스크리닝 결과에서는 항상 비어 있습니다."
          },
          "receiver_rows": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "결과 형태와 공유되는 거래 스크리닝 필드입니다. 지갑 스크리닝 결과에서는 항상 비어 있습니다."
          },
          "transaction_flows": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "결과 형태와 공유되는 거래 스크리닝 필드입니다. 지갑 스크리닝 결과에서는 항상 비어 있습니다."
          },
          "transaction_flows_status": {
            "type": "string",
            "nullable": true,
            "description": "결과 형태와 공유되는 거래 스크리닝 필드입니다. 지갑 스크리닝 결과에서는 항상 `null`입니다."
          },
          "transaction_flows_error": {
            "type": "string",
            "nullable": true,
            "description": "결과 형태와 공유되는 거래 스크리닝 필드입니다. 지갑 스크리닝 결과에서는 항상 `null`입니다."
          },
          "source_of_funds": {
            "type": "array",
            "description": "주소가 자금을 수취한 출처이며, 엔티티별로 귀속됩니다. 각 항목은 익스포저 세부 내역입니다.",
            "items": {
              "type": "object",
              "properties": {
                "category": {
                  "type": "string",
                  "description": "정규화된 위험 카테고리(예: `exchange_licensed`, `dex`, `defi`, `payment_processor`, `mixer`, `darknet_market`, `sanctioned`, `stolen_funds`, `high_risk_exchange`)입니다."
                },
                "percentage": {
                  "type": "number",
                  "description": "해당 방향의 총 노출 점유율(0-100)입니다."
                },
                "amount_usd": {
                  "type": "number",
                  "nullable": true,
                  "description": "이 엔티티에 기인한 USD 가치입니다."
                },
                "entity_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "귀속된 엔티티의 이름(예: 거래소, 믹서 또는 제재 대상 그룹)."
                },
                "entity_type": {
                  "type": "string",
                  "nullable": true,
                  "description": "제공자 엔터티 유형입니다(예: `Exchange`, `DeFi`, `Sanctions`, `Theft`)."
                },
                "entity_subtype": {
                  "type": "string",
                  "nullable": true,
                  "description": "더 세부적인 하위 유형입니다(예: `Mandatory KYC and AML`, `OFAC`, `Yield Aggregator`)."
                },
                "hops": {
                  "type": "integer",
                  "nullable": true,
                  "description": "제공업체가 보고하는 경우 엔티티까지의 홉 수입니다(직접 거래 상대방의 경우 1). 노출이 직접적인지 간접적인지만 보고하는 Merkle Science의 경우 항상 `null`이므로 `exposure_type`을 사용하십시오."
                },
                "description": {
                  "type": "string",
                  "nullable": true,
                  "description": "제공자가 엔티티에 지정한 라벨의 `entity_type / entity_subtype`."
                },
                "is_direct": {
                  "type": "boolean",
                  "description": "`exposure_type`이 `direct`인 경우 true입니다."
                },
                "exposure_direction": {
                  "type": "string",
                  "enum": [
                    "incoming",
                    "outgoing",
                    "connected"
                  ],
                  "description": "자금이 이 엔티티로부터 들어왔는지(`incoming`) 또는 이 엔티티로 나갔는지(`outgoing`) 여부입니다."
                },
                "exposure_type": {
                  "type": "string",
                  "enum": [
                    "direct",
                    "indirect"
                  ],
                  "description": "`direct`(1홉) 또는 `indirect`(다중 홉) 노출."
                },
                "provider_entity_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "엔터티에 대한 공급자 자체 식별자입니다."
                },
                "provider_entity_type_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "`entity_type`에 대한 공급자 자체 식별자입니다."
                },
                "provider_entity_subtype_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "`entity_subtype`에 대한 공급자 자체 식별자입니다."
                },
                "country": {
                  "type": "string",
                  "nullable": true,
                  "description": "엔터티의 기본 ISO 3166-1 alpha-2 국가입니다. 제공업체가 알지 못하는 경우 비어 있거나 `null`입니다."
                },
                "raw_amount": {
                  "type": "number",
                  "nullable": true,
                  "description": "제공업체에서 보고한 경우, 자산 자체 단위 기준의 금액입니다."
                },
                "raw_currency": {
                  "type": "string",
                  "nullable": true,
                  "description": "제공업체에서 보고한 경우 `raw_amount`의 단위입니다."
                }
              }
            }
          },
          "destination_of_funds": {
            "type": "array",
            "description": "주소가 자금을 전송한 대상이며, 엔티티별로 귀속됩니다. `exposure_direction` = `outgoing`인 `source_of_funds`와 동일한 항목 형태를 갖습니다.",
            "items": {
              "type": "object",
              "properties": {
                "category": {
                  "type": "string",
                  "description": "정규화된 위험 카테고리(예: `exchange_licensed`, `dex`, `defi`, `payment_processor`, `mixer`, `darknet_market`, `sanctioned`, `stolen_funds`, `high_risk_exchange`)입니다."
                },
                "percentage": {
                  "type": "number",
                  "description": "해당 방향의 총 노출 점유율(0-100)입니다."
                },
                "amount_usd": {
                  "type": "number",
                  "nullable": true,
                  "description": "이 엔티티에 기인한 USD 가치입니다."
                },
                "entity_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "귀속된 엔티티의 이름(예: 거래소, 믹서 또는 제재 대상 그룹)."
                },
                "entity_type": {
                  "type": "string",
                  "nullable": true,
                  "description": "제공자 엔터티 유형입니다(예: `Exchange`, `DeFi`, `Sanctions`, `Theft`)."
                },
                "entity_subtype": {
                  "type": "string",
                  "nullable": true,
                  "description": "더 세부적인 하위 유형입니다(예: `Mandatory KYC and AML`, `OFAC`, `Yield Aggregator`)."
                },
                "hops": {
                  "type": "integer",
                  "nullable": true,
                  "description": "제공업체가 보고하는 경우 엔티티까지의 홉 수입니다(직접 거래 상대방의 경우 1). 노출이 직접적인지 간접적인지만 보고하는 Merkle Science의 경우 항상 `null`이므로 `exposure_type`을 사용하십시오."
                },
                "description": {
                  "type": "string",
                  "nullable": true,
                  "description": "제공자가 엔티티에 지정한 라벨의 `entity_type / entity_subtype`."
                },
                "is_direct": {
                  "type": "boolean",
                  "description": "`exposure_type`이 `direct`인 경우 true입니다."
                },
                "exposure_direction": {
                  "type": "string",
                  "enum": [
                    "incoming",
                    "outgoing",
                    "connected"
                  ],
                  "description": "자금이 이 엔티티로부터 들어왔는지(`incoming`) 또는 이 엔티티로 나갔는지(`outgoing`) 여부입니다."
                },
                "exposure_type": {
                  "type": "string",
                  "enum": [
                    "direct",
                    "indirect"
                  ],
                  "description": "`direct`(1홉) 또는 `indirect`(다중 홉) 노출."
                },
                "provider_entity_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "엔터티에 대한 공급자 자체 식별자입니다."
                },
                "provider_entity_type_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "`entity_type`에 대한 공급자 자체 식별자입니다."
                },
                "provider_entity_subtype_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "`entity_subtype`에 대한 공급자 자체 식별자입니다."
                },
                "country": {
                  "type": "string",
                  "nullable": true,
                  "description": "엔터티의 기본 ISO 3166-1 alpha-2 국가입니다. 제공업체가 알지 못하는 경우 비어 있거나 `null`입니다."
                },
                "raw_amount": {
                  "type": "number",
                  "nullable": true,
                  "description": "제공업체에서 보고한 경우, 자산 자체 단위 기준의 금액입니다."
                },
                "raw_currency": {
                  "type": "string",
                  "nullable": true,
                  "description": "제공업체에서 보고한 경우 `raw_amount`의 단위입니다."
                }
              }
            }
          },
          "counterparty_connections": {
            "type": "array",
            "description": "제공업체가 스크리닝된 주소의 소유로 귀속시킨 엔티티입니다. Merkle Science의 경우 주소 자체의 소유자 및 사용자 태그에서 가져오므로 동일한 엔티티가 두 번 나타날 수 있으며 자금 흐름을 포함하지 않습니다(`received_usd`, `sent_usd`, `received_hops`, `sent_hops`는 `null`이고 `percentage`는 0). 여기서는 `risk_level`이나 `is_direct`를 기준으로 라우팅하지 마세요. 판정에는 `sanctions_hit`, `dominant_risk_category`, `risk_factors[].is_high_risk`를 사용하고, 직접성 여부에는 `source_of_funds`/`destination_of_funds`의 `exposure_type`을 사용하세요.",
            "items": {
              "type": "object",
              "properties": {
                "entity_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "귀속된 엔터티 이름입니다."
                },
                "entity_type": {
                  "type": "string",
                  "nullable": true,
                  "description": "제공자 엔터티 유형입니다."
                },
                "entity_subtype": {
                  "type": "string",
                  "nullable": true,
                  "description": "제공자 엔터티 하위 유형입니다."
                },
                "risk_level": {
                  "type": "string",
                  "description": "소문자이며 제공업체에 따라 다릅니다. Merkle Science의 경우 주소 자체의 0-5 위험 등급(`no_risk`, `low`, `medium_low`, `medium`, `high`, `critical`)이며, 엔터티의 카테고리가 고위험인 경우 `high`로 상향 조정됩니다. 이는 엔터티의 별도 등급이 아닙니다."
                },
                "categories": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "엔티티의 정규화된 위험 카테고리입니다."
                },
                "received_usd": {
                  "type": "number",
                  "nullable": true,
                  "description": "제공업체가 보고한 경우, 엔티티로부터 수취한 USD 금액입니다."
                },
                "sent_usd": {
                  "type": "number",
                  "nullable": true,
                  "description": "제공업체가 보고한 경우, 엔티티로 송금한 USD 금액입니다."
                },
                "received_hops": {
                  "type": "integer",
                  "nullable": true,
                  "description": "제공업체에서 보고한 경우, 수신 측 엔티티까지의 홉 수입니다."
                },
                "sent_hops": {
                  "type": "integer",
                  "nullable": true,
                  "description": "제공업체에서 보고한 경우, 송신 측 엔티티까지의 홉 수입니다."
                },
                "percentage": {
                  "type": "number",
                  "description": "제공업체가 보고하는 경우 주소의 노출 점유율이며, 그렇지 않은 경우 0입니다."
                },
                "is_direct": {
                  "type": "boolean",
                  "description": "연결이 거래 상대방이 아닌 귀속 정보인 Merkle Science의 경우 항상 `true`입니다."
                },
                "country": {
                  "type": "string",
                  "nullable": true,
                  "description": "알려진 경우 엔터티의 국가입니다."
                },
                "provider_entity_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "엔터티에 대한 공급자 자체 식별자입니다."
                }
              }
            }
          },
          "network_nodes": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "거래 스크리닝을 위한 익스포저 그래프 노드입니다. 지갑 스크리닝 결과에서는 비어 있습니다."
          },
          "network_edges": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "거래 스크리닝을 위한 익스포저 그래프 에지입니다. 지갑 스크리닝 결과에서는 비어 있습니다."
          },
          "sanctions_hit": {
            "type": "boolean",
            "description": "주소가 직접 또는 간접적인 제재에 노출된 경우 true입니다."
          },
          "pep_counterparty": {
            "type": "boolean",
            "description": "정치적 주요 인물(PEP) 노출 여부입니다. PEP 결과가 없는 경우 `null`이며, 현재 어떤 제공업체도 이를 보고하지 않으므로 모든 결과가 이에 해당합니다. 명시적인 부정적 스크리닝 결과에 대해서만 `false`입니다. `null`을 완료된 PEP 확인으로 간주하지 마십시오.",
            "nullable": true
          },
          "dominant_risk_category": {
            "type": "string",
            "nullable": true,
            "description": "가중치가 가장 높은 고위험 카테고리이거나, 지배적인 카테고리가 없는 경우 `null`입니다(예: `sanctioned`, `mixer`, `stolen_funds`)."
          },
          "risk_factors": {
            "type": "array",
            "description": "`risk_score`에 대한 순위별 설명입니다. 이 판정이 도출된 원인을 나타냅니다. 제공자는 자체 모델을 기반으로 주소의 등급을 매기고 판정 결과만 반환하므로(Merkle Science는 0-5 사이의 정수 반환), 점수만으로는 조치를 취하기 어렵습니다. 고위험 항목이 먼저 정렬되고, 그 다음 각 요인을 통해 이동한 금액 순으로 정렬되며 상위 5개로 제한됩니다. `source_of_funds` 및 `destination_of_funds`에는 항상 전체 내역이 포함됩니다. `is_high_risk` 항목이 없는데 `risk_score`가 높다면 제공자가 제재 또는 주소에 귀속된 엔티티 일치를 보고하지 않았으며 순전히 자체 위험 노출 모델에 따라 주소 등급을 매겼음을 의미합니다. `summary`에 이 내용이 명시적으로 표시됩니다.",
            "items": {
              "type": "object",
              "properties": {
                "source": {
                  "type": "string",
                  "enum": [
                    "attribution",
                    "exposure"
                  ],
                  "description": "`attribution`은 공급업체가 해당 주소 자체에 대해 식별한 정보(자체 태그 또는 클러스터)이며, `exposure`는 자금이 실제로 이동한 위치입니다."
                },
                "category": {
                  "type": "string",
                  "description": "정규화된 위험 카테고리로, 노출 세부 내역과 동일한 어휘를 사용합니다."
                },
                "label": {
                  "type": "string",
                  "description": "공급자 콘솔에서도 확인할 수 있는 드라이버에 대한 공급자 자체 문구입니다(예: `Gambling / Crypto only`)."
                },
                "entity_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "드라이버 배후에 귀속된 엔터티입니다(예: 도박 사이트 또는 거래소)."
                },
                "direction": {
                  "type": "string",
                  "enum": [
                    "incoming",
                    "outgoing",
                    "connected",
                    "unknown",
                    "attribution"
                  ],
                  "description": "자금 흐름의 방향입니다. 드라이버가 주소 자체의 태그인 경우 `attribution`, 제공업체가 방향을 보고하지 않은 경우 `unknown`입니다."
                },
                "exposure_type": {
                  "type": "string",
                  "enum": [
                    "direct",
                    "indirect",
                    "unknown",
                    "attribution"
                  ],
                  "description": "`direct`(1홉) 또는 `indirect`(다중 홉), 주소 자체 태그의 경우 `attribution`, 제공자가 거래 상대방의 홉 수를 명시하지 않은 경우 `unknown`. `unknown`은 `direct`가 아닌 미분류로 처리하십시오."
                },
                "amount_usd": {
                  "type": "number",
                  "format": "float",
                  "nullable": true,
                  "description": "이 드라이버에 귀속된 USD 가치입니다."
                },
                "percentage": {
                  "type": "number",
                  "format": "float",
                  "description": "두 방향을 합산한 주소의 전체 스크리닝 볼륨 점유율입니다. 방향별로 정규화되는 `source_of_funds`/`destination_of_funds` 내부의 `percentage`와 다릅니다. 전체 목록에 걸쳐 비교 및 합산이 가능합니다."
                },
                "is_high_risk": {
                  "type": "boolean",
                  "description": "해당 카테고리가 Didit에서 고위험으로 처리하는 카테고리(`sanctioned`, `mixer`, `stolen_funds`, `ransomware`, `scam`, `darknet_market`, `terrorist_financing`, `child_exploitation`, `hacked_exchange`, `high_risk_exchange`, `seized_funds`)인지 여부입니다."
                },
                "description": {
                  "type": "string",
                  "description": "드라이버를 한 줄로 표시한 것입니다(예: `9.01% indirect outgoing exposure to Gambling / Crypto only (Example Gambling)`)."
                }
              }
            }
          },
          "raw_response": {
            "type": "object",
            "additionalProperties": true,
            "description": "공급자 자체 payload입니다. 형태는 공급자마다 다르며 사전 예고 없이 변경될 수 있으므로, 이를 직접 파싱하지 말고 정규화된 필드를 확인하십시오."
          },
          "report_signature": {
            "type": "string",
            "description": "애플리케이션으로 범위가 지정된, 이 정확한 결과에 대한 불투명한 HMAC-SHA256 서명입니다. 단독으로는 의미가 없으며, PDF로 렌더링하려면 이 필드를 포함하여 수정되지 않은 전체 응답 본문을 `POST /v3/wallet-screening/pdf/`로 다시 전송해야 합니다. `report_signature`가 누락되었거나 다시 전송하기 전에 서명된 필드(예: `risk_score`, `severity`, `sanctions_hit`)가 수정된 경우, PDF endpoint에서는 요청을 `400`으로 거부합니다."
          }
        },
        "required": [
          "provider",
          "screening_type",
          "risk_score",
          "severity",
          "status",
          "summary",
          "wallet_address",
          "blockchain",
          "sanctions_hit",
          "dominant_risk_category",
          "source_of_funds",
          "destination_of_funds",
          "counterparty_connections",
          "report_signature"
        ]
      },
      "NetworkRiskDisplay": {
        "type": "object",
        "properties": {
          "score": {
            "type": "integer",
            "description": "위험 점수, 0-100."
          },
          "band": {
            "type": "string",
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "description": "점수가 표시되는 구간입니다. 70 이상은 high, 40 이상은 medium, 그 외에는 low입니다."
          },
          "bar": {
            "type": "number",
            "format": "float",
            "description": "위험 바를 렌더링하기 위한 정규화된 0-1 값입니다."
          }
        }
      },
      "NetworkNodeTag": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "color": {
            "type": "string",
            "nullable": true,
            "description": "가드 태그의 경우 null이며, 색상 token은 렌더러가 소유합니다."
          },
          "source": {
            "type": "string",
            "enum": [
              "subject_tag",
              "session_tag",
              "transaction_tag",
              "signal_guard"
            ],
            "description": "태그의 출처: 사용자/기업의 태그, 이 네트워크 세션의 태그, 당사자가 속한 거래의 태그, 또는 신호 보호 조건(예: 허브, 데이터센터 IP)."
          },
          "category": {
            "type": "string",
            "enum": [
              "customer",
              "quality"
            ],
            "nullable": true,
            "description": "고객 정의 태그의 경우 customer, 신호 품질 가드 태그의 경우 quality입니다. 해당 사항이 없으면 null입니다."
          }
        }
      },
      "NetworkListItem": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "network_id": {
            "type": "string",
            "description": "사람이 읽을 수 있는 조직별 순차 ID(예: N-0001)입니다."
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "in_review",
              "resolved",
              "dismissed"
            ],
            "description": "네트워크 라이프사이클 상태입니다. 네트워크 내부의 신청자별 outcome_status(approved/in_review/declined/not_completed)와 구별됩니다."
          },
          "risk": {
            "$ref": "#/components/schemas/NetworkRiskDisplay"
          },
          "pattern_types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "exact_same_device",
                "similar_device",
                "same_ip_address",
                "same_address",
                "similar_selfie_backgrounds",
                "similar_poa_documents",
                "same_document_number",
                "same_phone_number",
                "same_email"
              ]
            },
            "description": "이 네트워크에서 감지된 클러스터링 패턴입니다."
          },
          "signal_types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "ip_address",
                "device",
                "face",
                "document_number",
                "phone",
                "email",
                "address"
              ]
            },
            "description": "이 네트워크에 존재하는 고유한 신호 유형들입니다."
          },
          "member_counts": {
            "type": "object",
            "description": "카테고리별 멤버 수(예: 전체, outcome_status별)."
          },
          "member_status": {
            "type": "object",
            "description": "outcome_status별 멤버 내역입니다."
          },
          "signal_coverage": {
            "type": "object",
            "description": "이 네트워크 멤버들의 signal_type별 적용 범위입니다."
          },
          "first_activity_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_activity_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "NetworkDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/NetworkListItem"
          },
          {
            "type": "object",
            "properties": {
              "stats": {
                "type": "object",
                "description": "네트워크에 대한 집계 통계입니다(예: 멤버 총수)."
              },
              "fraud_tags": {
                "type": "array",
                "items": {
                  "type": "object"
                },
                "description": "네트워크에 나타난 사기 패턴 태그입니다."
              },
              "risk_signals": {
                "type": "object",
                "description": "위험 신호 요약: residential_proxy_reuse, email_intelligence, phone_intelligence."
              },
              "reviewed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "reviewed_by": {
                "type": "string",
                "nullable": true
              },
              "review_reason": {
                "type": "string",
                "nullable": true
              }
            }
          }
        ],
        "properties": {
          "notes_count": {
            "type": "integer",
            "minimum": 0,
            "readOnly": true,
            "description": "이 조사에 포함된 비공개 분석가 메모 수입니다."
          }
        }
      },
      "NetworkGraphNode": {
        "type": "object",
        "description": "종류에 따라 구분되는 주체 노드 또는 신호 노드입니다. 주체 노드(종류: vendor_user | vendor_business | transaction_party)에는 id, kind, subject, node_status(approved | in_review | declined | not_completed) 및 tags가 포함됩니다. 신호 노드(종류: signal)에는 id, kind, uuid, signal_type, subject_count, coverage, is_hub, is_datacenter_ip, is_high_collision_device, node_status(signal_active | signal_guarded), tags, risk_evidence, first_seen_at 및 last_seen_at이 포함됩니다.",
        "properties": {
          "id": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "vendor_user",
              "vendor_business",
              "transaction_party",
              "signal"
            ]
          }
        }
      },
      "NetworkGraphEdge": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "source": {
            "type": "string",
            "description": "주체 노드 ID입니다."
          },
          "target": {
            "type": "string",
            "description": "시그널 노드 ID입니다."
          },
          "subject_kind": {
            "type": "string",
            "enum": [
              "vendor_user",
              "vendor_business",
              "transaction_party"
            ]
          },
          "signal_type": {
            "type": "string",
            "enum": [
              "ip_address",
              "device",
              "face",
              "document_number",
              "phone",
              "email",
              "address"
            ]
          },
          "confidence": {
            "type": "number",
            "format": "float",
            "description": "정확히 일치하는 경우 1.0입니다."
          },
          "observation_count": {
            "type": "integer"
          },
          "first_seen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_seen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "NetworkGraph": {
        "type": "object",
        "properties": {
          "network": {
            "$ref": "#/components/schemas/NetworkDetail"
          },
          "depth": {
            "type": "integer",
            "nullable": true,
            "description": "적용된 유효 깊이이며, 제한이 없는 경우(depth=all) null입니다."
          },
          "truncated": {
            "type": "boolean",
            "description": "인접 노드가 깊이 제한으로 인해 잘린 경우 true입니다."
          },
          "nodes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkGraphNode"
            }
          },
          "edges": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkGraphEdge"
            }
          },
          "metrics": {
            "type": "object",
            "properties": {
              "node_count": {
                "type": "integer"
              },
              "edge_count": {
                "type": "integer"
              },
              "hub_signal_count": {
                "type": "integer"
              }
            }
          }
        }
      },
      "NetworkMember": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "object",
            "description": "이 멤버가 나타내는 vendor_user, vendor_business 또는 transaction_party입니다."
          },
          "outcome_status": {
            "type": "string",
            "description": "대상자의 인증/결정 결과입니다."
          },
          "node_status": {
            "type": "string",
            "enum": [
              "approved",
              "in_review",
              "declined",
              "not_completed",
              "signal_active",
              "signal_guarded"
            ],
            "description": "멤버 행의 경우 항상 subject-outcome 값 중 하나입니다: approved, in_review, declined 또는 not_completed."
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkNodeTag"
            }
          },
          "risk": {
            "$ref": "#/components/schemas/NetworkRiskDisplay"
          },
          "signal_coverage": {
            "type": "object"
          },
          "shared_infrastructure": {
            "type": "object"
          },
          "joined_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_seen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "provenance": {
            "type": "object",
            "properties": {
              "session_ids": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "business_session_ids": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "transaction_ids": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            }
          }
        }
      },
      "NetworkSignal": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "signal_type": {
            "type": "string",
            "enum": [
              "ip_address",
              "device",
              "face",
              "document_number",
              "phone",
              "email",
              "address"
            ]
          },
          "subject_count": {
            "type": "integer"
          },
          "coverage": {
            "type": "number",
            "format": "float"
          },
          "is_hub": {
            "type": "boolean",
            "description": "이 시그널이 비정상적으로 많은 수의 주체를 연결할 때 true입니다."
          },
          "is_datacenter_ip": {
            "type": "boolean"
          },
          "is_high_collision_device": {
            "type": "boolean"
          },
          "node_status": {
            "type": "string",
            "enum": [
              "signal_active",
              "signal_guarded"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkNodeTag"
            }
          },
          "risk_evidence": {
            "type": "object"
          },
          "first_seen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_seen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "NetworkTimelineEvent": {
        "type": "object",
        "properties": {
          "event_type": {
            "type": "string",
            "description": "예: network_detected, signal_observed, network_in_review, network_resolved, network_dismissed."
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "label": {
            "type": "string"
          },
          "metadata": {
            "type": "object"
          }
        }
      },
      "NetworkMap": {
        "type": "object",
        "properties": {
          "network": {
            "$ref": "#/components/schemas/NetworkDetail"
          },
          "convergence_count": {
            "type": "integer",
            "description": "멤버들이 모이는 서로 다른 주소/위치 지점의 수입니다."
          },
          "countries": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "points": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "country": {
                  "type": "string",
                  "nullable": true
                },
                "country_code": {
                  "type": "string",
                  "nullable": true
                },
                "city": {
                  "type": "string",
                  "nullable": true
                },
                "latitude": {
                  "type": "number",
                  "format": "float",
                  "nullable": true
                },
                "longitude": {
                  "type": "number",
                  "format": "float",
                  "nullable": true
                },
                "observed_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true
                }
              }
            }
          }
        }
      },
      "EntityNetworkMembership": {
        "type": "object",
        "properties": {
          "network": {
            "$ref": "#/components/schemas/NetworkListItem"
          },
          "subject": {
            "type": "object"
          },
          "signal_types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "ip_address",
                "device",
                "face",
                "document_number",
                "phone",
                "email",
                "address"
              ]
            }
          },
          "signal_count": {
            "type": "integer"
          },
          "joined_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_seen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "RiskSignals": {
        "type": "object",
        "description": "애플리케이션에서 관찰한 선택적 기기 및 네트워크 컨텍스트입니다. 모든 필드는 선택 사항입니다. 이를 전달하면 Networks의 세션 간 일치 감지 기능에 데이터가 제공됩니다.",
        "properties": {
          "ip": {
            "type": "string",
            "format": "ip",
            "description": "최종 사용자에 대해 관찰된 IPv4 또는 IPv6 주소입니다.",
            "example": "192.0.2.1"
          },
          "device_id": {
            "type": "string",
            "maxLength": 255,
            "description": "애플리케이션에서 수집한 안정적인 기기 식별자(Android `ANDROID_ID`, iOS `identifierForVendor`)입니다."
          },
          "device_platform": {
            "type": "string",
            "enum": [
              "android",
              "ios",
              "ipados",
              "tvos",
              "web"
            ],
            "description": "최종 사용자 기기의 플랫폼입니다."
          },
          "device_model": {
            "type": "string",
            "maxLength": 255,
            "description": "애플리케이션에서 보고한 기기 모델입니다."
          },
          "os_version": {
            "type": "string",
            "maxLength": 64,
            "description": "운영체제 버전입니다."
          },
          "app_version": {
            "type": "string",
            "maxLength": 64,
            "description": "애플리케이션의 버전입니다."
          },
          "user_agent": {
            "type": "string",
            "maxLength": 512,
            "description": "브라우저 또는 앱 사용자 에이전트입니다."
          }
        }
      },
      "PhoneRiskRequest": {
        "type": "object",
        "required": [
          "phone_number"
        ],
        "properties": {
          "phone_number": {
            "type": "string",
            "maxLength": 20,
            "description": "점수를 산정할 전화번호입니다. 유효성 검사를 거쳐 E.164로 정규화됩니다.",
            "example": "+14155552671"
          },
          "country_code": {
            "type": "string",
            "maxLength": 3,
            "description": "인텔리전스 적용 범위를 위한 선택적 ISO 3166-1 alpha-2 또는 alpha-3 국가 힌트입니다.",
            "example": "US"
          },
          "signals": {
            "$ref": "#/components/schemas/RiskSignals"
          },
          "vendor_data": {
            "type": "string",
            "description": "이 요청에 대한 안정적인 참조값입니다. API 세션에 저장되며 응답에 그대로 반영됩니다."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "귀하의 비민감 JSON 메타데이터입니다. API 세션에 저장되며 응답에 그대로 반환됩니다."
          },
          "enable_social": {
            "type": "boolean",
            "default": false,
            "description": "true인 경우, 전화번호의 소셜 발자국(등록된 메시징, 소셜, 전자상거래 및 전문 플랫폼)도 조회합니다. 이 endpoint 자체의 가격 외에 요청당 `phone_social` 1단위로 청구됩니다.",
            "example": true
          }
        }
      },
      "EmailRiskRequest": {
        "type": "object",
        "required": [
          "email"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "점수를 산정할 이메일 주소입니다.",
            "example": "alice@example.com"
          },
          "country_code": {
            "type": "string",
            "maxLength": 3,
            "description": "인텔리전스 적용 범위를 위한 선택적 ISO 3166-1 alpha-2 또는 alpha-3 국가 힌트입니다.",
            "example": "US"
          },
          "signals": {
            "$ref": "#/components/schemas/RiskSignals"
          },
          "vendor_data": {
            "type": "string",
            "description": "이 요청에 대한 안정적인 참조값입니다. API 세션에 저장되며 응답에 그대로 반영됩니다."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "귀하의 비민감 JSON 메타데이터입니다. API 세션에 저장되며 응답에 그대로 반환됩니다."
          },
          "enable_social": {
            "type": "boolean",
            "default": false,
            "description": "true인 경우, 주소의 소셜 발자국(등록된 이메일, 소셜, 전문, 전자상거래 및 엔터테인먼트 플랫폼)도 조회합니다. 이 endpoint 자체의 가격 외에 요청당 `email_social` 1단위로 청구됩니다.",
            "example": true
          }
        }
      },
      "IPRiskRequest": {
        "type": "object",
        "required": [
          "ip_address"
        ],
        "properties": {
          "ip_address": {
            "type": "string",
            "format": "ip",
            "description": "점수를 산정할 IPv4 또는 IPv6 주소입니다.",
            "example": "8.8.8.8"
          },
          "claimed_country": {
            "type": "string",
            "maxLength": 3,
            "description": "사용자 또는 세션에서 주장한 선택적 ISO 3166-1 alpha-2 또는 alpha-3 국가입니다. `country_mismatch`를 계산하는 데 사용됩니다.",
            "example": "ESP"
          },
          "user_agent": {
            "type": "string",
            "maxLength": 512,
            "description": "백엔드에서 확인된 사용자 에이전트입니다. 요청 컨텍스트로 저장되며 기기 핑거프린팅 기능은 제공하지 않습니다."
          },
          "vendor_data": {
            "type": "string",
            "description": "이 요청에 대한 안정적인 참조값입니다. API 세션에 저장되며 응답에 그대로 반영됩니다."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "귀하의 비민감 JSON 메타데이터입니다. API 세션에 저장되며 응답에 그대로 반환됩니다."
          }
        }
      },
      "RiskWarning": {
        "type": "object",
        "required": [
          "feature",
          "risk",
          "log_type",
          "short_description",
          "long_description"
        ],
        "properties": {
          "feature": {
            "type": "string",
            "description": "경고를 생성한 기능입니다."
          },
          "risk": {
            "type": "string",
            "description": "기계 판독 가능한 위험 코드입니다. 향후 새로운 값이 추가될 수 있습니다."
          },
          "additional_data": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "위험별 컨텍스트 또는 `null`."
          },
          "log_type": {
            "type": "string",
            "enum": [
              "error",
              "warning",
              "information"
            ],
            "description": "결정 규칙에서 사용하는 심각도입니다."
          },
          "short_description": {
            "type": "string",
            "description": "사람이 읽을 수 있는 한 줄 요약입니다."
          },
          "long_description": {
            "type": "string",
            "description": "사람이 읽기 쉬운 설명입니다."
          }
        }
      },
      "RiskLifecycleEvent": {
        "type": "object",
        "required": [
          "type",
          "timestamp",
          "details",
          "fee"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "기계 판독 가능한 이벤트 유형. 시간이 지남에 따라 새로운 값이 추가될 수 있습니다."
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "이벤트가 발생한 시점입니다."
          },
          "details": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "이벤트 관련 payload 또는 `null`입니다."
          },
          "fee": {
            "type": "number",
            "description": "이 이벤트에 대해 청구된 USD 금액입니다."
          }
        }
      },
      "PhoneMatchItem": {
        "type": "object",
        "description": "동일한 전화번호를 다른 `vendor_data`와 함께 사용한 애플리케이션의 다른 세션입니다.",
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 전화번호를 사용한 다른 인증의 세션 id입니다."
          },
          "session_number": {
            "type": "integer",
            "description": "해당 세션의 사람이 읽기 쉬운 순차 번호입니다."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "해당 세션의 `vendor_data`입니다."
          },
          "verification_date": {
            "type": "string",
            "description": "해당 세션이 생성된 시점(`YYYY-MM-DDTHH:MM:SSZ`)입니다."
          },
          "phone_number": {
            "type": "string",
            "description": "일치하는 전화번호입니다."
          },
          "status": {
            "type": "string",
            "description": "해당 세션의 상태(예: `Approved`, `Declined`, `In Progress`)입니다."
          },
          "is_blocklisted": {
            "type": "boolean",
            "description": "전화번호가 애플리케이션의 차단 목록에 있는지 여부입니다."
          },
          "api_service": {
            "type": "string",
            "nullable": true,
            "description": "API 유형 세션의 경우 이를 생성한 독립형 API, 일반 인증 세션의 경우 `null`입니다."
          },
          "source": {
            "type": "string",
            "description": "일치 항목이 발견된 위치입니다. 일반적으로 `session`이며, 조직 목록 항목을 통한 차단 목록 일치는 `list_entry`를 사용합니다."
          }
        }
      },
      "EmailMatchItem": {
        "type": "object",
        "description": "동일한 이메일 주소를 다른 `vendor_data`와 함께 사용한 애플리케이션의 다른 세션입니다.",
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 이메일 주소를 사용한 다른 인증의 세션 id입니다."
          },
          "session_number": {
            "type": "integer",
            "description": "해당 세션의 사람이 읽기 쉬운 순차 번호입니다."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "해당 세션의 `vendor_data`입니다."
          },
          "verification_date": {
            "type": "string",
            "description": "해당 세션이 생성된 시점(`YYYY-MM-DDTHH:MM:SSZ`)입니다."
          },
          "email": {
            "type": "string",
            "description": "일치하는 이메일 주소입니다."
          },
          "status": {
            "type": "string",
            "description": "해당 세션의 상태(예: `Approved`, `Declined`, `In Progress`)입니다."
          },
          "is_blocklisted": {
            "type": "boolean",
            "description": "이메일 주소가 애플리케이션의 차단 목록에 있는지 여부입니다."
          },
          "api_service": {
            "type": "string",
            "nullable": true,
            "description": "API 유형 세션의 경우 이를 생성한 독립형 API, 일반 인증 세션의 경우 `null`입니다."
          },
          "source": {
            "type": "string",
            "description": "일치 항목이 발견된 위치입니다. 일반적으로 `session`이며, 조직 목록 항목을 통한 차단 목록 일치는 `list_entry`를 사용합니다."
          }
        }
      },
      "PhoneIntelligence": {
        "type": "object",
        "description": "정규화된 전화번호 인텔리전스 블록입니다. 이 조회에 대해 인텔리전스 애드온이 실행된 경우에만 존재하며, 존재하는 경우 동일한 값을 가진 `enrichment` 별칭으로도 노출됩니다.",
        "properties": {
          "score": {
            "type": "number",
            "nullable": true,
            "description": "정규화된 0-100 위험 점수입니다. 높을수록 위험합니다."
          },
          "phone_type_risk": {
            "type": "string",
            "nullable": true,
            "description": "점수에서 파생된 `Low`, `Medium` 또는 `High`."
          },
          "phone_trust_index": {
            "type": "number",
            "nullable": true,
            "description": "점수가 높을수록 좋은 대시보드를 위한 점수를 반전한 값입니다."
          },
          "network_stability_index": {
            "type": "number",
            "nullable": true,
            "description": "회선 네트워크의 안정성입니다."
          },
          "is_disposable": {
            "type": "boolean",
            "nullable": true,
            "description": "번호가 일회용 또는 가상 번호로 보이는 경우 `true`입니다."
          },
          "is_ported": {
            "type": "boolean",
            "nullable": true,
            "description": "번호의 통신사가 변경된 경우 `true`입니다."
          },
          "is_recently_ported": {
            "type": "boolean",
            "nullable": true,
            "description": "최근에 번호 이동이 발생한 경우 `true`입니다."
          },
          "carrier_type": {
            "type": "string",
            "nullable": true,
            "description": "조회 결과로 보고된 회선 분류입니다(예: `mobile`)."
          },
          "reason_codes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "description": "신호의 안정적인 Didit 식별자입니다(예: `IR-5AC67A32`). 불투명한 값이므로 구문 분석하지 말고 그룹화 및 필터링에만 사용하세요."
                },
                "value": {
                  "nullable": true,
                  "description": "위험 플래그(예: `voip`, `leaked`, `disposable`, `spam_trap`)의 경우 해당 값: boolean, 수준 또는 날짜입니다. 점수가 산정된 사유 코드의 경우 null입니다."
                },
                "direction": {
                  "type": "string",
                  "enum": [
                    "risk",
                    "trust"
                  ],
                  "description": "신호가 위험을 높였는지 또는 신뢰도를 높였는지 여부입니다."
                },
                "message": {
                  "type": "string",
                  "description": "신호에 대한 사람이 읽기 쉬운 영어 설명입니다."
                },
                "impact_level": {
                  "type": "string",
                  "nullable": true,
                  "description": "시그널이 점수를 얼마나 크게 변동시켰는지 나타내며, 예를 들어 `low`, `medium`, `high` 등이 있습니다."
                }
              }
            },
            "description": "점수를 설명하는 신호 목록으로, 각각 안정적인 Didit 코드, 방향, 메시지 및 영향 수준을 포함합니다. 새로운 코드가 점진적으로 추가될 수 있으므로 알 수 없는 코드를 거부하지 마세요."
          }
        }
      },
      "EmailIntelligence": {
        "type": "object",
        "description": "정규화된 이메일 인텔리전스 블록입니다. 이 이메일에 대해 인텔리전스 애드온이 실행된 경우에만 존재하며, 존재하는 경우 동일한 값을 가진 `enrichment` 별칭으로도 노출됩니다.",
        "properties": {
          "score": {
            "type": "number",
            "nullable": true,
            "description": "정규화된 0-100 위험 점수입니다. 높을수록 위험합니다."
          },
          "deliverable": {
            "type": "string",
            "nullable": true,
            "description": "전송 가능성 구간(예: `high`)."
          },
          "breach_risk_level": {
            "type": "string",
            "nullable": true,
            "description": "`Low`, `Medium` 또는 `High`."
          },
          "breach_risk_index": {
            "type": "number",
            "nullable": true,
            "description": "숫자 침해 위험 지수입니다."
          },
          "is_recent_breach": {
            "type": "boolean",
            "nullable": true,
            "description": "주소가 최근 유출 사고에 나타난 경우 `true`입니다."
          },
          "is_frequent_breached": {
            "type": "boolean",
            "nullable": true,
            "description": "주소가 다수의 유출 사고에 나타난 경우 `true`입니다."
          },
          "is_disposable": {
            "type": "boolean",
            "nullable": true,
            "description": "도메인이 일회용 이메일 제공업체인 경우 `true`입니다."
          },
          "is_free_domain": {
            "type": "boolean",
            "nullable": true,
            "description": "도메인이 무료 메일 제공업체인 경우 `true`입니다."
          },
          "is_breached": {
            "type": "boolean",
            "nullable": true,
            "description": "주소가 알려진 유출 사고에 나타난 경우 `true`입니다."
          },
          "no_of_breaches": {
            "type": "number",
            "nullable": true,
            "description": "해당 주소가 포함된 알려진 유출 건수입니다."
          },
          "reason_codes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "description": "신호의 안정적인 Didit 식별자입니다(예: `IR-5AC67A32`). 불투명한 값이므로 구문 분석하지 말고 그룹화 및 필터링에만 사용하세요."
                },
                "value": {
                  "nullable": true,
                  "description": "위험 플래그(예: `voip`, `leaked`, `disposable`, `spam_trap`)의 경우 해당 값: boolean, 수준 또는 날짜입니다. 점수가 산정된 사유 코드의 경우 null입니다."
                },
                "direction": {
                  "type": "string",
                  "enum": [
                    "risk",
                    "trust"
                  ],
                  "description": "신호가 위험을 높였는지 또는 신뢰도를 높였는지 여부입니다."
                },
                "message": {
                  "type": "string",
                  "description": "신호에 대한 사람이 읽기 쉬운 영어 설명입니다."
                },
                "impact_level": {
                  "type": "string",
                  "nullable": true,
                  "description": "시그널이 점수를 얼마나 크게 변동시켰는지 나타내며, 예를 들어 `low`, `medium`, `high` 등이 있습니다."
                }
              }
            },
            "description": "점수를 설명하는 신호 목록으로, 각각 안정적인 Didit 코드, 방향, 메시지 및 영향 수준을 포함합니다. 새로운 코드가 점진적으로 추가될 수 있으므로 알 수 없는 코드를 거부하지 마세요."
          }
        }
      },
      "IPRiskResult": {
        "type": "object",
        "description": "IP 위험 결과입니다. 조회를 통해 사용할 수 있는 데이터가 반환되지 않은 경우 개별 보강 필드는 `null`일 수 있습니다.",
        "required": [
          "status",
          "threat"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "In Review"
            ],
            "description": "확인된 국가가 `claimed_country`와 충돌하거나, 주소가 VPN, Tor 또는 데이터 센터 인프라와 연결된 경우 `In Review`. 그렇지 않으면 `Approved`."
          },
          "ip_address": {
            "type": "string",
            "nullable": true,
            "description": "점수가 산정된 주소입니다. 사용 가능한 데이터를 반환한 보강 소스가 없는 경우 `null`입니다."
          },
          "ip_country": {
            "type": "string",
            "nullable": true,
            "description": "확인된 국가명입니다."
          },
          "ip_country_code": {
            "type": "string",
            "nullable": true,
            "description": "확인된 국가 코드입니다. 국가 문자열 원본을 직접 비교하는 대신 `country_mismatch`를 통해 국가를 비교하십시오."
          },
          "ip_state": {
            "type": "string",
            "nullable": true,
            "description": "확인된 주 또는 지역입니다."
          },
          "ip_city": {
            "type": "string",
            "nullable": true,
            "description": "확인된 도시입니다."
          },
          "latitude": {
            "type": "number",
            "nullable": true,
            "description": "대략적인 네트워크 지리적 위치이며, 정밀한 기기 위치가 아닙니다."
          },
          "longitude": {
            "type": "number",
            "nullable": true,
            "description": "대략적인 네트워크 지리적 위치이며, 정밀한 기기 위치가 아닙니다."
          },
          "isp": {
            "type": "string",
            "nullable": true,
            "description": "해당 주소에 서비스를 제공하는 인터넷 서비스 제공업체입니다."
          },
          "organization": {
            "type": "string",
            "nullable": true,
            "description": "주소 블록을 소유한 조직입니다."
          },
          "is_vpn_or_tor": {
            "type": "boolean",
            "nullable": true,
            "description": "주소가 VPN 또는 Tor 인프라와 연결되어 있는 경우 `true`입니다."
          },
          "is_data_center": {
            "type": "boolean",
            "nullable": true,
            "description": "주소가 호스팅 또는 데이터 센터 네트워크에 속한 경우 `true`입니다."
          },
          "time_zone": {
            "type": "string",
            "nullable": true,
            "description": "확인된 위치의 시간대입니다."
          },
          "time_zone_offset": {
            "type": "string",
            "nullable": true,
            "description": "확인된 위치의 UTC 오프셋입니다."
          },
          "asn_number": {
            "type": "number",
            "nullable": true,
            "description": "자율 시스템 번호(ASN)입니다."
          },
          "asn_organization": {
            "type": "string",
            "nullable": true,
            "description": "자율 시스템을 운영하는 조직입니다."
          },
          "connection_type": {
            "type": "string",
            "nullable": true,
            "description": "연결 분류(예: `cellular`, `hosting`)입니다."
          },
          "carrier": {
            "type": "string",
            "nullable": true,
            "description": "주소가 모바일 네트워크에 속하는 경우의 이동통신사입니다."
          },
          "proxy_type": {
            "type": "string",
            "nullable": true,
            "description": "주소가 프록시 뒤에 있을 때의 프록시 분류입니다."
          },
          "claimed_country": {
            "type": "string",
            "nullable": true,
            "description": "전송한 `claimed_country`의 에코 값입니다."
          },
          "country_mismatch": {
            "type": "boolean",
            "nullable": true,
            "description": "확인된 국가가 `claimed_country`와 다를 때 `true`입니다. 보강 데이터가 없거나 주장된 국가가 없는 경우 `null`입니다."
          },
          "threat": {
            "type": "object",
            "additionalProperties": true,
            "description": "데이터 보강 소스에서 제공되는 자유 형식 네트워크 위협 증거(예: `is_proxy`, `is_tor`)입니다. 보강 데이터를 사용할 수 없는 경우 빈 객체입니다. 안정적인 규약이 아닌 진단 세부 정보로 취급하십시오."
          }
        }
      },
      "PhoneRiskResponse": {
        "type": "object",
        "required": [
          "request_id",
          "status",
          "created_at"
        ],
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 요청에 대해 생성된 API 세션의 ID입니다. 결과를 향후의 webhook이나 콘솔 활동과 연결해야 하는 경우 `vendor_data`와 함께 저장하세요."
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "In Review",
              "Declined"
            ],
            "description": "이 API 세션의 최종 결정입니다. 일반적으로 `Approved`이며, 위험 평가에 따라 `In Review` 또는 `Declined`가 생성될 수 있습니다."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "전송한 `vendor_data`의 에코 값이며, 전송하지 않은 경우 `null`입니다."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "전송한 `metadata`의 에코 값이며, 전송하지 않은 경우 `null`입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "이 응답의 타임스탬프입니다."
          },
          "phone": {
            "type": "object",
            "description": "전화번호 인증 응답에서 사용되는 것과 동일한 블록인 정규화된 전화번호 보고서입니다.",
            "required": [
              "status"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "Approved",
                  "In Review",
                  "Declined"
                ],
                "description": "이 전화번호에 대한 결정입니다. 최상위 `status`를 반영합니다."
              },
              "phone_number_prefix": {
                "type": "string",
                "description": "`+`로 시작하는 국가 전화번호 코드(예: `+1`)입니다.",
                "example": "+1"
              },
              "phone_number": {
                "type": "string",
                "description": "국가 전화 코드를 제외한 국내 번호.",
                "example": "4155552671"
              },
              "full_number": {
                "type": "string",
                "description": "E.164 형식의 전체 번호입니다.",
                "example": "+14155552671"
              },
              "country_code": {
                "type": "string",
                "nullable": true,
                "description": "해당 번호의 ISO 3166-1 alpha-2 국가 코드입니다.",
                "example": "US"
              },
              "country_name": {
                "type": "string",
                "description": "`country_code`에서 파생된 전체 국가명입니다.",
                "example": "United States"
              },
              "carrier": {
                "type": "object",
                "nullable": true,
                "description": "해당 번호를 서비스하는 현재 네트워크입니다. 조회를 통해 통신사를 확인할 수 없는 경우 `null`입니다.",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "통신사 이름. 조회 시 식별할 수 없는 경우 빈 문자열입니다."
                  },
                  "type": {
                    "type": "string",
                    "description": "조회 결과로 보고된 회선 유형: `mobile`, `fixed_line`, `voip`, `isp`, `vpn`, `toll_free`, `premium_rate`, 또는 이와 유사한 유형."
                  }
                }
              },
              "is_disposable": {
                "type": "boolean",
                "description": "번호가 임시 번호 또는 버너 번호 서비스에 속하는 경우 `true`입니다."
              },
              "is_virtual": {
                "type": "boolean",
                "description": "회선 유형이 가상(`voip`, `isp` 또는 `vpn`)인 경우 `true`입니다."
              },
              "verification_method": {
                "type": "string",
                "nullable": true,
                "description": "기반이 되는 인증의 OTP 채널입니다. 코드를 보내지 않는 위험 조회의 경우 `null`입니다."
              },
              "verification_attempts": {
                "type": "integer",
                "description": "이 번호에 대한 OTP 전송 횟수입니다. 위험 조회의 경우 `0`입니다."
              },
              "verified_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "해당 번호가 OTP를 통해 마지막으로 인증된 시점입니다. 위험도 조회의 경우 `null`입니다."
              },
              "warnings": {
                "type": "array",
                "description": "이 요청에 대해 기록된 위험 경고. 없을 경우 빈 배열입니다.",
                "items": {
                  "$ref": "#/components/schemas/RiskWarning"
                }
              },
              "lifecycle": {
                "type": "array",
                "description": "요청의 시간순 감사 로그입니다. 전송 이벤트가 없는 위험 조회의 경우 빈 배열입니다.",
                "items": {
                  "$ref": "#/components/schemas/RiskLifecycleEvent"
                }
              },
              "matches": {
                "type": "array",
                "description": "다른 사용자(다른 `vendor_data`)가 동일한 전화번호를 사용한 애플리케이션의 다른 세션입니다. 최대 5개 항목입니다. 일치하는 항목이 없으면 빈 배열입니다.",
                "items": {
                  "$ref": "#/components/schemas/PhoneMatchItem"
                }
              },
              "phone_intelligence": {
                "$ref": "#/components/schemas/PhoneIntelligence"
              },
              "enrichment": {
                "$ref": "#/components/schemas/PhoneIntelligence"
              },
              "phone_social": {
                "$ref": "#/components/schemas/PhoneSocialFootprint"
              }
            }
          }
        }
      },
      "EmailRiskResponse": {
        "type": "object",
        "required": [
          "request_id",
          "status",
          "created_at"
        ],
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 요청에 대해 생성된 API 세션의 ID입니다. 결과를 향후의 webhook이나 콘솔 활동과 연결해야 하는 경우 `vendor_data`와 함께 저장하세요."
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "In Review",
              "Declined"
            ],
            "description": "이 API 세션의 최종 결정입니다. 일반적으로 `Approved`이며, 위험 평가에 따라 `In Review` 또는 `Declined`가 생성될 수 있습니다."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "전송한 `vendor_data`의 에코 값이며, 전송하지 않은 경우 `null`입니다."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "전송한 `metadata`의 에코 값이며, 전송하지 않은 경우 `null`입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "이 응답의 타임스탬프입니다."
          },
          "email": {
            "type": "object",
            "description": "이메일 인증 응답에서 사용되는 것과 동일한 블록인 정규화된 이메일 보고서입니다.",
            "required": [
              "status",
              "email",
              "is_breached",
              "breaches",
              "is_disposable",
              "is_undeliverable"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "Approved",
                  "In Review",
                  "Declined"
                ],
                "description": "이 이메일 주소에 대한 결정입니다. 최상위 `status`를 반영합니다."
              },
              "email": {
                "type": "string",
                "description": "점수가 산정된 주소입니다.",
                "example": "alice@example.com"
              },
              "is_breached": {
                "type": "boolean",
                "description": "주소가 알려진 자격 증명 유출에 나타나는지 여부입니다."
              },
              "breaches": {
                "type": "array",
                "description": "이 주소를 포함하는 가장 최근의 알려진 침해 사례 최대 5건입니다. `is_breached`가 `false`이면 빈 배열입니다.",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "침해 식별자입니다."
                    },
                    "domain": {
                      "type": "string",
                      "description": "침해된 서비스의 도메인입니다."
                    },
                    "breach_date": {
                      "type": "string",
                      "format": "date",
                      "description": "위반이 발생한 일자입니다."
                    },
                    "breach_emails_count": {
                      "type": "integer",
                      "description": "유출 사건에서 노출된 계정의 총 개수입니다."
                    },
                    "description": {
                      "type": "string",
                      "description": "침해에 대한 사람이 읽기 쉬운 설명입니다(HTML 마크업을 포함할 수 있음)."
                    },
                    "logo_path": {
                      "type": "string",
                      "description": "침해된 서비스 로고의 URL입니다."
                    },
                    "data_classes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "노출된 데이터의 카테고리(snake_case 형식, 예: `email_addresses`, `passwords`)."
                    },
                    "is_verified": {
                      "type": "boolean",
                      "description": "유출이 사실인 것으로 확인되었는지 여부입니다."
                    }
                  }
                }
              },
              "is_disposable": {
                "type": "boolean",
                "description": "도메인이 일회용 제공업체에 속하는지 여부입니다."
              },
              "is_undeliverable": {
                "type": "boolean",
                "description": "주소로 전송할 수 없는 것으로 확인되었는지 여부입니다."
              },
              "verification_attempts": {
                "type": "integer",
                "description": "이 주소에 대한 OTP 전송 횟수입니다. 위험 조회의 경우 `0`입니다."
              },
              "verified_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "주소가 OTP를 통해 마지막으로 인증된 시점입니다. 위험 조회의 경우 `null`입니다."
              },
              "warnings": {
                "type": "array",
                "description": "이 요청에 대해 기록된 위험 경고. 없을 경우 빈 배열입니다.",
                "items": {
                  "$ref": "#/components/schemas/RiskWarning"
                }
              },
              "lifecycle": {
                "type": "array",
                "description": "요청의 시간순 감사 로그입니다. 전송이 없는 위험 조회의 경우 빈 배열입니다.",
                "items": {
                  "$ref": "#/components/schemas/RiskLifecycleEvent"
                }
              },
              "matches": {
                "type": "array",
                "description": "다른 사용자(다른 `vendor_data`)가 동일한 이메일 주소를 사용한 애플리케이션의 다른 세션입니다. 최대 5개 항목입니다. 일치하는 항목이 없으면 빈 배열입니다.",
                "items": {
                  "$ref": "#/components/schemas/EmailMatchItem"
                }
              },
              "email_intelligence": {
                "$ref": "#/components/schemas/EmailIntelligence"
              },
              "enrichment": {
                "$ref": "#/components/schemas/EmailIntelligence"
              },
              "email_social": {
                "$ref": "#/components/schemas/EmailSocialFootprint"
              }
            }
          }
        }
      },
      "IPRiskResponse": {
        "type": "object",
        "required": [
          "request_id",
          "status",
          "created_at"
        ],
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 요청에 대해 생성된 API 세션의 ID입니다. 결과를 향후의 webhook이나 콘솔 활동과 연결해야 하는 경우 `vendor_data`와 함께 저장하세요."
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "In Review"
            ],
            "description": "이 API 세션에 대한 결정: 네트워크 또는 국가 불일치 위험이 있는 경우 `In Review`, 그렇지 않으면 `Approved`입니다."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "전송한 `vendor_data`의 에코 값이며, 전송하지 않은 경우 `null`입니다."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "전송한 `metadata`의 에코 값이며, 전송하지 않은 경우 `null`입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "이 응답의 타임스탬프입니다."
          },
          "ip": {
            "type": "object",
            "description": "IP 위험 결과입니다. 조회를 통해 사용할 수 있는 데이터가 반환되지 않은 경우 개별 보강 필드는 `null`일 수 있습니다.",
            "required": [
              "status",
              "threat"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "Approved",
                  "In Review"
                ],
                "description": "확인된 국가가 `claimed_country`와 충돌하거나, 주소가 VPN, Tor 또는 데이터 센터 인프라와 연결된 경우 `In Review`. 그렇지 않으면 `Approved`."
              },
              "ip_address": {
                "type": "string",
                "nullable": true,
                "description": "점수가 산정된 주소입니다. 사용 가능한 데이터를 반환한 보강 소스가 없는 경우 `null`입니다."
              },
              "ip_country": {
                "type": "string",
                "nullable": true,
                "description": "확인된 국가명입니다."
              },
              "ip_country_code": {
                "type": "string",
                "nullable": true,
                "description": "확인된 국가 코드입니다. 국가 문자열 원본을 직접 비교하는 대신 `country_mismatch`를 통해 국가를 비교하십시오."
              },
              "ip_state": {
                "type": "string",
                "nullable": true,
                "description": "확인된 주 또는 지역입니다."
              },
              "ip_city": {
                "type": "string",
                "nullable": true,
                "description": "확인된 도시입니다."
              },
              "latitude": {
                "type": "number",
                "nullable": true,
                "description": "대략적인 네트워크 지리적 위치이며, 정밀한 기기 위치가 아닙니다."
              },
              "longitude": {
                "type": "number",
                "nullable": true,
                "description": "대략적인 네트워크 지리적 위치이며, 정밀한 기기 위치가 아닙니다."
              },
              "isp": {
                "type": "string",
                "nullable": true,
                "description": "해당 주소에 서비스를 제공하는 인터넷 서비스 제공업체입니다."
              },
              "organization": {
                "type": "string",
                "nullable": true,
                "description": "주소 블록을 소유한 조직입니다."
              },
              "is_vpn_or_tor": {
                "type": "boolean",
                "nullable": true,
                "description": "주소가 VPN 또는 Tor 인프라와 연결되어 있는 경우 `true`입니다."
              },
              "is_data_center": {
                "type": "boolean",
                "nullable": true,
                "description": "주소가 호스팅 또는 데이터 센터 네트워크에 속한 경우 `true`입니다."
              },
              "time_zone": {
                "type": "string",
                "nullable": true,
                "description": "확인된 위치의 시간대입니다."
              },
              "time_zone_offset": {
                "type": "string",
                "nullable": true,
                "description": "확인된 위치의 UTC 오프셋입니다."
              },
              "asn_number": {
                "type": "number",
                "nullable": true,
                "description": "자율 시스템 번호(ASN)입니다."
              },
              "asn_organization": {
                "type": "string",
                "nullable": true,
                "description": "자율 시스템을 운영하는 조직입니다."
              },
              "connection_type": {
                "type": "string",
                "nullable": true,
                "description": "연결 분류(예: `cellular`, `hosting`)입니다."
              },
              "carrier": {
                "type": "string",
                "nullable": true,
                "description": "주소가 모바일 네트워크에 속하는 경우의 이동통신사입니다."
              },
              "proxy_type": {
                "type": "string",
                "nullable": true,
                "description": "주소가 프록시 뒤에 있을 때의 프록시 분류입니다."
              },
              "claimed_country": {
                "type": "string",
                "nullable": true,
                "description": "전송한 `claimed_country`의 에코 값입니다."
              },
              "country_mismatch": {
                "type": "boolean",
                "nullable": true,
                "description": "확인된 국가가 `claimed_country`와 다를 때 `true`입니다. 보강 데이터가 없거나 주장된 국가가 없는 경우 `null`입니다."
              },
              "threat": {
                "type": "object",
                "additionalProperties": true,
                "description": "데이터 보강 소스에서 제공되는 자유 형식 네트워크 위협 증거(예: `is_proxy`, `is_tor`)입니다. 보강 데이터를 사용할 수 없는 경우 빈 객체입니다. 안정적인 규약이 아닌 진단 세부 정보로 취급하십시오."
              }
            }
          }
        }
      },
      "SocialFootprintPlatform": {
        "type": "object",
        "properties": {
          "platform": {
            "type": "string",
            "description": "플랫폼 식별자입니다.",
            "example": "whatsapp"
          },
          "category": {
            "type": "string",
            "description": "플랫폼 카테고리(예: MESSAGING, SOCIAL_MEDIA, ECOMMERCE, PROFESSIONAL, EMAIL_PROVIDER)입니다.",
            "example": "MESSAGING"
          },
          "scope": {
            "type": "string",
            "enum": [
              "global",
              "local"
            ],
            "description": "글로벌 플랫폼의 경우 `global`, 특정 지역 플랫폼의 경우 `local`.",
            "example": "global"
          }
        }
      },
      "SocialFootprintCategorySummary": {
        "type": "object",
        "properties": {
          "registered": {
            "type": "integer",
            "nullable": true,
            "description": "이 카테고리에서 가입이 확인된 플랫폼입니다.",
            "example": 2
          },
          "ratio": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "description": "해당 카테고리에서 확인된 플랫폼 중 등록이 있는 플랫폼의 비율(0.0-1.0)입니다.",
            "example": 0.6667
          }
        }
      },
      "SocialFootprintProfile": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true,
            "description": "플랫폼에서 제공하는 경우 프로필 이름입니다."
          },
          "photo": {
            "type": "string",
            "nullable": true,
            "description": "플랫폼에서 제공하는 경우 프로필 사진 URL입니다."
          },
          "about": {
            "type": "string",
            "nullable": true,
            "description": "플랫폼에서 제공하는 경우 프로필 소개/약력 텍스트입니다."
          },
          "privacy_status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "PUBLIC",
              "PRIVATE",
              null
            ],
            "description": "플랫폼에서 제공하는 경우 프로필 공개 여부입니다."
          },
          "business_account": {
            "type": "boolean",
            "nullable": true,
            "description": "플랫폼에서 정보를 제공하는 경우, 프로필이 비즈니스 계정인지 여부입니다."
          }
        }
      },
      "PhoneSocialFootprint": {
        "type": "object",
        "nullable": true,
        "description": "전화번호의 소셜 풋프린트(등록된 온라인 플랫폼)입니다. `enable_social`이 설정되고 확인이 완료된 경우에만 표시됩니다. 반환된 데이터가 없는 경우 각 개수는 null일 수 있습니다. `profiles_registered: 0`은 플랫폼을 확인했으나 해당 전화번호가 어떤 플랫폼에서도 발견되지 않았음을 의미하며, 이는 유효하고 요금이 청구되는 응답이자 흔히 나타나는 합성 신원 신호입니다.",
        "properties": {
          "profiles_registered": {
            "type": "integer",
            "nullable": true,
            "description": "전화번호 등록이 확인된 플랫폼입니다.",
            "example": 5
          },
          "profiles_checked": {
            "type": "integer",
            "nullable": true,
            "description": "가입 여부가 평가된 플랫폼입니다.",
            "example": 14
          },
          "names_found": {
            "type": "integer",
            "nullable": true,
            "description": "관련 이름을 반환한 플랫폼입니다.",
            "example": 0
          },
          "photos_found": {
            "type": "integer",
            "nullable": true,
            "description": "프로필 사진을 반환한 플랫폼입니다.",
            "example": 0
          },
          "communication_breadth": {
            "type": "integer",
            "nullable": true,
            "description": "존재가 감지된 커뮤니케이션 플랫폼입니다.",
            "example": 2
          },
          "digital_footprint_diversity": {
            "type": "integer",
            "nullable": true,
            "description": "존재가 감지된 고유한 플랫폼 카테고리입니다.",
            "example": 5
          },
          "digital_sophistication_index": {
            "type": "integer",
            "nullable": true,
            "description": "복합 디지털 성숙도 지표(0-10)입니다.",
            "example": 5
          },
          "engagement_depth_index": {
            "type": "integer",
            "nullable": true,
            "description": "프로필 정보량 지표, 0-10.",
            "example": 3
          },
          "subscription_affordability_index": {
            "type": "integer",
            "nullable": true,
            "description": "무료 대 유료 플랫폼 비율(0-10)입니다.",
            "example": 2
          },
          "free_platforms": {
            "type": "integer",
            "nullable": true,
            "description": "무료 플랫폼에서의 등록 수입니다.",
            "example": 4
          },
          "full_paid_platforms": {
            "type": "integer",
            "nullable": true,
            "description": "완전 유료 플랫폼에서의 등록 수입니다.",
            "example": 0
          },
          "partial_paid_platforms": {
            "type": "integer",
            "nullable": true,
            "description": "프리미엄(freemium) 플랫폼에서의 등록 수입니다.",
            "example": 1
          },
          "whatsapp_profile_completeness": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Basic",
              "Partial",
              "Complete",
              "Not Present",
              null
            ],
            "description": "WhatsApp 프로필의 완성도입니다. 전화번호 전용이며 이메일의 경우 null입니다.",
            "example": "Partial"
          },
          "registered_platforms": {
            "type": "array",
            "description": "가입이 확인된 플랫폼입니다.",
            "items": {
              "$ref": "#/components/schemas/SocialFootprintPlatform"
            }
          },
          "not_registered_platforms": {
            "type": "array",
            "description": "부정적인 결과가 반환된 플랫폼입니다.",
            "items": {
              "$ref": "#/components/schemas/SocialFootprintPlatform"
            }
          },
          "categories": {
            "type": "object",
            "description": "플랫폼 카테고리별 등록 수 및 비율입니다.",
            "additionalProperties": {
              "$ref": "#/components/schemas/SocialFootprintCategorySummary"
            }
          },
          "profiles": {
            "type": "object",
            "description": "플랫폼에서 프로필 세부 정보를 제공하는 경우, 플랫폼을 키로 하는 플랫폼별 프로필 세부 정보입니다.",
            "additionalProperties": {
              "$ref": "#/components/schemas/SocialFootprintProfile"
            }
          }
        }
      },
      "EmailSocialFootprint": {
        "type": "object",
        "nullable": true,
        "description": "이메일 주소의 소셜 풋프린트(등록된 온라인 플랫폼)입니다. `enable_social`이 설정되고 확인이 완료된 경우에만 표시됩니다. 반환된 데이터가 없는 경우 각 개수는 null일 수 있습니다. `profiles_registered: 0`은 플랫폼을 확인했으나 해당 이메일 주소가 어떤 플랫폼에서도 발견되지 않았음을 의미하며, 이는 유효하고 요금이 청구되는 응답이자 흔히 나타나는 합성 신원 신호입니다.",
        "properties": {
          "profiles_registered": {
            "type": "integer",
            "nullable": true,
            "description": "이메일 주소 등록이 확인된 플랫폼입니다.",
            "example": 5
          },
          "profiles_checked": {
            "type": "integer",
            "nullable": true,
            "description": "가입 여부가 평가된 플랫폼입니다.",
            "example": 14
          },
          "names_found": {
            "type": "integer",
            "nullable": true,
            "description": "관련 이름을 반환한 플랫폼입니다.",
            "example": 0
          },
          "photos_found": {
            "type": "integer",
            "nullable": true,
            "description": "프로필 사진을 반환한 플랫폼입니다.",
            "example": 0
          },
          "communication_breadth": {
            "type": "integer",
            "nullable": true,
            "description": "존재가 감지된 커뮤니케이션 플랫폼입니다.",
            "example": 2
          },
          "digital_footprint_diversity": {
            "type": "integer",
            "nullable": true,
            "description": "존재가 감지된 고유한 플랫폼 카테고리입니다.",
            "example": 5
          },
          "digital_sophistication_index": {
            "type": "integer",
            "nullable": true,
            "description": "복합 디지털 성숙도 지표(0-10)입니다.",
            "example": 5
          },
          "engagement_depth_index": {
            "type": "integer",
            "nullable": true,
            "description": "프로필 정보량 지표, 0-10.",
            "example": 3
          },
          "subscription_affordability_index": {
            "type": "integer",
            "nullable": true,
            "description": "무료 대 유료 플랫폼 비율(0-10)입니다.",
            "example": 2
          },
          "free_platforms": {
            "type": "integer",
            "nullable": true,
            "description": "무료 플랫폼에서의 등록 수입니다.",
            "example": 4
          },
          "full_paid_platforms": {
            "type": "integer",
            "nullable": true,
            "description": "완전 유료 플랫폼에서의 등록 수입니다.",
            "example": 0
          },
          "partial_paid_platforms": {
            "type": "integer",
            "nullable": true,
            "description": "프리미엄(freemium) 플랫폼에서의 등록 수입니다.",
            "example": 1
          },
          "whatsapp_profile_completeness": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Basic",
              "Partial",
              "Complete",
              "Not Present",
              null
            ],
            "description": "WhatsApp 프로필의 완성도입니다. 전화번호 전용이며 이메일의 경우 null입니다.",
            "example": "Partial"
          },
          "registered_platforms": {
            "type": "array",
            "description": "가입이 확인된 플랫폼입니다.",
            "items": {
              "$ref": "#/components/schemas/SocialFootprintPlatform"
            }
          },
          "not_registered_platforms": {
            "type": "array",
            "description": "부정적인 결과가 반환된 플랫폼입니다.",
            "items": {
              "$ref": "#/components/schemas/SocialFootprintPlatform"
            }
          },
          "categories": {
            "type": "object",
            "description": "플랫폼 카테고리별 등록 수 및 비율입니다.",
            "additionalProperties": {
              "$ref": "#/components/schemas/SocialFootprintCategorySummary"
            }
          },
          "profiles": {
            "type": "object",
            "description": "플랫폼에서 프로필 세부 정보를 제공하는 경우, 플랫폼을 키로 하는 플랫폼별 프로필 세부 정보입니다.",
            "additionalProperties": {
              "$ref": "#/components/schemas/SocialFootprintProfile"
            }
          }
        }
      },
      "KYBRegistryAddress": {
        "type": "object",
        "description": "등기부에 기재된 주소로, 모든 국가 및 등기부 소스에 대해 동일한 형식입니다. 모든 키가 항상 존재하며, 등기부에서 공개하지 않는 부분은 null입니다.",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true,
            "description": "소문자로 표시된 주소 유형: 본점 소재지의 경우 `registered`, 기타 유형은 법인 등기부에 기재된 명칭(예: `postal`, `office`)을 따릅니다. 등기부에 주소 유형이 명시되지 않은 경우 `null`입니다."
          },
          "address": {
            "type": "string",
            "description": "한 줄로 작성된 전체 주소입니다. 모든 주소에 항상 존재합니다."
          },
          "street": {
            "type": "string",
            "nullable": true,
            "description": "도로명 및 번호."
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "시 또는 지역입니다."
          },
          "postal_code": {
            "type": "string",
            "nullable": true,
            "description": "우편번호입니다."
          },
          "region": {
            "type": "string",
            "nullable": true,
            "description": "지역, 주 또는 도입니다."
          },
          "country_code": {
            "type": "string",
            "nullable": true,
            "description": "ISO 3166-1 alpha-2 국가 코드입니다."
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "주소에 대해 등기소 자체에서 제공한 라벨(있는 경우)입니다."
          }
        },
        "required": [
          "type",
          "address",
          "street",
          "city",
          "postal_code",
          "region",
          "country_code",
          "description"
        ]
      },
      "KYBRegistryIndustry": {
        "type": "object",
        "description": "등기부에서 기업을 분류한 업종 활동으로, 모든 국가 및 등기부 소스에 대해 동일한 형식입니다.",
        "properties": {
          "code": {
            "type": "string",
            "nullable": true,
            "description": "등기부에 기재된 업종 코드입니다(예: `73110`)."
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "등기부에서 공개한 경우의 업종 라벨입니다."
          },
          "scheme": {
            "type": "string",
            "nullable": true,
            "description": "분류 체계(보고한 출처와 관계없이 체계당 하나의 이름 사용): `UK SIC 2007`, `US SIC`, `NACE Rev. 2`, `NACE Rev. 2.1`, `NAF Rev. 2`, `CNAE`, `SBI`, `NOGA 2008`, `CAE Rev. 4`, `Canada SIC 1977`. 기타 국가 체계는 등기부 자체 이름을 유지합니다. 등기부에서 체계 이름을 지정하지 않은 경우 null입니다."
          },
          "is_primary": {
            "type": "boolean",
            "description": "기업의 주요 활동인 경우 true입니다. 목록이 비어 있지 않은 경우 정확히 하나의 항목이 주요 활동입니다."
          }
        },
        "required": [
          "code",
          "description",
          "scheme",
          "is_primary"
        ]
      },
      "KYBRegistryShareholding": {
        "type": "object",
        "nullable": true,
        "description": "모든 국가 및 법인 등기부 출처에 대해 동일한 형식으로 제공되는 소유자의 보유 내역입니다. 등기부에 보유 내역이 명시되어 있지 않은 경우 null입니다. 범위(예: 영국 PSC의 25-50%)는 지분이 아닙니다. `percentage`는 null이며 해당 범위는 `ownership_min_shares` / `ownership_max_shares`에 유지됩니다.",
        "properties": {
          "share_class": {
            "type": "string",
            "nullable": true,
            "description": "등기부에서 명시한 주식 종류 또는 유형입니다."
          },
          "number_of_shares": {
            "type": "number",
            "nullable": true,
            "description": "보유 주식 수입니다."
          },
          "currency": {
            "type": "string",
            "nullable": true,
            "description": "아래 값의 ISO 4217 통화입니다."
          },
          "nominal_value": {
            "type": "number",
            "nullable": true,
            "description": "주당 액면가."
          },
          "total_value": {
            "type": "number",
            "nullable": true,
            "description": "보유 자산의 총 가치입니다."
          },
          "percentage": {
            "type": "number",
            "nullable": true,
            "description": "소수점 넷째 자리까지 표시된 정확한 지분율(%)입니다."
          }
        },
        "required": [
          "share_class",
          "number_of_shares",
          "currency",
          "nominal_value",
          "total_value",
          "percentage"
        ]
      },
      "KYBRegistryOwnership": {
        "type": "object",
        "description": "모든 국가 및 등기부 출처에 대해 동일한 형식으로 제공되는 소유 구조(주주 / UBO) 등급의 결과입니다.",
        "properties": {
          "status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "not_requested",
              "pending",
              "delivered",
              "not_held",
              "unavailable",
              null
            ],
            "description": "등기소가 소유 구조를 공개한 경우 `delivered`, 소유 구조 등기소가 응답했으나 기업이 전혀 등재되어 있지 않은 경우 `not_held`(`unavailable_reason` 참조), 그 외의 사유로 소유 구조 데이터를 제공하지 않은 경우 `unavailable`(`unavailable_reason` 참조), 등기소에서 아직 조회 중인 경우 `pending`, Basic 등급인 경우 `not_requested`."
          },
          "tier_requested": {
            "type": "string",
            "nullable": true,
            "enum": [
              "basic",
              "shareholders",
              "ubo",
              null
            ],
            "description": "워크플로가 주문한 등급입니다."
          },
          "tier_delivered": {
            "type": "string",
            "nullable": true,
            "enum": [
              "basic",
              "shareholders",
              "ubo",
              null
            ],
            "description": "등기부에서 제공한(그리고 결제 청구되는) 등급입니다. 직접 주주만으로 응답된 UBO 요청은 `shareholders`가 됩니다."
          },
          "unavailable_reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "no_owners_on_record",
              "no_natural_person_owner",
              "ownership_section_unavailable",
              "company_not_found",
              "ambiguous_company_match",
              "missing_registration_number",
              "entity_type_not_covered",
              "provider_unavailable",
              "other",
              null
            ],
            "description": "요청된 소유 구조 등급이 제공되지 않은 이유입니다. `status`가 `unavailable` 또는 `pending`이 아닌 경우 null입니다."
          },
          "direct_ownership_complete": {
            "type": "boolean",
            "nullable": true,
            "description": "직접 주주의 명시된 지분 합계가 100%인 경우(반올림 오차 1퍼센트포인트 이내) true, 그렇지 않은 경우 false, 소유 구조가 전송되지 않았거나 지분이 명시되지 않은 경우 null입니다."
          },
          "unresolved": {
            "type": "array",
            "description": "법인 등기부에서 확인할 수 없는 소유 구조 체인의 일부(예: 직접 소유자 상위의 그룹 구조가 기록에 없음)입니다.",
            "items": {
              "type": "object",
              "properties": {
                "reason": {
                  "type": "string"
                },
                "section": {
                  "type": "string",
                  "nullable": true
                }
              }
            }
          }
        },
        "required": [
          "status",
          "tier_requested",
          "tier_delivered",
          "unavailable_reason",
          "direct_ownership_complete",
          "unresolved"
        ]
      },
      "KYBRegistryData": {
        "type": "object",
        "nullable": true,
        "description": "기업에 대한 Didit의 정규화된 법인 등기부 세부 정보입니다: 소유 구조 결과(`ownership_error`, `section_errors`, `ubo_resolution`, `lite_enrichment`), update-data로 수정된 내용 및 자체 필드가 없는 등기부 사실 정보가 포함됩니다. 등기부 소스 자체의 원본 레코드는 절대 포함되지 않습니다. 모든 키는 선택 사항이며 기업에 해당 값이 있는 경우에만 표시됩니다. 새로운 키가 추가될 수 있습니다. 해당 필드가 다루는 내용에 대해서는 표준 필드(`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`)를 확인하세요.",
        "properties": {
          "company_name": {
            "type": "string",
            "description": "Console에서 수정한 기업명입니다."
          },
          "registration_number": {
            "type": "string",
            "description": "법인 등기부 또는 콘솔 수정사항에 명시된 등록번호입니다."
          },
          "country_code": {
            "type": "string",
            "description": "등기부 또는 콘솔 수정 사항에 명시된 등록 국가입니다."
          },
          "region": {
            "type": "string",
            "description": "등록 지역 또는 주입니다."
          },
          "incorporation_date": {
            "type": "string",
            "description": "설립일(ISO 8601)."
          },
          "registration_date": {
            "type": "string",
            "description": "법인 등기부에서 설립일 외에 별도로 명시한 등록일(ISO 8601)입니다."
          },
          "dissolution_date": {
            "type": "string",
            "description": "등기부에 기재된 경우의 해산일(ISO 8601)입니다."
          },
          "tax_number": {
            "type": "string",
            "description": "납세자 번호입니다."
          },
          "vat_number": {
            "type": "string",
            "description": "VAT 번호입니다."
          },
          "legal_address": {
            "type": "string",
            "description": "콘솔에서 수정된 법적 주소입니다."
          },
          "registered_address": {
            "type": "string",
            "description": "등기부에 기재된 등록 주소입니다."
          },
          "company_type": {
            "type": "string",
            "description": "법적 형태입니다."
          },
          "registry_status": {
            "type": "string",
            "description": "법인 등기부상의 기업 상태입니다."
          },
          "verification_status": {
            "type": "string",
            "description": "인증 상태입니다."
          },
          "alternative_names": {
            "type": "string",
            "description": "기업이 거래에 사용하거나 사용했던 다른 상호입니다."
          },
          "nature_of_business": {
            "type": "string",
            "description": "업종 설명입니다."
          },
          "registered_capital": {
            "type": "string",
            "description": "인쇄된 자본금입니다."
          },
          "registered_capital_amount": {
            "type": "string",
            "description": "십진수 문자열 형태의 자본금 금액입니다."
          },
          "registered_capital_currency": {
            "type": "string",
            "description": "자본금 통화(ISO 4217)입니다."
          },
          "website": {
            "type": "string",
            "description": "웹사이트입니다."
          },
          "email": {
            "type": "string",
            "description": "연락처 이메일입니다."
          },
          "phone": {
            "type": "string",
            "description": "연락처 전화번호입니다."
          },
          "legal_entity_identifier": {
            "type": "string",
            "description": "법인식별기호(LEI)."
          },
          "location_of_registration": {
            "type": "string",
            "description": "등록지입니다."
          },
          "control_scheme": {
            "type": "string",
            "description": "등기소에서 공개하는 경우 거버넌스 체계입니다."
          },
          "ownership_error": {
            "type": "string",
            "enum": [
              "no_owners_on_record",
              "no_natural_person_owner",
              "ownership_section_unavailable",
              "company_not_found",
              "ambiguous_company_match",
              "missing_registration_number",
              "entity_type_not_covered",
              "provider_unavailable",
              "other"
            ],
            "description": "요청된 소유 구조 등급이 제공되지 않은 이유로, `ownership.unavailable_reason`과 동일한 코드입니다. `no_owners_on_record`(등기소가 응답했으나 소유자를 명시하지 않음)와 `ownership_section_unavailable`(등기소에서 소유 구조 섹션을 반환하지 않음)은 서로 다른 결과입니다."
          },
          "section_errors": {
            "type": "object",
            "description": "등기부에서 반환하지 않은 섹션으로, 섹션별(`officers`, `shareholders`, `group_structure`)로 키가 지정됩니다. 여기에 나열된 섹션은 전혀 전달되지 않았습니다. 그 옆에 빈 목록이 있더라도 해당 기업에 대해 아무것도 나타내지 않습니다.",
            "additionalProperties": {
              "$ref": "#/components/schemas/KYBRegistrySectionError"
            }
          },
          "ubo_resolution": {
            "$ref": "#/components/schemas/KYBRegistryUboResolution"
          },
          "lite_enrichment": {
            "$ref": "#/components/schemas/KYBRegistryLiteEnrichment"
          },
          "registry_metadata": {
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                }
              ]
            },
            "description": "등기소 명칭을 키로 하고 일반 값으로 표현된 해당 기업에 대한 등기소 자체 필드(레거시 레코드)입니다. 등기소 사실로 검토된 필드만 포함됩니다."
          },
          "registry_sources": {
            "type": "array",
            "description": "기록을 읽어온 공식 등기부 목록입니다(레거시 기록). 다른 출처의 이름은 명시되지 않습니다.",
            "items": {
              "$ref": "#/components/schemas/KYBRegistrySource"
            }
          },
          "previous_names": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "해당 기업이 이전에 등록되었던 이름입니다(기존 기록)."
          },
          "parent_companies": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "등기부에 기재된 모회사 목록입니다(레거시 기록)."
          },
          "documents_available": {
            "type": "integer",
            "description": "등기부에서 해당 기업에 대해 제공하는 제출 서류 수(레거시 기록)입니다."
          }
        }
      },
      "KYBRegistryGroupCompany": {
        "type": "object",
        "description": "법인 등기부상 신원에 따른 기업 그룹의 계열사입니다.",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true,
            "description": "기업명입니다."
          },
          "country_code": {
            "type": "string",
            "nullable": true,
            "description": "등록 국가."
          },
          "registration_number": {
            "type": "string",
            "nullable": true,
            "description": "등록번호입니다."
          }
        },
        "required": [
          "name",
          "country_code",
          "registration_number"
        ]
      },
      "KYBRegistryUboResolution": {
        "type": "object",
        "description": "UBO 등급이 기업의 상위 소유 구조 체인을 탐색한 방식입니다.",
        "properties": {
          "parent_chain": {
            "type": "array",
            "description": "최상위 모회사부터 해당 기업까지의 기업 모회사 목록입니다.",
            "items": {
              "$ref": "#/components/schemas/KYBRegistryGroupCompany"
            }
          },
          "subsidiaries": {
            "type": "array",
            "description": "기업 집단 내에서 해당 기업 바로 아래에 위치한 기업 목록입니다.",
            "items": {
              "$ref": "#/components/schemas/KYBRegistryGroupCompany"
            }
          },
          "unresolved": {
            "type": "array",
            "description": "법인 등기부에서 확인할 수 없는 소유 구조 체인의 일부입니다(`ownership.unresolved`와 동일한 항목).",
            "items": {
              "type": "object",
              "properties": {
                "reason": {
                  "type": "string",
                  "description": "이유(예: `no_group_structure_on_record`, `selected_company_not_in_group_structure` 또는 `section_error`)입니다."
                },
                "section": {
                  "type": "string",
                  "nullable": true,
                  "description": "해당 섹션입니다(예: `group_structure`)."
                }
              },
              "required": [
                "reason",
                "section"
              ]
            }
          }
        },
        "required": [
          "parent_chain",
          "subsidiaries",
          "unresolved"
        ]
      },
      "KYBRegistrySectionError": {
        "type": "object",
        "description": "법인 등기부에서 반환하지 않은 섹션입니다.",
        "properties": {
          "status_code": {
            "type": "integer",
            "nullable": true,
            "description": "해당 섹션에 대해 등기소에서 응답한 상태입니다."
          }
        },
        "required": [
          "status_code"
        ]
      },
      "KYBRegistryLiteEnrichment": {
        "type": "object",
        "description": "해당 국가의 다른 등기부 출처가 채운 Lite 프로필의 빈 필드입니다. 출처는 명시되지 않습니다.",
        "properties": {
          "fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "입력된 기업 필드입니다."
          },
          "people_added": {
            "type": "integer",
            "description": "추가된 임원 또는 소유자 수입니다."
          }
        },
        "required": [
          "fields",
          "people_added"
        ]
      },
      "KYBRegistrySource": {
        "type": "object",
        "description": "기록을 읽어온 공식 등기소입니다. 공식 정부 등기소, 규제 기관 및 공식 식별자 시스템만 명시되며, 기타 소스는 제외됩니다.",
        "properties": {
          "name": {
            "type": "string",
            "description": "등록부 명칭(예: `UK Companies House`)."
          },
          "source_type": {
            "type": "string",
            "enum": [
              "official"
            ],
            "description": "항상 `official`입니다."
          }
        },
        "required": [
          "name",
          "source_type"
        ]
      },
      "KYBOwnershipStructure": {
        "type": "object",
        "nullable": true,
        "description": "소유 구조 등급이 전송된 시점에 법인 등기부에서 증명한 자본 구조표(cap table)입니다: 직접 `shareholders` 및 `beneficial_owners`. 법인 등기부에서 소유 구조를 증명하지 못한 경우 null입니다. 등기부 소스 자체의 행은 절대 포함되지 않습니다. 현재 레코드는 `company.beneficial_owners` 및 `company.ownership`을 확인하십시오.",
        "properties": {
          "shareholders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/KYBOwnershipStructureOwner"
            }
          },
          "beneficial_owners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/KYBOwnershipStructureOwner"
            }
          }
        },
        "required": [
          "shareholders",
          "beneficial_owners"
        ]
      },
      "KYBOwnershipStructureOwner": {
        "type": "object",
        "description": "소유 구조 스냅샷의 소유자 1명: `company.beneficial_owners[]`와 동일한 법인 등기부상의 신원 및 지분, 그리고 표준 `shareholding`입니다.",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true,
            "description": "등기부에 기재된 소유자 이름입니다."
          },
          "first_name": {
            "type": "string",
            "nullable": true,
            "description": "등기소에 명시된 경우 자연인의 이름입니다."
          },
          "last_name": {
            "type": "string",
            "nullable": true,
            "description": "자연인의 경우, 등기부에 기재된 성입니다."
          },
          "date_of_birth": {
            "type": "string",
            "nullable": true,
            "description": "등기소에서 공개한 경우 생년월일(ISO 8601)입니다."
          },
          "country_of_birth": {
            "type": "string",
            "nullable": true,
            "description": "등기소에서 공개한 경우의 출생 국가입니다."
          },
          "company_name": {
            "type": "string",
            "nullable": true,
            "description": "법인 소유자의 기업명입니다."
          },
          "registration_number": {
            "type": "string",
            "nullable": true,
            "description": "법인 소유자의 등록번호입니다."
          },
          "entity_type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "person",
              "company",
              null
            ],
            "description": "소유자가 자연인인지 기업인지 여부입니다."
          },
          "nationality": {
            "type": "string",
            "nullable": true,
            "description": "등기부에 기재된 경우의 국적입니다."
          },
          "designation": {
            "type": "string",
            "nullable": true,
            "description": "등기부에 기재된 소유자의 직함 또는 역할입니다."
          },
          "roles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "직접 보유자의 경우 `shareholder`, 실소유자의 경우 `ubo`입니다."
          },
          "ownership_min_shares": {
            "type": "string",
            "nullable": true,
            "description": "지분의 하한값(백분율, 정확한 지분의 경우 상한값과 동일함)."
          },
          "ownership_max_shares": {
            "type": "string",
            "nullable": true,
            "description": "지분율 상한(백분율)입니다."
          },
          "voting_min_shares": {
            "type": "string",
            "nullable": true,
            "description": "의결권의 하한값(백분율)."
          },
          "voting_max_shares": {
            "type": "string",
            "nullable": true,
            "description": "의결권 상한(백분율)입니다."
          },
          "appointment_date": {
            "type": "string",
            "nullable": true,
            "description": "보유 또는 선임이 시작된 날짜(ISO 8601)입니다."
          },
          "is_active": {
            "type": "boolean",
            "nullable": true,
            "description": "이전 소유자의 경우 False입니다."
          },
          "shareholding": {
            "$ref": "#/components/schemas/KYBRegistryShareholding"
          }
        },
        "required": [
          "name",
          "first_name",
          "last_name",
          "date_of_birth",
          "country_of_birth",
          "company_name",
          "registration_number",
          "entity_type",
          "nationality",
          "designation",
          "roles",
          "ownership_min_shares",
          "ownership_max_shares",
          "voting_min_shares",
          "voting_max_shares",
          "appointment_date",
          "is_active",
          "shareholding"
        ]
      },
      "DigitalIdWalletApiWalletVerificationError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "기계 판독 가능한 고정 코드입니다(예: wallet_unavailable)."
          },
          "detail": {
            "type": "string"
          }
        },
        "required": [
          "detail",
          "error"
        ]
      },
      "DigitalIdWalletApiWalletVerificationStartForbidden": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/DigitalIdWalletApiClientCredentialsForbiddenErrorMessage"
          },
          {
            "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
          }
        ]
      },
      "DigitalIdWalletApiClientCredentialsForbiddenErrorMessage": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string",
            "default": "Forbidden - User doesn't have permission"
          }
        }
      },
      "DigitalIdWalletApiWalletVerificationStartBadRequest": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
          },
          {
            "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationFieldErrors"
          }
        ]
      },
      "DigitalIdWalletApiWalletVerificationFieldErrors": {
        "type": "object",
        "description": "요청 유효성 검사 오류: 거부된 각 필드 및 해당 메시지입니다.",
        "additionalProperties": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "DigitalIdWalletApiWalletVerificationResponse": {
        "type": "object",
        "description": "모든 지갑 endpoint가 응답하는 단일 독립형 지갑 검증입니다.",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "wallet_verification": {
            "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResult"
          },
          "vendor_data": {
            "type": "string",
            "nullable": true
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "시작 시 전송된 메타데이터 객체 또는 null입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "created_at",
          "metadata",
          "request_id",
          "vendor_data",
          "wallet_verification"
        ]
      },
      "DigitalIdWalletApiWalletVerificationResult": {
        "type": "object",
        "properties": {
          "wallet": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiWallet"
              }
            ],
            "readOnly": true
          },
          "country": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "보류 중인 동안에는 완료되지 않음, 이후 승인됨(인증됨) 또는 거부됨."
          },
          "outcome": {
            "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResultOutcomeEnum"
          },
          "error": {
            "type": "string",
            "nullable": true,
            "readOnly": true
          },
          "interaction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiInteractionEnum"
              }
            ],
            "readOnly": true
          },
          "simulated": {
            "type": "boolean",
            "readOnly": true
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "next_action": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletNextAction"
              }
            ],
            "nullable": true,
            "readOnly": true
          },
          "identity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletIdentity"
              }
            ],
            "nullable": true,
            "readOnly": true
          },
          "attributes": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "readOnly": true
          },
          "level_of_assurance": {
            "type": "string",
            "nullable": true
          },
          "verified_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "signature_valid": {
            "type": "boolean",
            "nullable": true,
            "description": "자격 증명의 서명이 검증되면 true이고, 시뮬레이션된 자격 증명의 경우 null입니다."
          },
          "credential_type": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "attributes",
          "country",
          "credential_type",
          "error",
          "expires_at",
          "identity",
          "interaction",
          "level_of_assurance",
          "next_action",
          "outcome",
          "signature_valid",
          "simulated",
          "status",
          "verified_at",
          "wallet"
        ]
      },
      "DigitalIdWalletApiWalletIdentity": {
        "type": "object",
        "properties": {
          "full_name": {
            "type": "string",
            "nullable": true
          },
          "first_name": {
            "type": "string",
            "nullable": true
          },
          "last_name": {
            "type": "string",
            "nullable": true
          },
          "date_of_birth": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "nationality": {
            "type": "string",
            "nullable": true,
            "description": "지갑이 국적을 명시한 경우에만 제공되는 ISO3 국적입니다(절대 유추되지 않음)."
          },
          "issuing_state": {
            "type": "string",
            "description": "신원을 발급한 체계의 ISO3 국가입니다."
          }
        },
        "required": [
          "date_of_birth",
          "first_name",
          "full_name",
          "issuing_state",
          "last_name",
          "nationality"
        ]
      },
      "DigitalIdWalletApiWalletNextAction": {
        "type": "object",
        "properties": {
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletNextActionTypeEnum"
              }
            ],
            "description": "redirect: 사용자의 브라우저를 url로 이동시킵니다. confirm_in_app: 사용자에게 verification_code를 표시하고 사용자가 지갑 앱의 코드와 일치하는지 확인한 후 승인하면 폴링합니다. request_digital_credential: 시작했던 origin에서 사용자 제스처를 통해 digital_credentials.request로 지갑에 요청한 후 반환된 값을 POST .../verifications/{request_id}/response/로 전송합니다.\n\n* `redirect` - redirect\n* `confirm_in_app` - confirm_in_app\n* `request_digital_credential` - request_digital_credential"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "redirect 전용: 사용자가 지갑으로 로그인하는 위치입니다."
          },
          "digital_credentials": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletDigitalCredentialsRequest"
              }
            ],
            "description": "request_digital_credential 전용: 지갑에 전달할 요청입니다."
          },
          "verification_code": {
            "type": "string",
            "description": "confirm_in_app 전용: 지갑 앱에도 표시되는 4자리 비교 코드입니다."
          },
          "poll_interval_seconds": {
            "type": "integer",
            "description": "confirm_in_app 전용: 즉각적인 피드백을 위해 POST .../verifications/{request_id}/poll/을 호출하는 주기입니다. Didit은 백그라운드에서도 대기 중인 로그인을 폴링하므로 사용자가 폴링하지 않더라도 webhook이 결과를 보고합니다."
          }
        },
        "required": [
          "type"
        ]
      },
      "DigitalIdWalletApiWalletNextActionTypeEnum": {
        "enum": [
          "redirect",
          "confirm_in_app",
          "request_digital_credential"
        ],
        "type": "string",
        "description": "* `redirect` - redirect\n* `confirm_in_app` - confirm_in_app\n* `request_digital_credential` - request_digital_credential"
      },
      "DigitalIdWalletApiInteractionEnum": {
        "enum": [
          "redirect",
          "in_app",
          "digital_credentials"
        ],
        "type": "string",
        "description": "* `redirect` - redirect\n* `in_app` - in_app\n* `digital_credentials` - digital_credentials"
      },
      "DigitalIdWalletApiWalletVerificationResultOutcomeEnum": {
        "enum": [
          "pending",
          "verified",
          "cancelled",
          "timeout",
          "failed"
        ],
        "type": "string",
        "description": "* `pending` - 대기 중\n* `verified` - 확인됨\n* `cancelled` - 사용자에 의해 취소됨\n* `timeout` - 시간 초과\n* `failed` - 실패함"
      },
      "DigitalIdWalletApiWallet": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "지갑의 카탈로그 id(예: bankid_se)."
          },
          "name": {
            "type": "string"
          },
          "issuing_authority": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "issuing_authority",
          "name"
        ]
      },
      "DigitalIdWalletApiEudiWalletVerificationStartRequest": {
        "type": "object",
        "description": "EUDI Wallet 인증(AUT, BEL, BGR, HRV, CYP, CZE, DNK, EST, FIN, FRA, DEU, GRC, HUN, IRL, ITA, LVA, LTU, LUX, MLT, NLD, POL, PRT, ROU, SVK, SVN, ESP, SWE, ISL, LIE, NOR)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiEudiWalletVerificationStartCountryEnum"
              }
            ],
            "description": "EUDI Wallet 신원의 ISO 3166-1 alpha-3 국가입니다.\n\n* `AUT` - AUT\n* `BEL` - BEL\n* `BGR` - BGR\n* `HRV` - HRV\n* `CYP` - CYP\n* `CZE` - CZE\n* `DNK` - DNK\n* `EST` - EST\n* `FIN` - FIN\n* `FRA` - FRA\n* `DEU` - DEU\n* `GRC` - GRC\n* `HUN` - HUN\n* `IRL` - IRL\n* `ITA` - ITA\n* `LVA` - LVA\n* `LTU` - LTU\n* `LUX` - LUX\n* `MLT` - MLT\n* `NLD` - NLD\n* `POL` - POL\n* `PRT` - PRT\n* `ROU` - ROU\n* `SVK` - SVK\n* `SVN` - SVN\n* `ESP` - ESP\n* `SWE` - SWE\n* `ISL` - ISL\n* `LIE` - LIE\n* `NOR` - NOR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "country",
          "return_url"
        ]
      },
      "DigitalIdWalletApiDeviceEnum": {
        "enum": [
          "same_device",
          "cross_device"
        ],
        "type": "string",
        "description": "* `same_device` - same_device\n* `cross_device` - cross_device"
      },
      "DigitalIdWalletApiEudiWalletVerificationStartCountryEnum": {
        "enum": [
          "AUT",
          "BEL",
          "BGR",
          "HRV",
          "CYP",
          "CZE",
          "DNK",
          "EST",
          "FIN",
          "FRA",
          "DEU",
          "GRC",
          "HUN",
          "IRL",
          "ITA",
          "LVA",
          "LTU",
          "LUX",
          "MLT",
          "NLD",
          "POL",
          "PRT",
          "ROU",
          "SVK",
          "SVN",
          "ESP",
          "SWE",
          "ISL",
          "LIE",
          "NOR"
        ],
        "type": "string",
        "description": "* `AUT` - AUT\n* `BEL` - BEL\n* `BGR` - BGR\n* `HRV` - HRV\n* `CYP` - CYP\n* `CZE` - CZE\n* `DNK` - DNK\n* `EST` - EST\n* `FIN` - FIN\n* `FRA` - FRA\n* `DEU` - DEU\n* `GRC` - GRC\n* `HUN` - HUN\n* `IRL` - IRL\n* `ITA` - ITA\n* `LVA` - LVA\n* `LTU` - LTU\n* `LUX` - LUX\n* `MLT` - MLT\n* `NLD` - NLD\n* `POL` - POL\n* `PRT` - PRT\n* `ROU` - ROU\n* `SVK` - SVK\n* `SVN` - SVN\n* `ESP` - ESP\n* `SWE` - SWE\n* `ISL` - ISL\n* `LIE` - LIE\n* `NOR` - NOR"
      },
      "DigitalIdWalletApiConnectidWalletVerificationStartRequest": {
        "type": "object",
        "description": "ConnectID 인증(AUS)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiConnectidWalletVerificationStartCountryEnum"
              }
            ],
            "default": "AUS",
            "description": "ConnectID 신원의 ISO 3166-1 alpha-3 국가입니다. 서비스 대상 국가인 AUS가 기본값입니다.\n\n* `AUS` - AUS"
          },
          "authorisation_server_id": {
            "type": "string",
            "minLength": 1,
            "description": "ConnectID의 은행 선택기에서 선택된 인증 서버 ID입니다. 샌드박스의 기본값은 Mock Bank A입니다.",
            "maxLength": 36
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiConnectidWalletVerificationStartCountryEnum": {
        "enum": [
          "AUS"
        ],
        "type": "string",
        "description": "* `AUS` - AUS"
      },
      "DigitalIdWalletApiAudkenniWalletVerificationStartRequest": {
        "type": "object",
        "description": "Auðkenni 인증(ISL)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiAudkenniWalletVerificationStartCountryEnum"
              }
            ],
            "default": "ISL",
            "description": "Auðkenni 신원의 ISO 3166-1 alpha-3 국가입니다. 서비스 대상 국가인 ISL이 기본값입니다.\n\n* `ISL` - ISL"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiAudkenniWalletVerificationStartCountryEnum": {
        "enum": [
          "ISL"
        ],
        "type": "string",
        "description": "* `ISL` - ISL"
      },
      "DigitalIdWalletApiFranceconnectWalletVerificationStartRequest": {
        "type": "object",
        "description": "FranceConnect 인증(FRA)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum"
              }
            ],
            "default": "FRA",
            "description": "FranceConnect 신원의 ISO 3166-1 alpha-3 국가입니다. 서비스 대상 국가인 FRA가 기본값입니다.\n\n* `FRA` - FRA"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum": {
        "enum": [
          "FRA"
        ],
        "type": "string",
        "description": "* `FRA` - FRA"
      },
      "DigitalIdWalletApiDiiaWalletVerificationStartRequest": {
        "type": "object",
        "description": "Diia 인증(UKR)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDiiaWalletVerificationStartCountryEnum"
              }
            ],
            "default": "UKR",
            "description": "Diia 신원의 ISO 3166-1 alpha-3 국가입니다. 서비스 대상 국가인 UKR이 기본값입니다.\n\n* `UKR` - UKR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiDiiaWalletVerificationStartCountryEnum": {
        "enum": [
          "UKR"
        ],
        "type": "string",
        "description": "* `UKR` - UKR"
      },
      "DigitalIdWalletApiMojeidWalletVerificationStartRequest": {
        "type": "object",
        "description": "MojeID 인증(CZE)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryE2dEnum"
              }
            ],
            "default": "CZE",
            "description": "MojeID 신원의 ISO 3166-1 alpha-3 국가입니다. 기본값은 지원하는 유일한 국가인 CZE입니다.\n\n* `CZE` - CZE"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiCountryE2dEnum": {
        "enum": [
          "CZE"
        ],
        "type": "string",
        "description": "* `CZE` - CZE"
      },
      "DigitalIdWalletApiBankidCzWalletVerificationStartRequest": {
        "type": "object",
        "description": "Bank iD 인증(CZE)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryE2dEnum"
              }
            ],
            "default": "CZE",
            "description": "Bank iD 신원의 ISO 3166-1 alpha-3 국가입니다. 서비스 대상 국가인 CZE가 기본값입니다.\n\n* `CZE` - CZE"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest": {
        "type": "object",
        "description": "eParaksts mobile 인증(LVA)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiEparakstsMobileWalletVerificationStartCountryEnum"
              }
            ],
            "default": "LVA",
            "description": "eParaksts mobile 신원의 ISO 3166-1 alpha-3 국가입니다. 기본값은 지원하는 유일한 국가인 LVA입니다.\n\n* `LVA` - LVA"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiEparakstsMobileWalletVerificationStartCountryEnum": {
        "enum": [
          "LVA"
        ],
        "type": "string",
        "description": "* `LVA` - LVA"
      },
      "DigitalIdWalletApiIdcardEeWalletVerificationStartRequest": {
        "type": "object",
        "description": "에스토니아 ID 카드 인증(EST)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum"
              }
            ],
            "default": "EST",
            "description": "Estonian ID-card 신원의 ISO 3166-1 alpha-3 국가입니다. 서비스 대상 국가인 EST가 기본값입니다.\n\n* `EST` - EST"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum": {
        "enum": [
          "EST"
        ],
        "type": "string",
        "description": "* `EST` - EST"
      },
      "DigitalIdWalletApiMobileIdWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mobile-ID 인증(EST, LTU)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiMobileIdWalletVerificationStartCountryEnum"
              }
            ],
            "description": "Mobile-ID 신원의 ISO 3166-1 alpha-3 국가입니다.\n\n* `EST` - EST\n* `LTU` - LTU"
          },
          "personal_code": {
            "type": "string",
            "minLength": 1,
            "description": "사용자의 국가 개인 식별 코드입니다. 사용자의 Mobile-ID 앱으로 전송되며, 사용자는 앱에서 비교 코드를 확인하고 PIN을 입력합니다. PIN을 수집하지 마세요.",
            "pattern": "^[0-9-]{6,20}$"
          },
          "phone_number": {
            "type": "string",
            "minLength": 1,
            "description": "E.164 형식(+372... 또는 +370...)의 Mobile-ID 전화번호입니다.",
            "maxLength": 16
          }
        },
        "required": [
          "country",
          "personal_code",
          "phone_number"
        ]
      },
      "DigitalIdWalletApiMobileIdWalletVerificationStartCountryEnum": {
        "enum": [
          "EST",
          "LTU"
        ],
        "type": "string",
        "description": "* `EST` - EST\n* `LTU` - LTU"
      },
      "DigitalIdWalletApiSmartIdWalletVerificationStartRequest": {
        "type": "object",
        "description": "Smart-ID 인증(EST, LVA, LTU, BEL)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiSmartIdWalletVerificationStartCountryEnum"
              }
            ],
            "description": "Smart-ID 신원의 ISO 3166-1 alpha-3 국가입니다.\n\n* `EST` - EST\n* `LVA` - LVA\n* `LTU` - LTU\n* `BEL` - BEL"
          },
          "personal_code": {
            "type": "string",
            "minLength": 1,
            "description": "사용자의 국가 개인 식별 코드입니다. 사용자의 Smart-ID 앱으로 전송되며, 사용자는 앱에서 비교 코드를 확인하고 PIN을 입력합니다. PIN을 수집하지 마세요.",
            "pattern": "^[0-9-]{6,20}$"
          }
        },
        "required": [
          "country",
          "personal_code"
        ]
      },
      "DigitalIdWalletApiSmartIdWalletVerificationStartCountryEnum": {
        "enum": [
          "EST",
          "LVA",
          "LTU",
          "BEL"
        ],
        "type": "string",
        "description": "* `EST` - EST\n* `LVA` - LVA\n* `LTU` - LTU\n* `BEL` - BEL"
      },
      "DigitalIdWalletApiGovukWalletWalletVerificationStartRequest": {
        "type": "object",
        "description": "GOV.UK Wallet 인증(GBR)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountry520Enum"
              }
            ],
            "default": "GBR",
            "description": "GOV.UK Wallet 신원의 ISO 3166-1 alpha-3 국가입니다. 기본값은 지원하는 유일한 국가인 GBR입니다.\n\n* `GBR` - GBR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiCountry520Enum": {
        "enum": [
          "GBR"
        ],
        "type": "string",
        "description": "* `GBR` - GBR"
      },
      "DigitalIdWalletApiOneidWalletVerificationStartRequest": {
        "type": "object",
        "description": "OneID 인증(GBR)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountry520Enum"
              }
            ],
            "default": "GBR",
            "description": "OneID 신원의 ISO 3166-1 alpha-3 국가입니다. 기본값은 지원하는 유일한 국가인 GBR입니다.\n\n* `GBR` - GBR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiGovbrWalletVerificationStartRequest": {
        "type": "object",
        "description": "gov.br 인증(BRA)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum"
              }
            ],
            "default": "BRA",
            "description": "gov.br 신원의 ISO 3166-1 alpha-3 국가입니다. 기본값은 지원하는 유일한 국가인 BRA입니다.\n\n* `BRA` - BRA"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum": {
        "enum": [
          "BRA"
        ],
        "type": "string",
        "description": "* `BRA` - BRA"
      },
      "DigitalIdWalletApiUaePassWalletVerificationStartRequest": {
        "type": "object",
        "description": "UAE PASS 인증(ARE)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiUaePassWalletVerificationStartCountryEnum"
              }
            ],
            "default": "ARE",
            "description": "UAE PASS 신원의 ISO 3166-1 alpha-3 국가입니다. 기본값은 지원하는 유일한 국가인 ARE입니다.\n\n* `ARE` - ARE"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiUaePassWalletVerificationStartCountryEnum": {
        "enum": [
          "ARE"
        ],
        "type": "string",
        "description": "* `ARE` - ARE"
      },
      "DigitalIdWalletApiFrejaidWalletVerificationStartRequest": {
        "type": "object",
        "description": "Freja eID 인증(SWE)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryEe9Enum"
              }
            ],
            "default": "SWE",
            "description": "Freja eID 신원의 ISO 3166-1 alpha-3 국가입니다. 기본값은 지원하는 유일한 국가인 SWE입니다.\n\n* `SWE` - SWE"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiCountryEe9Enum": {
        "enum": [
          "SWE"
        ],
        "type": "string",
        "description": "* `SWE` - SWE"
      },
      "DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest": {
        "type": "object",
        "description": "Personalausweis 인증(DEU)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiPersonalausweisWalletVerificationStartCountryEnum"
              }
            ],
            "default": "DEU",
            "description": "Personalausweis 신원의 ISO 3166-1 alpha-3 국가입니다. 기본값은 지원하는 유일한 국가인 DEU입니다.\n\n* `DEU` - DEU"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiPersonalausweisWalletVerificationStartCountryEnum": {
        "enum": [
          "DEU"
        ],
        "type": "string",
        "description": "* `DEU` - DEU"
      },
      "DigitalIdWalletApiFtnWalletVerificationStartRequest": {
        "type": "object",
        "description": "Finnish Trust Network 인증(FIN)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiFtnWalletVerificationStartCountryEnum"
              }
            ],
            "default": "FIN",
            "description": "Finnish Trust Network 신원의 ISO 3166-1 alpha-3 국가입니다. 서비스 대상 국가인 FIN이 기본값입니다.\n\n* `FIN` - FIN"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiFtnWalletVerificationStartCountryEnum": {
        "enum": [
          "FIN"
        ],
        "type": "string",
        "description": "* `FIN` - FIN"
      },
      "DigitalIdWalletApiIdinWalletVerificationStartRequest": {
        "type": "object",
        "description": "iDIN 인증(NLD)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdinWalletVerificationStartCountryEnum"
              }
            ],
            "default": "NLD",
            "description": "iDIN 신원의 ISO 3166-1 alpha-3 국가입니다. 기본값은 지원하는 유일한 국가인 NLD입니다.\n\n* `NLD` - NLD"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiIdinWalletVerificationStartCountryEnum": {
        "enum": [
          "NLD"
        ],
        "type": "string",
        "description": "* `NLD` - NLD"
      },
      "DigitalIdWalletApiItsmeWalletVerificationStartRequest": {
        "type": "object",
        "description": "itsme 인증(BEL, LUX, NLD)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiItsmeWalletVerificationStartCountryEnum"
              }
            ],
            "description": "itsme 신원의 ISO 3166-1 alpha-3 국가입니다.\n\n* `BEL` - BEL\n* `LUX` - LUX\n* `NLD` - NLD"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "country",
          "return_url"
        ]
      },
      "DigitalIdWalletApiItsmeWalletVerificationStartCountryEnum": {
        "enum": [
          "BEL",
          "LUX",
          "NLD"
        ],
        "type": "string",
        "description": "* `BEL` - BEL\n* `LUX` - LUX\n* `NLD` - NLD"
      },
      "DigitalIdWalletApiBuypassWalletVerificationStartRequest": {
        "type": "object",
        "description": "Buypass ID 인증(NOR)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryAfcEnum"
              }
            ],
            "default": "NOR",
            "description": "Buypass ID 신원의 ISO 3166-1 alpha-3 국가입니다. 서비스 대상 국가인 NOR가 기본값입니다.\n\n* `NOR` - NOR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiCountryAfcEnum": {
        "enum": [
          "NOR"
        ],
        "type": "string",
        "description": "* `NOR` - NOR"
      },
      "DigitalIdWalletApiVippsWalletVerificationStartRequest": {
        "type": "object",
        "description": "Vipps 인증(NOR)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryAfcEnum"
              }
            ],
            "default": "NOR",
            "description": "Vipps 신원의 ISO 3166-1 alpha-3 국가입니다. 기본값은 지원하는 유일한 국가인 NOR입니다.\n\n* `NOR` - NOR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiBankidNoWalletVerificationStartRequest": {
        "type": "object",
        "description": "BankID 인증(NOR)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryAfcEnum"
              }
            ],
            "default": "NOR",
            "description": "BankID 신원의 ISO 3166-1 alpha-3 국가입니다. 서비스 대상 국가인 NOR가 기본값입니다.\n\n* `NOR` - NOR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiBankidSeWalletVerificationStartRequest": {
        "type": "object",
        "description": "BankID 인증(SWE)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryEe9Enum"
              }
            ],
            "default": "SWE",
            "description": "BankID 신원의 ISO 3166-1 alpha-3 국가입니다. 서비스 대상 국가인 SWE가 기본값입니다.\n\n* `SWE` - SWE"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiMitidWalletVerificationStartRequest": {
        "type": "object",
        "description": "MitID 인증(DNK)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiMitidWalletVerificationStartCountryEnum"
              }
            ],
            "default": "DNK",
            "description": "MitID 신원의 ISO 3166-1 alpha-3 국가입니다. 기본값은 지원하는 유일한 국가인 DNK입니다.\n\n* `DNK` - DNK"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "지갑 완료 후 사용자의 브라우저가 돌아갈 https URL이며, request_id 및 result가 추가됩니다. 호스트는 애플리케이션의 allowed_return_hosts에 등록되어 있어야 합니다(또는 해당 화이트 라벨 도메인이어야 함). result 값만 단독으로 신뢰하지 마세요. GET .../verifications/{request_id}/ 또는 webhook을 통해 최종 결과를 확인하세요.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "페이지가 표시된 동일한 기기에서 로그인하는 경우 same_device, 다른 기기를 사용하는 경우 cross_device(예: BankID의 QR 코드)입니다.\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiMitidWalletVerificationStartCountryEnum": {
        "enum": [
          "DNK"
        ],
        "type": "string",
        "description": "* `DNK` - DNK"
      },
      "DigitalIdWalletApiWalletCatalogResponse": {
        "type": "object",
        "properties": {
          "wallets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DigitalIdWalletApiWalletCatalogEntry"
            }
          }
        },
        "required": [
          "wallets"
        ]
      },
      "DigitalIdWalletApiWalletCatalogEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "path": {
            "type": "string",
            "description": "지갑 자체의 시작 endpoint입니다."
          },
          "countries": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "issuing_authority": {
            "type": "string"
          },
          "level_of_assurance": {
            "type": "string",
            "nullable": true
          },
          "interaction": {
            "$ref": "#/components/schemas/DigitalIdWalletApiInteractionEnum"
          },
          "required_fields": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "available": {
            "type": "boolean",
            "description": "이 애플리케이션이 현재 이 환경에서 이를 시작할 수 있는지 여부입니다. 목록에 표시되어 있다고 해서 프로덕션 상태인 것은 아닙니다."
          }
        },
        "required": [
          "available",
          "countries",
          "id",
          "interaction",
          "issuing_authority",
          "level_of_assurance",
          "name",
          "path",
          "required_fields"
        ]
      },
      "CaseDuplicateCaseDuplicate": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "case_number": {
            "type": "string",
            "nullable": true,
            "maxLength": 32
          },
          "title": {
            "type": "string",
            "maxLength": 255
          },
          "status": {
            "$ref": "#/components/schemas/CaseDuplicateStatusEnum"
          },
          "priority": {
            "$ref": "#/components/schemas/CaseDuplicatePriorityEnum"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "created_at",
          "title",
          "uuid"
        ]
      },
      "CaseDuplicateCaseDuplicatePage": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "next_offset": {
            "type": "integer",
            "nullable": true
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseDuplicateCaseDuplicate"
            }
          }
        },
        "required": [
          "count",
          "next_offset",
          "results"
        ]
      },
      "RoutingPublicationPolicyDraftResponse": {
        "type": "object",
        "properties": {
          "draft": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraft"
              }
            ],
            "nullable": true
          }
        },
        "required": [
          "draft"
        ]
      },
      "RoutingPublicationPolicyDraftWriteRequest": {
        "type": "object",
        "properties": {
          "expected_version": {
            "type": "integer",
            "minimum": 0
          },
          "expected_revision": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "changes": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": [
          "changes",
          "expected_revision",
          "expected_version"
        ]
      },
      "CasePublicationPolicyDraft": {
        "type": "object",
        "properties": {
          "revision": {
            "type": "string",
            "format": "uuid"
          },
          "base_version": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "changes": {},
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "maxLength": 254
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "base_version",
          "updated_at"
        ]
      },
      "CasePublicationPolicyDraftPreconditionRequest": {
        "type": "object",
        "properties": {
          "expected_version": {
            "type": "integer",
            "minimum": 0
          },
          "expected_revision": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          }
        },
        "required": [
          "expected_revision",
          "expected_version"
        ]
      },
      "CaseCollaborationCaseNote": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "comment": {
            "type": "string"
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "maxLength": 255
          },
          "actor_name": {
            "type": "string",
            "nullable": true,
            "maxLength": 255
          },
          "mentioned_emails": {},
          "is_internal": {
            "type": "boolean"
          },
          "attachments": {},
          "tags": {},
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "reply_to": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CaseCollaborationCaseNoteReply"
              }
            ],
            "nullable": true,
            "readOnly": true
          },
          "is_pinned": {
            "type": "boolean"
          },
          "client_reference": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          }
        },
        "required": [
          "comment",
          "created_at",
          "reply_to",
          "uuid"
        ]
      },
      "CustomerMessagingPaginatedCaseRequestList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=400&limit=100"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=200&limit=100"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomerMessagingCaseRequest"
            }
          }
        }
      },
      "FraudCheckResponse": {
        "type": "object",
        "properties": {
          "check_id": {
            "type": "string",
            "format": "uuid"
          },
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 검사를 위해 생성된 네이티브 인증 세션입니다."
          },
          "client_reference": {
            "type": "string",
            "nullable": true
          },
          "processing_status": {
            "$ref": "#/components/schemas/FraudProcessingStatusEnum"
          },
          "profile_id": {
            "type": "string"
          },
          "profile_version": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "inputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudCheckInput"
            }
          },
          "modules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudCheckModuleReport"
            }
          },
          "attribute_evidence": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "compound_evidence": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "risk": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudCheckRisk"
            }
          },
          "network": {
            "type": "object",
            "additionalProperties": {}
          },
          "enrichment": {
            "type": "object",
            "additionalProperties": {}
          },
          "identity_relationship": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FraudCheckIdentityRelationship"
              }
            ],
            "nullable": true
          },
          "recommendation": {
            "$ref": "#/components/schemas/FraudRecommendationEnum"
          },
          "next_action": {
            "$ref": "#/components/schemas/FraudNextActionEnum"
          },
          "decision_reasons": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "coverage": {
            "type": "object",
            "additionalProperties": {}
          },
          "usage": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "vendor_data": {
            "type": "string",
            "nullable": true
          },
          "metadata": {
            "nullable": true
          }
        },
        "required": [
          "attribute_evidence",
          "check_id",
          "client_reference",
          "completed_at",
          "compound_evidence",
          "coverage",
          "created_at",
          "decision_reasons",
          "inputs",
          "modules",
          "network",
          "next_action",
          "processing_status",
          "profile_id",
          "profile_version",
          "recommendation",
          "risk",
          "usage"
        ]
      },
      "CaseReviewTeam": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "members": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseReviewTeamMember"
            },
            "maxItems": 250
          },
          "is_active": {
            "type": "boolean"
          },
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        }
      },
      "CaseActionCaseEntityActionRequest": {
        "type": "object",
        "properties": {
          "client_reference": {
            "type": "string",
            "format": "uuid"
          },
          "retry": {
            "type": "boolean",
            "default": false
          },
          "action": {
            "$ref": "#/components/schemas/CaseActionActionEnum"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            }
          },
          "note": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "action"
        ]
      },
      "RoutingPublicationPaginatedPolicyRevisionList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=400&limit=100"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=200&limit=100"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoutingPublicationPolicyRevision"
            }
          }
        }
      },
      "FraudRecommendationEnum": {
        "enum": [
          "approve",
          "review",
          "reject"
        ],
        "type": "string",
        "description": "* `approve` - 승인\n* `review` - 검토\n* `reject` - 거부"
      },
      "CustomerMessagingCaseRequestPreviewResponse": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "recipient": {
            "type": "string",
            "format": "email"
          },
          "sender": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "html": {
            "type": "string"
          },
          "requires_user_action": {
            "type": "boolean"
          },
          "preview_token": {
            "type": "string"
          }
        },
        "required": [
          "expires_at",
          "html",
          "preview_token",
          "recipient",
          "request_id",
          "requires_user_action",
          "sender",
          "subject"
        ]
      },
      "CustomerMessagingCaseCustomerResponseRequest": {
        "type": "object",
        "properties": {
          "full_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512
          },
          "date_of_birth": {
            "type": "string",
            "format": "date"
          },
          "file": {
            "type": "string",
            "format": "binary",
            "writeOnly": true
          }
        }
      },
      "CaseCollaborationCaseNoteReply": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "actor_name": {
            "type": "string",
            "nullable": true
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "comment": {
            "type": "string",
            "maxLength": 300
          }
        },
        "required": [
          "actor_email",
          "actor_name",
          "comment",
          "uuid"
        ]
      },
      "FraudCheckModuleReport": {
        "type": "object",
        "properties": {
          "module": {
            "$ref": "#/components/schemas/FraudExcludeEnum"
          },
          "status": {
            "$ref": "#/components/schemas/FraudStatusEnum"
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "latency_ms": {
            "type": "integer"
          },
          "freshness": {
            "type": "string",
            "nullable": true
          },
          "billable_units": {
            "type": "integer"
          }
        },
        "required": [
          "billable_units",
          "freshness",
          "latency_ms",
          "module",
          "reason",
          "status"
        ]
      },
      "CaseDuplicateEntityTypeEnum": {
        "enum": [
          "session",
          "business_session",
          "transaction"
        ],
        "type": "string",
        "description": "* `session` - 세션\n* `business_session` - 기업 세션\n* `transaction` - 거래"
      },
      "FraudClientCredentialsErrorMessage": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string",
            "default": "Authentication failed: Invalid client access token."
          }
        }
      },
      "FraudAvailabilityEnum": {
        "enum": [
          "available",
          "not_requested",
          "no_reference",
          "insufficient_history",
          "unsupported_region",
          "source_unavailable"
        ],
        "type": "string",
        "description": "* `available` - 사용 가능\n* `not_requested` - 요청되지 않음\n* `no_reference` - 참조 정보 없음\n* `insufficient_history` - 이력 불충분\n* `unsupported_region` - 미지원 지역\n* `source_unavailable` - 소스 사용 불가"
      },
      "CasePublicationPolicyDraftResponse": {
        "type": "object",
        "properties": {
          "draft": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CasePublicationPolicyDraft"
              }
            ],
            "nullable": true
          }
        },
        "required": [
          "draft"
        ]
      },
      "FraudCheckAttributesRequest": {
        "type": "object",
        "description": "보강 속성입니다. 모두 선택 사항이며 모듈 적용 범위를 넓혀줍니다.",
        "properties": {
          "first_name": {
            "type": "string",
            "maxLength": 128
          },
          "last_name": {
            "type": "string",
            "maxLength": 128
          },
          "full_name": {
            "type": "string",
            "maxLength": 256
          },
          "date_of_birth": {
            "type": "string",
            "format": "date"
          },
          "nationality": {
            "type": "string",
            "maxLength": 3
          },
          "gender": {
            "type": "string",
            "maxLength": 16
          },
          "address": {
            "type": "string",
            "maxLength": 512
          },
          "city": {
            "type": "string",
            "maxLength": 128
          },
          "state": {
            "type": "string",
            "maxLength": 128
          },
          "postal_code": {
            "type": "string",
            "maxLength": 32
          }
        }
      },
      "NetworkNote": {
        "type": "object",
        "required": [
          "uuid",
          "actor_email",
          "comment",
          "client_reference",
          "created_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "readOnly": true,
            "description": "서버에서 할당한 인증된 작성자입니다."
          },
          "comment": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10000
          },
          "client_reference": {
            "type": "string",
            "format": "uuid"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        }
      },
      "CaseActionEntityTypeEnum": {
        "enum": [
          "user",
          "business"
        ],
        "type": "string",
        "description": "* `user` - user\n* `business` - business"
      },
      "CaseRoutingCondition": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "enum": [
              "source",
              "priority",
              "tags"
            ]
          },
          "operator": {
            "type": "string",
            "enum": [
              "equals",
              "in",
              "contains"
            ]
          },
          "value": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          }
        },
        "required": [
          "field",
          "operator",
          "value"
        ],
        "description": "출처 및 우선순위는 지원되는 값을 사용하는 equals 또는 in을 지원합니다. 태그는 비어 있지 않은 단일 태그를 사용하는 contains를 지원합니다."
      },
      "RoutingPublicationPolicyRevision": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "snapshot": {},
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "maxLength": 254
          },
          "published_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "published_at",
          "snapshot",
          "version"
        ]
      },
      "CasePublicationPolicyRevision": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "snapshot": {},
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "maxLength": 254
          },
          "published_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "published_at",
          "snapshot",
          "version"
        ]
      },
      "FraudCheckIdentityRelationship": {
        "type": "object",
        "properties": {
          "result": {
            "$ref": "#/components/schemas/FraudResultEnum"
          },
          "reference_type": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "availability": {
            "$ref": "#/components/schemas/FraudAvailabilityEnum"
          },
          "reason_codes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "availability",
          "country",
          "reason_codes",
          "reference_type",
          "result"
        ]
      },
      "CasePublicationPaginatedPolicyRevisionList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=400&limit=100"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=200&limit=100"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CasePublicationPolicyRevision"
            }
          }
        }
      },
      "CaseDuplicateBlankEnum": {
        "enum": [
          ""
        ]
      },
      "FraudCheckPlan": {
        "type": "object",
        "properties": {
          "profile_id": {
            "type": "string"
          },
          "profile_version": {
            "type": "string"
          },
          "modules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudCheckPlannedModule"
            }
          },
          "estimated_price": {
            "type": "string",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "nullable": true
          },
          "is_sandbox": {
            "type": "boolean"
          },
          "can_afford": {
            "type": "boolean"
          }
        },
        "required": [
          "can_afford",
          "currency",
          "estimated_price",
          "is_sandbox",
          "modules",
          "profile_id",
          "profile_version"
        ]
      },
      "CaseReviewTeamUpdate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "members": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseReviewTeamMember"
            },
            "maxItems": 250
          },
          "is_active": {
            "type": "boolean"
          }
        }
      },
      "RoutingPublicationPolicyDraft": {
        "type": "object",
        "properties": {
          "revision": {
            "type": "string",
            "format": "uuid"
          },
          "base_version": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "changes": {},
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "maxLength": 254
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "base_version",
          "updated_at"
        ]
      },
      "FraudCheckRequestRequest": {
        "type": "object",
        "properties": {
          "client_reference": {
            "type": "string",
            "minLength": 1,
            "description": "이 검사에 대한 귀하 고유의 참조값입니다. 멱등성 키 역할을 겸합니다. 동일한 본문으로 재사용하면 모듈을 다시 실행하거나 비용을 청구하지 않고 원래 검사 결과를 반환하며, 다른 본문으로 재사용하면 409를 반환합니다.",
            "maxLength": 255
          },
          "profile": {
            "type": "string",
            "minLength": 1,
            "default": "standard",
            "description": "오케스트레이션 프로필 ID입니다. Didit `standard` 프로필이 기본값으로 사용됩니다.",
            "maxLength": 64
          },
          "profile_version": {
            "type": "string",
            "minLength": 1,
            "description": "동결된 프로필 버전을 고정합니다. 기본값은 프로필의 현재 버전입니다.",
            "maxLength": 32
          },
          "subject": {
            "$ref": "#/components/schemas/FraudCheckSubjectRequest"
          },
          "context": {
            "$ref": "#/components/schemas/FraudCheckContextRequest"
          },
          "checks": {
            "$ref": "#/components/schemas/FraudCheckModuleSelectionRequest"
          },
          "vendor_data": {
            "type": "string",
            "maxLength": 1000
          },
          "metadata": {}
        },
        "required": [
          "subject"
        ]
      },
      "CaseDuplicateCaseSubjectInputRequest": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/CaseDuplicateTypeEnum"
          },
          "uuid": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "type",
          "uuid"
        ]
      },
      "CaseReviewTeamMember": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "availability": {
            "type": "string",
            "enum": [
              "available",
              "unavailable"
            ],
            "default": "available"
          },
          "capacity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000,
            "default": 10
          },
          "skills": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            },
            "maxItems": 25
          },
          "available_from": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "available_until": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "user_id"
        ]
      },
      "CaseRoutingPreviewRequest": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "MANUAL",
              "AML_SCREENING",
              "TRANSACTION_RULE",
              "WORKFLOW_BUILDER"
            ]
          },
          "priority": {
            "type": "string",
            "enum": [
              "LOW",
              "MEDIUM",
              "HIGH"
            ],
            "default": "MEDIUM"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            },
            "maxItems": 50
          },
          "rule_uuid": {
            "type": "string",
            "format": "uuid"
          },
          "draft": {
            "$ref": "#/components/schemas/CaseRoutingRuleCreate"
          }
        },
        "required": [
          "source"
        ]
      },
      "FraudExcludeEnum": {
        "enum": [
          "normalization",
          "email_risk",
          "email_social",
          "phone_social",
          "phone_risk",
          "ip_risk",
          "database_validation",
          "networks_same_org",
          "networks_cross_org",
          "biometric_identity"
        ],
        "type": "string",
        "description": "* `normalization` - 정규화\n* `email_risk` - 이메일 위험\n* `email_social` - 이메일 소셜\n* `phone_social` - 전화번호 소셜\n* `phone_risk` - 전화번호 위험\n* `ip_risk` - IP 위험\n* `database_validation` - 데이터베이스 검증\n* `networks_same_org` - 동일 조직 네트워크\n* `networks_cross_org` - 조직 간 네트워크\n* `biometric_identity` - 생체 신원"
      },
      "CaseDuplicateCaseLinkCreateRequest": {
        "type": "object",
        "properties": {
          "entity_type": {
            "$ref": "#/components/schemas/CaseDuplicateEntityTypeEnum"
          },
          "entity_uuid": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "entity_type",
          "entity_uuid"
        ]
      },
      "CaseDuplicateStatusEnum": {
        "enum": [
          "OPEN",
          "AWAITING_USER",
          "RESOLVED"
        ],
        "type": "string",
        "description": "* `OPEN` - 열림\n* `AWAITING_USER` - 사용자 대기 중\n* `RESOLVED` - 해결됨"
      },
      "FraudBandEnum": {
        "enum": [
          "low",
          "medium",
          "high",
          "unknown"
        ],
        "type": "string",
        "description": "* `low` - 낮음\n* `medium` - 보통\n* `high` - 높음\n* `unknown` - 알 수 없음"
      },
      "CaseDuplicatePriorityEnum": {
        "enum": [
          "LOW",
          "MEDIUM",
          "HIGH"
        ],
        "type": "string",
        "description": "* `LOW` - 낮음\n* `MEDIUM` - 보통\n* `HIGH` - 높음"
      },
      "FraudStatusEnum": {
        "enum": [
          "planned",
          "completed",
          "skipped",
          "failed"
        ],
        "type": "string",
        "description": "* `planned` - 예정됨\n* `completed` - 완료됨\n* `skipped` - 건너뜀\n* `failed` - 실패함"
      },
      "FraudCheckInput": {
        "type": "object",
        "properties": {
          "reference": {
            "type": "string",
            "description": "제출된 식별자에 대해 마스킹 처리된 핸들입니다."
          },
          "type": {
            "$ref": "#/components/schemas/FraudTypeEnum"
          },
          "namespace": {
            "type": "object",
            "additionalProperties": {}
          },
          "quality": {
            "type": "string"
          },
          "normalization": {
            "type": "object",
            "additionalProperties": {}
          },
          "availability": {
            "$ref": "#/components/schemas/FraudAvailabilityEnum"
          }
        },
        "required": [
          "availability",
          "namespace",
          "normalization",
          "quality",
          "reference",
          "type"
        ]
      },
      "CustomerMessagingPurposesEnum": {
        "enum": [
          "identity_document",
          "proof_of_address",
          "business_document",
          "confirm_details",
          "review_in_progress"
        ],
        "type": "string",
        "description": "* `identity_document` - identity_document\n* `proof_of_address` - proof_of_address\n* `business_document` - business_document\n* `confirm_details` - confirm_details\n* `review_in_progress` - review_in_progress"
      },
      "FraudTypeEnum": {
        "enum": [
          "email",
          "phone",
          "national_id",
          "tax_number",
          "passport_number",
          "driving_licence_number",
          "residence_permit_number",
          "voter_id",
          "external_id"
        ],
        "type": "string",
        "description": "* `email` - 이메일\n* `phone` - 전화번호\n* `national_id` - 국가 신분증 번호\n* `tax_number` - 납세자 번호\n* `passport_number` - 여권 번호\n* `driving_licence_number` - 운전면허증 번호\n* `residence_permit_number` - 거주 허가증 번호\n* `voter_id` - 유권자 ID\n* `external_id` - 외부 ID"
      },
      "CaseDuplicateCaseSubjectInput": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/CaseDuplicateTypeEnum"
          },
          "uuid": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "type",
          "uuid"
        ]
      },
      "CaseReviewTeamCreate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "members": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseReviewTeamMember"
            },
            "maxItems": 250
          },
          "is_active": {
            "type": "boolean"
          }
        },
        "required": [
          "name",
          "members"
        ]
      },
      "CaseDuplicateCaseDuplicateQueryRequest": {
        "type": "object",
        "properties": {
          "subject": {
            "$ref": "#/components/schemas/CaseDuplicateCaseSubjectInputRequest"
          },
          "links": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseDuplicateCaseLinkCreateRequest"
            }
          },
          "offset": {
            "type": "integer",
            "maximum": 1000000,
            "minimum": 0,
            "default": 0
          }
        }
      },
      "CaseDuplicateResolutionEnum": {
        "enum": [
          "FALSE_POSITIVE",
          "VALID_THREAT"
        ],
        "type": "string",
        "description": "* `FALSE_POSITIVE` - 오탐\n* `VALID_THREAT` - 실제 위협"
      },
      "CasePublicationPolicyDraftWriteRequest": {
        "type": "object",
        "properties": {
          "expected_version": {
            "type": "integer",
            "minimum": 0
          },
          "expected_revision": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "changes": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": [
          "changes",
          "expected_revision",
          "expected_version"
        ]
      },
      "FraudCheckSubjectRequest": {
        "type": "object",
        "properties": {
          "selfie": {
            "type": "string",
            "minLength": 1,
            "description": "Base64 JPEG, PNG 또는 WebP 셀피로, 최대 6MB입니다. 참조 이미지나 URL은 허용되지 않습니다.",
            "maxLength": 8388672
          },
          "identifiers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudCheckIdentifierRequest"
            },
            "description": "하나 이상의 유형이 지정된 식별자입니다. 하나만 있어도 충분합니다.",
            "maxItems": 10,
            "minItems": 1
          },
          "attributes": {
            "$ref": "#/components/schemas/FraudCheckAttributesRequest"
          }
        },
        "required": [
          "identifiers"
        ]
      },
      "RoutingPublicationRoutingCondition": {
        "type": "object",
        "properties": {
          "field": {
            "$ref": "#/components/schemas/RoutingPublicationFieldEnum"
          },
          "operator": {
            "$ref": "#/components/schemas/RoutingPublicationOperatorEnum"
          },
          "value": {}
        },
        "required": [
          "field",
          "operator",
          "value"
        ]
      },
      "CaseActionCaseActionReceipt": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "client_reference": {
            "type": "string",
            "format": "uuid"
          },
          "action": {
            "type": "string",
            "maxLength": 32
          },
          "status": {
            "$ref": "#/components/schemas/CaseActionStatusEnum"
          },
          "result": {},
          "error": {
            "type": "string",
            "maxLength": 255
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "maxLength": 254
          },
          "attempts": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "action",
          "client_reference",
          "created_at",
          "status",
          "updated_at",
          "uuid"
        ]
      },
      "FraudCheckContextRequest": {
        "type": "object",
        "properties": {
          "ip_address": {
            "type": "string",
            "minLength": 1
          },
          "user_agent": {
            "type": "string",
            "maxLength": 512
          },
          "country": {
            "type": "string",
            "description": "대상자가 위치한다고 주장하는 국가입니다. 맥락 정보로만 사용되며, 신원 소유권의 증거로는 절대 사용할 수 없습니다.",
            "maxLength": 3
          },
          "purpose": {
            "type": "string",
            "maxLength": 128
          },
          "consent_obtained": {
            "type": "boolean"
          }
        }
      },
      "CustomerMessagingCaseCustomerResponseResult": {
        "type": "object",
        "properties": {
          "responded_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "responded_at"
        ]
      },
      "CustomerMessagingCaseRequestContact": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "verified_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "email",
          "uuid",
          "verified_at"
        ]
      },
      "FraudClientCredentialsForbiddenErrorMessage": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string",
            "default": "Forbidden - User doesn't have permission"
          }
        }
      },
      "CasePublicationAssignmentMethodEnum": {
        "enum": [
          "MANUAL",
          "AUTOMATIC"
        ],
        "type": "string",
        "description": "* `MANUAL` - 수동\n* `AUTOMATIC` - 자동"
      },
      "CaseDuplicateNullEnum": {
        "enum": [
          null
        ]
      },
      "CustomerMessagingLanguageEnum": {
        "enum": [
          "en",
          "es",
          "pt"
        ],
        "type": "string",
        "description": "* `en` - en\n* `es` - es\n* `pt` - pt"
      },
      "CaseDuplicateCaseFraudSourceContextRequest": {
        "type": "object",
        "properties": {
          "check_id": {
            "type": "string",
            "format": "uuid"
          },
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "source_section": {
            "type": "string",
            "minLength": 1,
            "pattern": "^[A-Z][A-Z0-9_:-]{0,63}$"
          }
        },
        "required": [
          "check_id",
          "request_id",
          "source_section"
        ]
      },
      "FraudCheckPlannedModule": {
        "type": "object",
        "properties": {
          "module": {
            "$ref": "#/components/schemas/FraudExcludeEnum"
          },
          "available": {
            "type": "boolean"
          },
          "availability_reason": {
            "type": "string",
            "nullable": true
          },
          "will_run": {
            "type": "boolean"
          },
          "selection_reason": {
            "type": "string",
            "nullable": true
          },
          "estimated_price": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "availability_reason",
          "available",
          "estimated_price",
          "module",
          "selection_reason",
          "will_run"
        ]
      },
      "CustomerMessagingCaseRequestOptions": {
        "type": "object",
        "properties": {
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomerMessagingCaseRequestContact"
            }
          },
          "purposes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomerMessagingPurposesEnum"
            }
          },
          "languages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomerMessagingLanguagesEnum"
            }
          }
        },
        "required": [
          "contacts",
          "languages",
          "purposes"
        ]
      },
      "CaseCollaborationPaginatedCaseNoteList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=400&limit=100"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=200&limit=100"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseCollaborationCaseNote"
            }
          }
        }
      },
      "FraudProcessingStatusEnum": {
        "enum": [
          "pending",
          "running",
          "completed",
          "failed"
        ],
        "type": "string",
        "description": "* `pending` - 대기 중\n* `running` - 실행 중\n* `completed` - 완료됨\n* `failed` - 실패함"
      },
      "CasePublicationCaseBlueprint": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "name": {
            "type": "string",
            "maxLength": 24
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "assignment_method": {
            "$ref": "#/components/schemas/CasePublicationAssignmentMethodEnum"
          },
          "assignee_pool": {},
          "max_active_cases": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0,
            "nullable": true
          },
          "escalation_enabled": {
            "type": "boolean"
          },
          "escalation_blueprint": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "escalation_blueprint_name": {
            "type": "string",
            "readOnly": true
          },
          "transfer_enabled": {
            "type": "boolean"
          },
          "four_eyes_checker_blueprint": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "four_eyes_checker_blueprint_name": {
            "type": "string",
            "readOnly": true
          },
          "require_resolution_note": {
            "type": "boolean"
          },
          "content_config": {},
          "version": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "default_deadline_hours": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0,
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          },
          "preset_key": {
            "type": "string",
            "nullable": true,
            "maxLength": 64
          },
          "creation_sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            },
            "readOnly": true
          },
          "receives_escalation_from": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            },
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "created_at",
          "creation_sources",
          "escalation_blueprint_name",
          "four_eyes_checker_blueprint_name",
          "name",
          "receives_escalation_from",
          "updated_at",
          "uuid"
        ]
      },
      "CaseRoutingRuleUpdate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "priority": {
            "type": "integer",
            "minimum": 0
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseRoutingCondition"
            },
            "maxItems": 20
          },
          "required_skills": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            },
            "maxItems": 25
          },
          "blueprint": {
            "type": "string",
            "format": "uuid"
          },
          "team": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          },
          "expected_version": {
            "type": "integer",
            "minimum": 1,
            "writeOnly": true,
            "description": "편집기에서 연 버전입니다. 제공된 경우 오래된 쓰기 작업은 규칙을 변경하지 않고 409를 반환합니다."
          }
        }
      },
      "CustomerMessagingCaseRequestPreviewRequest": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "format": "uuid"
          },
          "purpose": {
            "$ref": "#/components/schemas/CustomerMessagingPurposeEnum"
          },
          "language": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CustomerMessagingLanguageEnum"
              }
            ],
            "default": "en"
          }
        },
        "required": [
          "contact_id",
          "purpose"
        ]
      },
      "CaseDuplicateCaseFraudSourceContext": {
        "type": "object",
        "properties": {
          "check_id": {
            "type": "string",
            "format": "uuid"
          },
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "source_section": {
            "type": "string",
            "pattern": "^[A-Z][A-Z0-9_:-]{0,63}$"
          }
        },
        "required": [
          "check_id",
          "request_id",
          "source_section"
        ]
      },
      "RoutingPublicationOperatorEnum": {
        "enum": [
          "equals",
          "in",
          "contains"
        ],
        "type": "string",
        "description": "* `equals` - 일치\n* `in` - 포함(목록)\n* `contains` - 포함(문자열)"
      },
      "CaseRoutingPreview": {
        "type": "object",
        "properties": {
          "rule_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "rule_name": {
            "type": "string",
            "nullable": true
          },
          "rule_version": {
            "type": "integer",
            "nullable": true
          },
          "blueprint_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "team_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "assignee_user_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "reason": {
            "type": "string"
          },
          "candidates": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "user_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "eligible": {
                  "type": "boolean"
                },
                "active_cases": {
                  "type": "integer",
                  "nullable": true
                },
                "reason": {
                  "type": "string",
                  "nullable": true
                }
              }
            }
          },
          "matched_rules": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "priority": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "FraudDimensionEnum": {
        "enum": [
          "identity",
          "contact",
          "device_network",
          "behavioral",
          "fraud_network"
        ],
        "type": "string",
        "description": "* `identity` - 신원\n* `contact` - 연락처\n* `device_network` - 기기 및 네트워크\n* `behavioral` - 행동\n* `fraud_network` - 사기 네트워크"
      },
      "FraudBadRequestErrorMessage": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string",
            "default": "Bad Request - Invalid request data"
          }
        }
      },
      "FraudNextActionEnum": {
        "enum": [
          "none",
          "manual_review",
          "step_up",
          "resubmit_capture"
        ],
        "type": "string",
        "description": "* `none` - 없음\n* `manual_review` - 수동 검토\n* `step_up` - 추가 인증\n* `resubmit_capture` - 캡처 재제출"
      },
      "RoutingPublicationPolicyDraftPreconditionRequest": {
        "type": "object",
        "properties": {
          "expected_version": {
            "type": "integer",
            "minimum": 0
          },
          "expected_revision": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          }
        },
        "required": [
          "expected_revision",
          "expected_version"
        ]
      },
      "FraudCheckRisk": {
        "type": "object",
        "properties": {
          "dimension": {
            "$ref": "#/components/schemas/FraudDimensionEnum"
          },
          "score": {
            "type": "integer",
            "nullable": true
          },
          "band": {
            "$ref": "#/components/schemas/FraudBandEnum"
          },
          "availability": {
            "$ref": "#/components/schemas/FraudAvailabilityEnum"
          },
          "requested_but_unavailable": {
            "type": "boolean",
            "description": "요청이 이 차원에 필요한 모든 것을 제공했음에도 플랫폼에서 응답할 수 없는 경우 true입니다. 이러한 확인은 응답한 차원의 결과만을 근거로 승인을 권장하지 않습니다."
          },
          "reason_codes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "evidence_indexes": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          }
        },
        "required": [
          "availability",
          "band",
          "dimension",
          "evidence_indexes",
          "reason_codes",
          "requested_but_unavailable",
          "score"
        ]
      },
      "CaseDuplicateSourceEnum": {
        "enum": [
          "MANUAL",
          "AML_SCREENING",
          "TRANSACTION_RULE",
          "WORKFLOW_BUILDER"
        ],
        "type": "string",
        "description": "* `MANUAL` - 수동\n* `AML_SCREENING` - AML 스크리닝\n* `TRANSACTION_RULE` - 거래 규칙\n* `WORKFLOW_BUILDER` - 워크플로 빌더"
      },
      "CaseCollaborationPatchedCaseNoteUpdateRequest": {
        "type": "object",
        "properties": {
          "is_pinned": {
            "type": "boolean"
          }
        }
      },
      "CustomerMessagingPurposeEnum": {
        "enum": [
          "identity_document",
          "proof_of_address",
          "business_document",
          "confirm_details",
          "review_in_progress"
        ],
        "type": "string",
        "description": "* `identity_document` - identity_document\n* `proof_of_address` - proof_of_address\n* `business_document` - business_document\n* `confirm_details` - confirm_details\n* `review_in_progress` - review_in_progress"
      },
      "CaseDuplicateTypeEnum": {
        "enum": [
          "user",
          "business"
        ],
        "type": "string",
        "description": "* `user` - user\n* `business` - business"
      },
      "CaseCollaborationCaseNoteCreateRequest": {
        "type": "object",
        "properties": {
          "comment": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10000
          },
          "reply_to": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "client_reference": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "mentioned_emails": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email",
              "minLength": 1
            }
          },
          "is_internal": {
            "type": "boolean",
            "default": false
          },
          "attachments": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            }
          }
        },
        "required": [
          "comment"
        ]
      },
      "CustomerMessagingLanguagesEnum": {
        "enum": [
          "en",
          "es",
          "pt"
        ],
        "type": "string",
        "description": "* `en` - en\n* `es` - es\n* `pt` - pt"
      },
      "CustomerMessagingCaseRequestConfirmRequest": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "format": "uuid"
          },
          "purpose": {
            "$ref": "#/components/schemas/CustomerMessagingPurposeEnum"
          },
          "language": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CustomerMessagingLanguageEnum"
              }
            ],
            "default": "en"
          },
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "preview_token": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512
          }
        },
        "required": [
          "contact_id",
          "expires_at",
          "preview_token",
          "purpose",
          "request_id"
        ]
      },
      "CaseRoutingRule": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "priority": {
            "type": "integer",
            "minimum": 0
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseRoutingCondition"
            },
            "maxItems": 20
          },
          "required_skills": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            },
            "maxItems": 25
          },
          "blueprint": {
            "type": "string",
            "format": "uuid"
          },
          "team": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          },
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "version": {
            "type": "integer",
            "readOnly": true
          },
          "blueprint_name": {
            "type": "string",
            "readOnly": true
          },
          "team_name": {
            "type": "string",
            "nullable": true,
            "readOnly": true
          }
        }
      },
      "FraudResultEnum": {
        "enum": [
          "match",
          "mismatch",
          "inconclusive",
          "no_reference"
        ],
        "type": "string",
        "description": "* `match` - 일치\n* `mismatch` - 불일치\n* `inconclusive` - 판정 불가\n* `no_reference` - 참조 정보 없음"
      },
      "CaseRoutingRuleCreate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "priority": {
            "type": "integer",
            "minimum": 0
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseRoutingCondition"
            },
            "maxItems": 20
          },
          "required_skills": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            },
            "maxItems": 25
          },
          "blueprint": {
            "type": "string",
            "format": "uuid"
          },
          "team": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          },
          "publish": {
            "type": "boolean",
            "writeOnly": true,
            "description": "게시된 적 없는 초안으로 저장하려면 false로 설정합니다. 초안이 명시적으로 게시될 때까지 레코드는 버전 0인 비활성 상태로 유지됩니다. 이 필드를 생략하면 기존 연동에 대해 즉시 생성이 유지됩니다."
          }
        },
        "required": [
          "name",
          "conditions",
          "blueprint"
        ]
      },
      "FraudCheckIdentifierRequest": {
        "type": "object",
        "properties": {
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FraudTypeEnum"
              }
            ],
            "description": "식별자 유형입니다. 필수 네임스페이스 필드를 결정합니다.\n\n* `email` - 이메일\n* `phone` - 전화번호\n* `national_id` - 국가 ID\n* `tax_number` - 납세자 번호\n* `passport_number` - 여권 번호\n* `driving_licence_number` - 운전면허증 번호\n* `residence_permit_number` - 거주 허가증 번호\n* `voter_id` - 유권자 ID\n* `external_id` - 외부 ID"
          },
          "value": {
            "type": "string",
            "minLength": 1,
            "description": "통상적으로 사용되는 형식의 식별자 값입니다.",
            "maxLength": 255
          },
          "country": {
            "type": "string",
            "description": "ISO-3166 alpha-2 또는 alpha-3 발급 국가입니다. 정부 발급 식별자 유형에 필수입니다. 동일한 번호라도 국가마다 다른 사람을 나타냅니다.",
            "maxLength": 3
          },
          "issuer": {
            "type": "string",
            "description": "국가만으로는 고유하지 않은 경우의 선택적 발급 기관 또는 국가 하위 단위 발급 기관입니다.",
            "maxLength": 128
          }
        },
        "required": [
          "type",
          "value"
        ]
      },
      "CaseActionActionEnum": {
        "enum": [
          "set_status",
          "add_tags",
          "add_note",
          "add_to_blocklist"
        ],
        "type": "string",
        "description": "* `set_status` - set_status\n* `add_tags` - add_tags\n* `add_note` - add_note\n* `add_to_blocklist` - add_to_blocklist"
      },
      "CaseActionCaseActionReceiptPage": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "next_offset": {
            "type": "integer",
            "nullable": true
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseActionCaseActionReceipt"
            }
          }
        },
        "required": [
          "count",
          "next_offset",
          "results"
        ]
      },
      "CaseActionCaseEntityActionResult": {
        "type": "object",
        "properties": {
          "receipt": {
            "$ref": "#/components/schemas/CaseActionCaseActionReceipt"
          },
          "entity_type": {
            "$ref": "#/components/schemas/CaseActionEntityTypeEnum"
          },
          "entity_uuid": {
            "type": "string",
            "format": "uuid"
          },
          "action": {
            "type": "string"
          },
          "previous_status": {
            "type": "string"
          },
          "new_status": {
            "type": "string"
          },
          "tags_added": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "comment_uuid": {
            "type": "string",
            "format": "uuid"
          },
          "blocklisted": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CustomerMessagingCaseRequest": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "purpose": {
            "type": "string",
            "readOnly": true
          },
          "language": {
            "type": "string",
            "readOnly": true
          },
          "recipient": {
            "type": "string",
            "format": "email",
            "readOnly": true
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "readOnly": true,
            "nullable": true
          },
          "delivery_status": {
            "type": "string",
            "readOnly": true
          },
          "delivered_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true,
            "nullable": true
          },
          "cancelled_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true,
            "nullable": true
          },
          "responded_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true,
            "nullable": true
          },
          "response": {
            "readOnly": true,
            "nullable": true
          },
          "has_attachment": {
            "type": "boolean",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "actor_email",
          "cancelled_at",
          "created_at",
          "delivered_at",
          "delivery_status",
          "expires_at",
          "has_attachment",
          "language",
          "purpose",
          "recipient",
          "responded_at",
          "response",
          "uuid"
        ]
      },
      "CustomerMessagingCaseRequestPublic": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "purpose": {
            "$ref": "#/components/schemas/CustomerMessagingPurposeEnum"
          },
          "language": {
            "$ref": "#/components/schemas/CustomerMessagingLanguageEnum"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "responded_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "copy": {
            "type": "object",
            "additionalProperties": {}
          },
          "organization_name": {
            "type": "string"
          },
          "is_white_label": {
            "type": "boolean"
          },
          "customization": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true
          }
        },
        "required": [
          "copy",
          "customization",
          "expires_at",
          "is_white_label",
          "language",
          "organization_name",
          "purpose",
          "request_id",
          "responded_at"
        ]
      },
      "RoutingPublicationFieldEnum": {
        "enum": [
          "source",
          "priority",
          "tags"
        ],
        "type": "string",
        "description": "* `source` - source\n* `priority` - priority\n* `tags` - tags"
      },
      "RoutingPublicationCaseRoutingRule": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "priority": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoutingPublicationRoutingCondition"
            }
          },
          "required_skills": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            },
            "maxItems": 25
          },
          "blueprint": {
            "type": "string",
            "format": "uuid"
          },
          "blueprint_name": {
            "type": "string",
            "readOnly": true
          },
          "team": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "team_name": {
            "type": "string",
            "readOnly": true
          },
          "is_active": {
            "type": "boolean"
          },
          "version": {
            "type": "integer",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "blueprint",
          "blueprint_name",
          "conditions",
          "created_at",
          "name",
          "team_name",
          "updated_at",
          "uuid",
          "version"
        ]
      },
      "CaseActionStatusEnum": {
        "enum": [
          "APPLIED",
          "FAILED"
        ],
        "type": "string",
        "description": "* `APPLIED` - 적용됨\n* `FAILED` - 실패함"
      },
      "FraudCheckModuleSelectionRequest": {
        "type": "object",
        "properties": {
          "include": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudExcludeEnum"
            }
          },
          "exclude": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudExcludeEnum"
            }
          }
        }
      },
      "SignatureField": {
        "type": "object",
        "description": "세션 문서에 배치할 필드입니다. 어느 서명인이 어떻게, 어디에 채우는지를 지정합니다. 위치(`page`, `x`, `y`, `width`, `height`) 또는 `anchor` 중 하나를 제공하십시오. 위치는 표시되는 페이지의 왼쪽 상단 모서리를 기준으로 소수점 4자리까지 반올림된 비율 값이며, 필드는 페이지 내에 맞아야 합니다. 문서는 최대 200개의 필드를, 한 명의 서명인은 최대 500개까지 가질 수 있으며, 문서에 필드가 있는 모든 역할은 해당 문서에 `signature` 또는 `initials` 필드가 필요합니다. [문서의 필드](/ko/core-technology/electronic-signature/overview#문서의-필드)를 참조하십시오.",
        "required": [
          "key",
          "type"
        ],
        "properties": {
          "key": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9_]{0,63}$",
            "description": "결과 및 `sign.field_values`에서 필드를 지정합니다. 문서 내에서 고유해야 합니다."
          },
          "type": {
            "type": "string",
            "enum": [
              "signature",
              "initials",
              "full_name",
              "date_signed",
              "text",
              "checkbox",
              "email",
              "data"
            ],
            "description": "필드에 포함되는 내용입니다. 서명자는 본인이 채택한 `signature` 및 `initials`를 적용하고, `text`를 입력하며, `checkbox`를 선택하고, 세션에 인증된 이메일이 없는 경우 `email`을 입력합니다. Didit은 `full_name`(인증된 성명), `date_signed`(서명자 시간대의 서명 날짜), `data`(`prefill`에서 가져옴) 및 인증된 `email`을 채우고 읽기 전용으로 표시합니다. 날짜 선택기 유형은 없으므로 `text`를 사용하십시오."
          },
          "role": {
            "type": "string",
            "enum": [
              "verified_person",
              "legal_representative",
              "key_people"
            ],
            "description": "`signature_signer` 값을 사용하여 필드를 채우는 주체입니다. 단계는 자체 서명자의 필드만 작성하고 스탬프를 찍습니다. 기본값은 해당 단계의 서명자입니다."
          },
          "page": {
            "type": "integer",
            "minimum": 1,
            "description": "페이지 번호(1부터 문서의 전체 페이지 수까지)입니다. Word 문서의 경우 변환된 PDF의 페이지입니다."
          },
          "x": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "페이지 너비의 비율로 표시된 왼쪽 가장자리입니다."
          },
          "y": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "페이지 높이 비율 기준 상단 가장자리입니다."
          },
          "width": {
            "type": "number",
            "minimum": 0.02,
            "maximum": 1,
            "description": "페이지 너비에 대한 비율로 나타낸 너비입니다. 서명 너비는 최소 `0.12`입니다."
          },
          "height": {
            "type": "number",
            "minimum": 0.012,
            "maximum": 1,
            "description": "페이지 높이에 대한 비율로 나타낸 높이입니다. 서명은 최소 `0.035` 높이여야 합니다."
          },
          "anchor": {
            "$ref": "#/components/schemas/SignatureFieldAnchor"
          },
          "required": {
            "type": "boolean",
            "description": "`signature` and `initials` are required unless you set `false`. `full_name`, `date_signed` and `data` are always required. The signer can't finish a document until its required fields have a value, and a required checkbox must be ticked."
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "description": "서명자와 결과에 표시됩니다. 유형에 따른 기본값이 적용됩니다."
          },
          "placeholder": {
            "type": "string",
            "nullable": true,
            "maxLength": 80,
            "description": "`text` 및 `email`만 해당합니다."
          },
          "validation": {
            "$ref": "#/components/schemas/SignatureFieldValidation"
          },
          "prefill": {
            "type": "string",
            "nullable": true,
            "description": "값의 출처: `identity.full_name`, `identity.first_name`, `identity.last_name`, `identity.date_of_birth`(`DD/MM/YYYY`), `identity.nationality`, `identity.document_number`, `identity.document_type`, `identity.issuing_country`, `identity.address`, `contact.email`, `contact.phone`, `company.name`, `company.registration_number`, `company.address`, `company.country`(KYB), `session.vendor_data`, `metadata.<key>`(세션 `metadata`의 키) 또는 `api.<key>`(`sign.field_values`의 키). `data`에 필수입니다. `full_name`은 항상 `identity.full_name`을 사용하고 `email`은 `contact.email`을 사용합니다. `data`, `full_name` 및 인증된 `email` 필드의 값은 서명자가 서명을 시작할 때 고정됩니다."
          },
          "editable_when_prefilled": {
            "type": "boolean",
            "default": false,
            "description": "`text` 및 `email`만 해당: 서명자가 사전 입력된 값을 변경할 수 있습니다."
          },
          "checked_by_default": {
            "type": "boolean",
            "default": false,
            "description": "`checkbox` 전용: 확인란이 선택된 상태로 시작합니다."
          },
          "date_format": {
            "type": "string",
            "enum": [
              "DD/MM/YYYY",
              "MM/DD/YYYY",
              "YYYY-MM-DD",
              "D MMMM YYYY"
            ],
            "default": "DD/MM/YYYY",
            "description": "`date_signed`만 해당합니다."
          }
        }
      },
      "SessionSignDocument": {
        "type": "object",
        "required": [
          "file_name",
          "content_base64"
        ],
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "서명자에게 표시되는 제목입니다. 기본값은 `file_name`입니다."
          },
          "file_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "`.pdf` 또는 `.docx`로 끝나는 파일 이름입니다."
          },
          "content_base64": {
            "type": "string",
            "format": "byte",
            "description": "Base64로 인코딩된 파일입니다. PDF는 비밀번호, 스크립트 또는 첨부 파일 없이 최대 20MB 및 100페이지까지 가능합니다. Word 파일(`.docx`)은 최대 20MB까지 가능하며, 요청이 실행되는 동안 최대 25초 이내에 PDF로 변환됩니다. 변환된 PDF에도 동일한 제한이 적용됩니다. 세션당 최대 5개의 Word 파일을 지원합니다. 매크로, 변경 내용 추적, 외부 콘텐츠 링크 또는 포함된 개체가 있는 Word 파일은 `signature_document_not_supported`와 함께 거부되며, 변환할 수 없는 파일은 `signature_document_conversion_failed`를 반환하고 각각 `reason`이 포함됩니다."
          },
          "fields": {
            "type": "array",
            "description": "이 문서에 배치할 선택적 필드로, 최대 200개까지 지정할 수 있습니다. 페이지 및 위치는 PDF 또는 Word 파일이 변환된 PDF를 기준으로 합니다. 필드가 없으면 서명자는 문서를 읽고 동의하게 됩니다.",
            "items": {
              "$ref": "#/components/schemas/SignatureField"
            },
            "maxItems": 200
          }
        }
      },
      "SignatureResult": {
        "type": "object",
        "description": "하나의 전자 서명 단계에 대한 서명자 1명의 결과입니다. [전자 서명 보고서](/ko/core-technology/electronic-signature/report-electronic-signature)를 참조하십시오.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "이 서명자의 증빙을 다운로드하거나 서명을 검증하려면 `signature_id`로 전달하세요."
          },
          "node_id": {
            "type": "string",
            "description": "이를 생성한 워크플로 단계입니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "intro",
              "review",
              "code",
              "signing",
              "signed",
              "declined"
            ],
            "description": "해당 단계에서 서명자의 진행 위치입니다. `signed`인 경우에만 문서가 서명되었음을 의미합니다."
          },
          "verdict": {
            "type": "string",
            "enum": [
              "Not Finished",
              "Approved",
              "In Review",
              "Declined"
            ],
            "description": "단계의 결과입니다. 경고가 발생하면 해당 규칙을 통해 설정되며, 커스텀 상태 규칙은 그 이후에 적용됩니다."
          },
          "level": {
            "type": "string",
            "enum": [
              "simple",
              "aes",
              "qes"
            ],
            "description": "`simple`(기본값) 또는 `aes`입니다. `qes`(적격 전자 서명, QES)는 아직 제공되지 않는 부가 기능입니다."
          },
          "format": {
            "type": "string",
            "enum": [
              "pdf",
              "pades"
            ],
            "description": "Simple 서명의 경우 `pdf`, Advanced(AES)의 경우 `pades`입니다."
          },
          "profile": {
            "type": "string",
            "nullable": true,
            "description": "고급(AES) 서명이 생성되면 `PAdES-B-LT`, 그렇지 않은 경우 null."
          },
          "signer": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "nullable": true,
                "description": "서명자의 성명입니다. 인증된 세션 성명이 없는 Simple 등급(서명자가 직접 입력한 이름이며 인증되지 않음)을 제외하고는 검증 완료된 성명(승인된 신분증 인증 또는 세션에서 추출)입니다."
              },
              "capacity": {
                "type": "string",
                "enum": [
                  "self",
                  "company"
                ]
              },
              "company": {
                "type": "string",
                "nullable": true
              },
              "role": {
                "type": "string",
                "nullable": true,
                "description": "신고된 주요 인물의 직함입니다."
              },
              "roles": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "기업에 대해 신고된 주요 인물의 구조화된 역할입니다."
              },
              "identity_session_id": {
                "type": "string",
                "format": "uuid",
                "description": "서명자를 인증한 KYC 세션입니다."
              }
            }
          },
          "identity_used": {
            "type": "object",
            "description": "서명이 기반으로 하는 인증된 신원입니다. 인증된 신원이 없는 Simple 서명의 경우 비어 있습니다.",
            "properties": {
              "session_id": {
                "type": "string",
                "format": "uuid"
              },
              "kyc_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true
              },
              "verified": {
                "type": "boolean"
              },
              "expected_name": {
                "type": "string",
                "nullable": true,
                "description": "서명자가 일치해야 했던 이름입니다."
              }
            }
          },
          "certificate": {
            "type": "object",
            "nullable": true,
            "description": "문서 서명에 사용된 인증서입니다. 서명되기 전까지는 `null`이며, 단순 서명의 경우 항상 `null`입니다.",
            "properties": {
              "issuer": {
                "type": "string"
              },
              "issued_to": {
                "type": "string"
              },
              "serial": {
                "type": "string",
                "description": "일련번호(16진수)입니다."
              },
              "valid_from": {
                "type": "string",
                "format": "date-time"
              },
              "valid_until": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "confirmation": {
            "type": "object",
            "properties": {
              "channel": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "email",
                  "sms"
                ],
                "description": "코드가 없는 Simple 서명의 경우 `null`입니다."
              },
              "destination": {
                "type": "string",
                "nullable": true,
                "description": "코드가 전송된 마스킹된 연락처입니다."
              },
              "confirmed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "attempts": {
                "type": "integer",
                "description": "입력된 코드(올바른 코드 포함)."
              }
            }
          },
          "timestamp": {
            "type": "object",
            "nullable": true,
            "description": "Didit에서 발급한 서명의 RFC 3161 타임스탬프입니다. 서명 전까지는 `null`이며, 단순 서명의 경우 항상 `null`입니다.",
            "properties": {
              "time": {
                "type": "string",
                "format": "date-time"
              },
              "qualified": {
                "type": "boolean",
                "description": "AES의 경우 항상 `false`입니다."
              },
              "valid": {
                "type": "boolean"
              }
            }
          },
          "documents": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "해당 서명자 사본에 포함된 문서입니다. 서명된 파일을 다운로드하는 데 사용하세요."
                },
                "uuid": {
                  "type": "string",
                  "format": "uuid",
                  "description": "`id`와 동일합니다."
                },
                "title": {
                  "type": "string"
                },
                "file_name": {
                  "type": "string"
                },
                "pages": {
                  "type": "integer",
                  "description": "서명된 문서의 페이지입니다. Word의 경우 변환된 PDF의 페이지입니다."
                },
                "size_bytes": {
                  "type": "integer"
                },
                "sha256_original": {
                  "type": "string",
                  "description": "서명자에게 표시된 문서의 SHA-256입니다."
                },
                "sha256_signed": {
                  "type": "string",
                  "nullable": true,
                  "description": "서명 완료 후 서명된 PDF의 SHA-256입니다."
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "signed",
                    "declined",
                    "not_signed",
                    "not_reached"
                  ],
                  "description": "`not_signed`: 열람했으나 서명하지 않았습니다. `not_reached`: 열람한 적이 없습니다."
                },
                "opened_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true
                },
                "read_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true,
                  "description": "해당 단계에서 요구할 때 서명자가 필드가 없는 문서의 끝에 도달한 시점입니다."
                },
                "read_to_end": {
                  "type": "boolean"
                },
                "consented_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true,
                  "description": "서명자가 필드가 없는 문서에 동의했거나, 필드가 있는 문서의 필드 작성을 완료한 시점입니다."
                },
                "consent": {
                  "type": "boolean"
                },
                "signed_file": {
                  "type": "string",
                  "nullable": true,
                  "description": "서명 완료된 PDF의 경로입니다. [서명된 문서 다운로드](/ko/sessions-api/electronic-signature/download-signed-document)를 참고하세요."
                },
                "mode": {
                  "type": "string",
                  "enum": [
                    "fields",
                    "read_and_agree"
                  ],
                  "description": "필드가 있는 문서의 경우 `fields`, 없는 문서의 경우 `read_and_agree`."
                },
                "source_format": {
                  "type": "string",
                  "enum": [
                    "pdf",
                    "docx"
                  ],
                  "description": "`pdf` 또는 Didit에서 PDF로 변환한 Word 문서의 경우 `docx`입니다."
                },
                "conversion": {
                  "type": "object",
                  "nullable": true,
                  "description": "PDF의 경우 `null`입니다. Word 문서의 경우 원본 파일 및 변환 파일입니다.",
                  "properties": {
                    "from": {
                      "type": "string",
                      "enum": [
                        "docx"
                      ]
                    },
                    "file_name": {
                      "type": "string",
                      "description": "귀하의 원본 Word 파일 이름입니다."
                    },
                    "sha256": {
                      "type": "string",
                      "description": "원본 Word 파일의 SHA-256입니다."
                    },
                    "size_bytes": {
                      "type": "integer",
                      "description": "원본 Word 파일 크기입니다."
                    },
                    "converter": {
                      "type": "string",
                      "description": "PDF를 생성한 변환기의 버전입니다."
                    }
                  }
                },
                "fields": {
                  "type": "array",
                  "description": "문서의 필드와 해당 값입니다. 필드가 없는 문서의 경우 비어 있습니다.",
                  "items": {
                    "$ref": "#/components/schemas/SignatureFieldResult"
                  }
                }
              }
            }
          },
          "adopted_signature": {
            "type": "object",
            "nullable": true,
            "description": "서명자가 서명 및 이니셜 필드에 적용한 서명과 이니셜입니다. 서명자가 적용하기 전까지는 `null`입니다.",
            "properties": {
              "method": {
                "type": "string",
                "enum": [
                  "typed",
                  "drawn"
                ],
                "description": "`typed`: 필기체 스타일로 작성된 인증된 이름입니다. `drawn`: 손가락이나 마우스로 그린 것입니다."
              },
              "font": {
                "type": "string",
                "nullable": true,
                "description": "입력된 서명의 필기체 스타일입니다. 직접 그린 경우 `null`입니다."
              },
              "adopted_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "electronic_signature_consent_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "서명자가 검토 화면에서 문서 전자 서명에 동의한 시점입니다. 문서에 필드가 하나라도 있는 경우 설정됩니다."
          },
          "evidence_file": {
            "type": "string",
            "nullable": true,
            "description": "서명 완료 후 증빙 PDF의 경로입니다. [서명 증빙 다운로드](/ko/sessions-api/electronic-signature/download-evidence)를 참조하세요."
          },
          "warnings": {
            "type": "array",
            "description": "이 서명자에 대해 발생한 경고입니다. [전자 서명 경고](/ko/core-technology/electronic-signature/warnings-electronic-signature)를 참고하세요.",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "enum": [
                    "SIGNATURE_DECLINED",
                    "SIGNATURE_OTP_FAILED",
                    "SIGNATURE_NAME_MISMATCH",
                    "SIGNATURE_IDENTITY_NOT_VERIFIED",
                    "SIGNATURE_DOCUMENT_CHANGED",
                    "SIGNATURE_FIELD_DATA_MISSING"
                  ]
                },
                "node_id": {
                  "type": "string"
                }
              }
            }
          },
          "validation": {
            "type": "object",
            "nullable": true,
            "description": "서명된 문서의 마지막 암호학적 검증입니다. 문서가 서명될 때까지 `null`입니다. Didit이 서명 결과를 확인할 수 없는 경우 `{\"valid\": null, \"reason\": \"signature_provider_outcome_unknown\", \"checked_at\": ...}`이며 `status`는 `signing`으로 유지됩니다. 서명되지 않은 것으로 처리하십시오.",
            "properties": {
              "valid": {
                "type": "boolean",
                "nullable": true,
                "description": "모든 문서가 유효한 경우 `true`입니다. 서명 결과를 확인할 수 없는 경우 `null`입니다."
              },
              "reason": {
                "type": "string",
                "description": "`valid`가 `null`일 때 설정됩니다: `signature_provider_outcome_unknown`."
              },
              "checked_at": {
                "type": "string",
                "format": "date-time"
              },
              "documents": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "checked_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "valid": {
                      "type": "boolean",
                      "description": "서명과 타임스탬프가 모두 유효하고 신뢰할 수 있는 경우 `true`입니다."
                    },
                    "integrity": {
                      "type": "boolean",
                      "description": "서명 이후 문서가 변경되지 않은 경우 `true`입니다."
                    },
                    "trusted": {
                      "type": "boolean",
                      "description": "서명 인증서가 신뢰할 수 있는 루트로 체인되는 경우 `true`입니다."
                    },
                    "revoked": {
                      "type": "boolean"
                    },
                    "trusted_list": {
                      "type": "object",
                      "description": "EU 신뢰 목록(EU Trusted List) 확인입니다. AES의 경우: `{\"status\": \"not_applicable\", \"reason\": \"aes_not_qualified\"}`.",
                      "properties": {
                        "status": {
                          "type": "string"
                        },
                        "reason": {
                          "type": "string"
                        }
                      }
                    },
                    "certificate": {
                      "type": "object",
                      "nullable": true,
                      "description": "문서 서명에 사용된 인증서입니다. 서명되기 전까지는 `null`이며, 단순 서명의 경우 항상 `null`입니다.",
                      "properties": {
                        "issuer": {
                          "type": "string"
                        },
                        "issued_to": {
                          "type": "string"
                        },
                        "serial": {
                          "type": "string",
                          "description": "일련번호(16진수)입니다."
                        },
                        "valid_from": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "valid_until": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    },
                    "timestamp": {
                      "type": "object",
                      "nullable": true,
                      "description": "Didit에서 발급한 서명의 RFC 3161 타임스탬프입니다. 서명 전까지는 `null`이며, 단순 서명의 경우 항상 `null`입니다.",
                      "properties": {
                        "time": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "qualified": {
                          "type": "boolean",
                          "description": "AES의 경우 항상 `false`입니다."
                        },
                        "valid": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "declined_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "declined_action": {
            "type": "string",
            "enum": [
              "DECLINE",
              "REVIEW",
              "NO_ACTION"
            ]
          },
          "signed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "서명 링크의 작동이 중단되는 시점입니다."
          },
          "email_sent_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "email_unavailable_reason": {
            "type": "string",
            "nullable": true
          },
          "ip_address": {
            "type": "string",
            "nullable": true,
            "description": "서명자가 코드를 요청했을 때의 IP 주소입니다."
          },
          "place": {
            "type": "string",
            "nullable": true,
            "description": "수집되지 않음: 항상 `null`입니다."
          },
          "place_unavailable_reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "not_collected"
            ]
          }
        }
      },
      "SignatureFieldValidation": {
        "type": "object",
        "nullable": true,
        "description": "`text` 필드 값에 대한 규칙입니다. 콘솔 미리보기, 서명 워크플로 및 API는 동일한 규칙을 적용합니다.",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "any",
              "letters",
              "number",
              "email",
              "pattern"
            ],
            "description": "`letters`: 모든 문자 체계의 문자, 공백, 하이픈 및 아포스트로피입니다. `number`: 선택적 소수점 구분 기호가 포함된 숫자입니다. `pattern`: 값은 `pattern`과 일치해야 합니다."
          },
          "min_length": {
            "type": "integer",
            "minimum": 0,
            "maximum": 500,
            "description": "`0`부터 `max_length`까지입니다."
          },
          "max_length": {
            "type": "integer",
            "minimum": 1,
            "maximum": 500,
            "default": 120
          },
          "pattern": {
            "type": "string",
            "nullable": true,
            "minLength": 1,
            "maxLength": 200,
            "description": "`kind: \"pattern\"`인 경우 필수입니다. 전체 값이 일치해야 하는 정규식입니다. 전방/후방 탐색(Lookaround) 및 역참조(backreference)는 지원되지 않습니다."
          },
          "message": {
            "type": "string",
            "nullable": true,
            "maxLength": 120,
            "description": "기본 오류 대신 서명자에게 표시됩니다."
          }
        }
      },
      "SignatureFieldAnchor": {
        "type": "object",
        "description": "위치 대신 문서 내의 텍스트 일부를 기준으로 필드를 배치합니다. Didit은 PDF에서 해당 텍스트를 제거하지 않으므로 페이지 배경과 동일한 색상으로 작성하십시오. 텍스트를 찾을 수 없는 경우 호출 시 `field_anchor_not_found`와 함께 `400`이 반환됩니다. [앵커 텍스트로 필드 배치하기](/ko/sessions-api/create-session#앵커-텍스트로-필드-배치)를 참조하십시오.",
        "required": [
          "text"
        ],
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "description": "문서에서 검색된 텍스트입니다. Word 파일의 경우 변환된 PDF 내에서 검색됩니다."
          },
          "occurrence": {
            "type": "string",
            "enum": [
              "first",
              "all"
            ],
            "default": "first",
            "description": "`all`은 일치 항목당 하나의 필드를 배치합니다. 첫 번째 키 이후의 키에는 `_2`, `_3` 등이 붙습니다."
          },
          "offset_x": {
            "type": "number",
            "description": "페이지 너비의 비율로 텍스트의 왼쪽 가장자리에 추가됩니다."
          },
          "offset_y": {
            "type": "number",
            "description": "페이지 높이의 비율로 텍스트의 위쪽 가장자리에 추가됩니다."
          },
          "width": {
            "type": "number",
            "minimum": 0.02,
            "maximum": 1,
            "description": "페이지 너비에 대한 비율로 나타낸 필드 너비입니다."
          },
          "height": {
            "type": "number",
            "minimum": 0.012,
            "maximum": 1,
            "description": "페이지 높이에 대한 비율로 나타낸 필드의 높이입니다."
          }
        }
      },
      "SignatureFieldResult": {
        "type": "object",
        "description": "서명된 문서의 필드이며, 이 서명자 사본에서의 값을 포함합니다. [필드](/ko/core-technology/electronic-signature/report-electronic-signature#필드)를 참조하십시오.",
        "properties": {
          "key": {
            "type": "string",
            "description": "`sign.field_values`에서 사용되는 필드의 키입니다."
          },
          "type": {
            "type": "string",
            "enum": [
              "signature",
              "initials",
              "full_name",
              "date_signed",
              "text",
              "checkbox",
              "email",
              "data"
            ]
          },
          "role": {
            "type": "string",
            "enum": [
              "verified_person",
              "legal_representative",
              "key_people"
            ]
          },
          "label": {
            "type": "string"
          },
          "page": {
            "type": "integer",
            "description": "1부터 시작하는 페이지 번호입니다. Word 문서의 경우 변환된 PDF의 페이지입니다."
          },
          "x": {
            "type": "number",
            "description": "페이지 너비의 비율로 표시된 왼쪽 가장자리입니다."
          },
          "y": {
            "type": "number",
            "description": "페이지 높이 비율 기준 상단 가장자리입니다."
          },
          "width": {
            "type": "number",
            "description": "페이지 너비에 대한 비율로 나타낸 너비입니다."
          },
          "height": {
            "type": "number",
            "description": "페이지 높이에 대한 비율로 나타낸 높이입니다."
          },
          "required": {
            "type": "boolean"
          },
          "value": {
            "nullable": true,
            "description": "`text`, `email`, `full_name`, `date_signed`, `data`의 경우 문자열, `checkbox`의 경우 불리언, 서명 또는 이니셜이 적용된 경우 `true`입니다. 비어 있으면 `null`입니다."
          },
          "display_value": {
            "type": "string",
            "nullable": true,
            "description": "페이지에 날인된 값입니다. 날짜는 해당 필드의 `date_format` 형식, 체크박스는 `Yes` 또는 `No`, 서명 또는 이니셜은 `Signed`로 표시됩니다."
          },
          "value_source": {
            "type": "string",
            "nullable": true,
            "enum": [
              "signer",
              "identity",
              "contact",
              "company",
              "session",
              "metadata",
              "api",
              "signing_time",
              null
            ],
            "description": "값의 출처: `signer`(서명자가 입력, 체크 또는 적용), `identity`(인증된 신분증), `contact`(인증된 이메일 또는 전화번호), `company`(인증된 기업), `session`(`vendor_data`), `metadata`, `api`(`sign.field_values`) 또는 `signing_time`(서명된 날짜)."
          },
          "filled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "image_url": {
            "type": "string",
            "nullable": true,
            "description": "서명 및 이니셜 전용: 적용된 이미지의 경로입니다. [서명 이미지 다운로드](/ko/sessions-api/electronic-signature/download-field-image)를 참조하세요."
          },
          "value_unavailable_reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "source_empty",
              null
            ],
            "description": "사전 입력된 필드가 세션에 값이 없었지만 `signature_field_data_missing_action`을 통해 서명자가 그대로 서명하도록 허용한 경우 `source_empty`입니다."
          }
        }
      },
      "VaspDirectoryWidgetEntry": {
        "type": "object",
        "description": "최종 사용자의 VASP 선택기에 표시되는 내용입니다(VASP가 누구인지와 연결 가능한지 여부).",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "GET /v3/travel-rule/vasps/{vasp_id}/ 호출을 위한 항목의 id입니다."
          },
          "kind": {
            "type": "string",
            "enum": [
              "directory",
              "didit"
            ],
            "description": "공유 디렉터리의 항목인 경우 directory, Didit 네트워크 멤버인 경우 didit입니다."
          },
          "name": {
            "type": "string"
          },
          "lei": {
            "type": "string"
          },
          "jurisdiction": {
            "type": "string",
            "description": "소스에서 제공한 ISO 3166 국가 코드입니다."
          },
          "domains": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "VASP의 웹 도메인입니다. Didit 네트워크 멤버의 경우 항상 비어 있습니다."
          },
          "reachable": {
            "type": "boolean",
            "description": "애플리케이션에 이 VASP 또는 해당 브랜드의 엔터티 중 하나로 연결 가능한 경로가 있는지 여부입니다. Didit 네트워크 멤버의 경우 항상 true입니다."
          }
        }
      },
      "TravelRuleDataSharingFields": {
        "type": "object",
        "description": "엔터티 유형별로 Didit이 귀하의 사용자에 대해 거래 상대방 VASP로 전송하는 필드입니다. 목록의 내용과 관계없이 `name` 및 `wallet_address`는 항상 전송됩니다. 선택하지 않은 엔터티 유형은 모든 필드를 공유합니다. 빈 목록도 하나의 선택 항목이며, 이 경우 이름과 지갑만 공유합니다.",
        "properties": {
          "individual": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "name",
                "wallet_address",
                "address",
                "national_id",
                "customer_identification",
                "date_of_birth",
                "place_of_birth"
              ]
            },
            "description": "자연인에 대해 공유된 필드입니다."
          },
          "company": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "name",
                "wallet_address",
                "address",
                "national_id",
                "customer_identification"
              ]
            },
            "description": "법인에 대해 공유된 필드입니다."
          }
        }
      },
      "TravelRuleMatchingRules": {
        "type": "object",
        "description": "엔티티 유형별로 거래 상대방의 각 데이터 필드를 보유 중인 데이터와 얼마나 엄격하게 비교할지 여부입니다. 생략된 필드는 기본값을 유지합니다. `NONE`은 비교를 건너뛰고, `STRICT`는 정확히 일치하는 단어를 요구하며, `CONTAINS`는 한 값의 단어가 다른 값에 모두 포함된 경우를 허용하고, `DEFAULT`는 표준 하위 집합 일치이며, `FUZZY`는 유사한 철자(생년월일의 경우 일과 월이 바뀐 경우 포함)를 허용합니다.",
        "properties": {
          "individual": {
            "type": "object",
            "description": "자연인에 대한 규칙입니다.",
            "properties": {
              "name": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "기본값: `name_matching_strictness`를 따릅니다."
              },
              "date_of_birth": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "기본값은 `NONE`입니다."
              },
              "address": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "기본값은 `NONE`입니다."
              },
              "account": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "거래가 라우팅된 지갑입니다. 기본값은 `STRICT`입니다."
              }
            }
          },
          "company": {
            "type": "object",
            "description": "법인에 대한 규칙.",
            "properties": {
              "name": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "기본값: `name_matching_strictness`를 따릅니다."
              },
              "address": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "기본값은 `NONE`입니다."
              },
              "account": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "거래가 라우팅된 지갑입니다. 기본값은 `STRICT`입니다."
              }
            }
          }
        }
      },
      "TravelRuleDataMatch": {
        "type": "object",
        "nullable": true,
        "description": "전송 당사자 데이터와 상대방이 파악하고 있는 지갑 소유자 정보 간의 필드별 비교입니다. 값은 포함하지 않고 필드와 결과만 지정하므로 거래 상대방의 데이터가 마스킹된 상태에서도 가독성이 유지됩니다. 비교가 실행되기 전까지는 null입니다.",
        "properties": {
          "matched": {
            "type": "boolean",
            "description": "비교된 필드가 모두 동일한 경우 true입니다."
          },
          "mismatched_fields": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "name",
                "date_of_birth",
                "address",
                "account"
              ]
            },
            "description": "서로 다른 필드입니다."
          },
          "fields": {
            "type": "object",
            "description": "당사자의 엔티티 유형에 따라 비교된 필드당 항목 1개(`name`, `date_of_birth`, `address`, `account`, 기업의 경우 `date_of_birth`가 없음)입니다.",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "result": {
                  "type": "string",
                  "enum": [
                    "matched",
                    "mismatched",
                    "not_compared"
                  ],
                  "description": "규칙이 `NONE`이거나 양쪽 중 어느 한쪽이라도 해당 필드에 대한 값이 없는 경우 `not_compared`입니다."
                },
                "strictness": {
                  "type": "string",
                  "enum": [
                    "NONE",
                    "STRICT",
                    "CONTAINS",
                    "DEFAULT",
                    "FUZZY"
                  ]
                }
              }
            }
          }
        }
      },
      "TravelRuleDataUnmasked": {
        "type": "object",
        "nullable": true,
        "description": "거래 상대방의 데이터가 마스킹 해제된 시점의 감사 기록입니다. 데이터가 여전히 마스킹되어 있는 동안 및 외부 송금의 경우 null입니다.",
        "properties": {
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "reason": {
            "type": "string",
            "enum": [
              "ownership_confirmed",
              "wallet_proof",
              "address_book_match",
              "own_verified_wallet",
              "inquiry_approved",
              "known_payment_method",
              "travel_address"
            ],
            "description": "소유권을 확인한 근거: ownership_confirmed(콘솔 또는 API를 통한 확인), wallet_proof(위젯의 지갑 증명 또는 생성 시 설정된 INTERNAL 인바운드 전송), address_book_match(인증된 주소록 지갑), own_verified_wallet(사용자의 인증된 자체 지갑), inquiry_approved(인바운드 TRP 조회 또는 GTR이나 Sygna 메시지에 대한 승인), known_payment_method(사용자가 이미 결제에 사용한 지갑) 또는 travel_address(지갑을 지정한 지갑별 Travel Address)입니다."
          },
          "actor": {
            "type": "string",
            "description": "확인한 주체: 콘솔 사용자의 이메일 또는 API 키의 라벨입니다. 자동 결정의 경우 비어 있습니다."
          }
        }
      },
      "TravelRuleMessageAttachment": {
        "type": "object",
        "nullable": true,
        "description": "메시지에 첨부된 문서이며, 다른 거래 문서와 동일하게 저장됩니다.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "note": {
            "type": "string",
            "nullable": true
          },
          "uploaded_by": {
            "type": "string",
            "nullable": true,
            "description": "첨부한 주체입니다. 픽업 포털에서 귀하가 보낸 파일에는 VASP 이름이 표시되며, 그 파일을 전송한 사람이나 API 키는 절대 표시되지 않습니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "files": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "file_url": {
                  "type": "string",
                  "nullable": true,
                  "description": "시간 제한 다운로드 URL입니다."
                },
                "original_filename": {
                  "type": "string"
                },
                "file_size": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "TravelRuleMessage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "enum": [
              "MESSAGE",
              "DOCUMENT_REQUEST"
            ]
          },
          "direction": {
            "type": "string",
            "enum": [
              "INBOUND",
              "OUTBOUND"
            ],
            "description": "`OUTBOUND`는 조회자의 측에서 전송한 내역입니다. 픽업 포털에서 방향은 거래 상대방 측 기준입니다."
          },
          "author": {
            "type": "string",
            "description": "자체 측에서 누가 작성했는지 나타냅니다. 콘솔 사용자의 이메일, API 키 레이블, 또는 상대방 VASP의 이름입니다."
          },
          "body": {
            "type": "string"
          },
          "requested_documents": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "요청자의 표현으로 DOCUMENT_REQUEST가 요청하는 내용입니다."
          },
          "reply_to": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "fulfilled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "답장에 문서가 포함되면 DOCUMENT_REQUEST에 설정됩니다."
          },
          "attachment": {
            "$ref": "#/components/schemas/TravelRuleMessageAttachment"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TravelRuleMessageCreateRequest": {
        "type": "object",
        "description": "JSON으로 전송하거나 첨부 파일이 `files`에 포함된 multipart/form-data로 전송하십시오.",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "MESSAGE",
              "DOCUMENT_REQUEST"
            ],
            "default": "MESSAGE"
          },
          "body": {
            "type": "string",
            "maxLength": 5000,
            "description": "파일이 첨부되지 않은 경우 MESSAGE에 필수입니다."
          },
          "requested_documents": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 255
            },
            "maxItems": 10,
            "description": "DOCUMENT_REQUEST에 필수(최소 1개)이며, 해당 경우에만 허용됩니다."
          },
          "reply_to": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "동일한 이체의 메시지입니다. 문서가 포함된 회신은 응답 대상 문서 요청을 충족합니다."
          },
          "files": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "binary"
            },
            "maxItems": 5,
            "description": "Multipart 전용입니다. 각 10MB 이하의 파일 최대 5개까지 가능합니다."
          }
        }
      },
      "SessionDeletionJob": {
        "type": "object",
        "description": "백그라운드에서 실행 중인 대량 세션 삭제: 진행 상황과 결과별 건수이며, 삭제된 세션 목록은 포함되지 않습니다.",
        "properties": {
          "job_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 id로 `GET /v3/sessions/delete/{job_id}/`를 폴링하십시오."
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "PROCESSING",
              "COMPLETED",
              "FAILED"
            ],
            "description": "`PENDING`: 접수되었으며 아직 시작되지 않음. `PROCESSING`: 삭제 중이며 `processed` 및 `outcomes`가 업데이트되는 중임. `COMPLETED`: 선택한 모든 세션이 처리됨. `FAILED`: 작업이 조기 중단됨. `error`를 참조하십시오."
          },
          "total": {
            "type": "integer",
            "description": "삭제 요청 시 선택된 세션입니다."
          },
          "processed": {
            "type": "integer",
            "description": "작업이 지금까지 처리를 완료한 세션입니다."
          },
          "outcomes": {
            "type": "object",
            "description": "각 결과로 종료된 세션 수입니다. 모든 키는 항상 존재합니다.",
            "properties": {
              "deleted": {
                "type": "integer",
                "description": "얼굴 임베딩과 함께 삭제된 세션입니다."
              },
              "none": {
                "type": "integer",
                "description": "얼굴 임베딩이 없어 삭제된 세션입니다."
              },
              "retained_with_user": {
                "type": "integer",
                "description": "요청 또는 애플리케이션 정책에 따라 사용자를 위한 이미지 없는 생체 인식 템플릿 1개가 보존되는 동안 삭제된 세션입니다."
              },
              "ineligible_no_vendor_user": {
                "type": "integer",
                "description": "보존이 요청되었으나 연결된 사용자가 없어 얼굴 임베딩과 함께 삭제된 세션입니다."
              },
              "failed_retryable": {
                "type": "integer",
                "description": "삭제되지 않은 것으로 보고된 세션입니다. 작업은 자체적으로 삭제하지 못한 그룹을 여기에 집계하는 대신 재시도합니다."
              },
              "already_deleted": {
                "type": "integer",
                "description": "작업이 도달했을 때 다른 요청 등에 의해 이미 삭제된 선택된 세션입니다."
              }
            }
          },
          "deleted_child_verifications": {
            "type": "integer",
            "description": "삭제된 기업 인증에서 생성되어 함께 삭제된 인증 건수입니다. KYC 세션만 삭제하는 `POST /v3/sessions/delete/`로 시작된 작업의 경우 항상 `0`입니다."
          },
          "error": {
            "type": "string",
            "nullable": true,
            "description": "`status`가 `FAILED`가 아닌 한 `null`이며, 이때 삭제가 중단된 이유가 표시됩니다. 작업이 도달하지 않은 세션은 그대로 유지되므로 요청을 다시 실행하여 삭제하십시오."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "삭제가 요청된 시점입니다."
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "작업이 완료된 시점입니다. 실행 중일 때는 `null`입니다."
          }
        }
      },
      "EntityStatusUpdateRequest": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "FLAGGED",
              "BLOCKED"
            ],
            "description": "새 라이프사이클 상태입니다. `BLOCKED`는 `vendor_data`를 시스템 차단 목록에도 추가합니다."
          }
        }
      },
      "AMLMonitoringToggleResult": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "users_total",
              "already_enabled",
              "with_existing_aml",
              "needing_screening",
              "skipped_no_identity_data",
              "skipped_blocked",
              "estimated_screening_cost_usd",
              "estimated_annual_monitoring_cost_usd",
              "balance_sufficient",
              "unmatched"
            ],
            "description": "예상 비용입니다. estimate_only가 true인 경우 직접 반환됩니다(아무것도 기록되지 않음).",
            "properties": {
              "users_total": {
                "type": "integer",
                "description": "선택 조건과 일치하는 프로필 수입니다."
              },
              "already_enabled": {
                "type": "integer",
                "description": "이미 모니터링 중인 프로필(활성화 시 수행할 작업 없음. 비활성화 시 해제되는 대상임)."
              },
              "with_existing_aml": {
                "type": "integer",
                "description": "기존 AML 스크리닝이 모니터링 상태로 전환될 프로필 수(신규 스크리닝 없음)."
              },
              "needing_screening": {
                "type": "integer",
                "description": "AML 스크리닝 이력이 없어 먼저 스크리닝을 진행할 프로필 수(일반 AML 스크리닝으로 청구됨)."
              },
              "skipped_no_identity_data": {
                "type": "integer",
                "description": "신원 데이터가 누락되어 스크리닝할 수 없는 프로필 수입니다."
              },
              "skipped_blocked": {
                "type": "integer",
                "description": "건너뛸 차단된 사용자 수입니다(기업의 경우 항상 0)."
              },
              "estimated_screening_cost_usd": {
                "type": "number",
                "example": 0.2,
                "description": "새 스크리닝의 일회성 비용입니다."
              },
              "estimated_annual_monitoring_cost_usd": {
                "type": "number",
                "example": 0.07,
                "description": "모니터링 대상이 될 프로필의 연간 모니터링 비용입니다."
              },
              "balance_sufficient": {
                "type": "boolean",
                "description": "조직 잔액이 스크리닝과 첫해 모니터링 비용을 충당할 수 있는지 여부입니다."
              },
              "unmatched": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "이 애플리케이션의 어떤 프로필과도 일치하지 않는 요청의 식별자로, 전송된 형태 그대로입니다."
              }
            }
          },
          {
            "type": "object",
            "required": [
              "job_id",
              "status",
              "is_enabled",
              "target_type",
              "total",
              "processed",
              "outcomes",
              "results",
              "error",
              "created_at",
              "completed_at",
              "estimate",
              "unmatched"
            ],
            "properties": {
              "job_id": {
                "type": "string",
                "format": "uuid"
              },
              "status": {
                "type": "string",
                "enum": [
                  "PENDING",
                  "PROCESSING",
                  "COMPLETED",
                  "FAILED"
                ]
              },
              "is_enabled": {
                "type": "boolean",
                "description": "작업이 모니터링을 활성화하면 true, 비활성화하면 false입니다."
              },
              "target_type": {
                "type": "string",
                "enum": [
                  "user",
                  "business"
                ],
                "description": "작업이 전환하는 프로필 패밀리입니다."
              },
              "total": {
                "type": "integer",
                "description": "작업이 처리하는 프로필 수입니다."
              },
              "processed": {
                "type": "integer",
                "description": "지금까지 처리된 프로필 수입니다."
              },
              "outcomes": {
                "type": "object",
                "description": "레코드별 결과 카운터입니다. 선택된 모든 프로필은 정확히 하나의 카운터에 해당하며, 암묵적으로 건너뛰는 프로필은 없습니다.",
                "properties": {
                  "enabled": {
                    "type": "integer",
                    "description": "기존 AML 스크리닝에서 모니터링이 활성화되었습니다."
                  },
                  "screened_and_enabled": {
                    "type": "integer",
                    "description": "새로운 AML 스크리닝이 생성되었으며(청구됨) 모니터링이 활성화되었습니다."
                  },
                  "already_enabled": {
                    "type": "integer",
                    "description": "모니터링이 이미 활성화되어 있었으며, 변경된 사항이 없고 청구되지 않았습니다."
                  },
                  "disabled": {
                    "type": "integer",
                    "description": "프로필의 모든 AML 스크리닝에서 모니터링이 꺼졌습니다."
                  },
                  "skipped_no_identity_data": {
                    "type": "integer",
                    "description": "건너뜀: 프로필에 스크리닝에 필요한 성명, 생년월일, 국가(사용자) 또는 이름(기업)이 없습니다."
                  },
                  "skipped_blocked": {
                    "type": "integer",
                    "description": "건너뜀: 사용자가 차단되었습니다."
                  },
                  "skipped_sandbox": {
                    "type": "integer",
                    "description": "건너뜀: 샌드박스 애플리케이션으로 스크리닝이 생성되지 않습니다."
                  },
                  "failed_provider": {
                    "type": "integer",
                    "description": "스크리닝을 완료할 수 없습니다. 나중에 다시 시도하세요."
                  },
                  "failed_insufficient_balance": {
                    "type": "integer",
                    "description": "작업이 실행되는 동안 잔액이 소진되었습니다."
                  }
                }
              },
              "results": {
                "type": "array",
                "description": "처리 순서에 따른 처리된 프로필당 항목 1개입니다. 작업이 실행되는 동안 증가하며 상태가 COMPLETED가 되면 완료됩니다. API를 통해 시작된 작업에 대해 기록됩니다.",
                "items": {
                  "type": "object",
                  "properties": {
                    "didit_internal_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "프로필의 Didit 내부 ID입니다."
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "프로필에 대한 귀하 고유의 식별자입니다."
                    },
                    "outcome": {
                      "type": "string",
                      "enum": [
                        "enabled",
                        "screened_and_enabled",
                        "already_enabled",
                        "disabled",
                        "skipped_no_identity_data",
                        "skipped_blocked",
                        "skipped_sandbox",
                        "failed_provider",
                        "failed_insufficient_balance"
                      ]
                    }
                  }
                }
              },
              "error": {
                "type": "string",
                "nullable": true,
                "description": "상태가 FAILED일 때의 일반 실패 메시지입니다. 자세한 원인은 플랫폼 측에 보관됩니다."
              },
              "created_at": {
                "type": "string",
                "format": "date-time"
              },
              "completed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "estimate": {
                "type": "object",
                "description": "예상 비용입니다. estimate_only가 true인 경우 직접 반환됩니다(아무것도 기록되지 않음).",
                "properties": {
                  "users_total": {
                    "type": "integer",
                    "description": "선택 조건과 일치하는 프로필 수입니다."
                  },
                  "already_enabled": {
                    "type": "integer",
                    "description": "이미 모니터링 중인 프로필(활성화 시 수행할 작업 없음. 비활성화 시 해제되는 대상임)."
                  },
                  "with_existing_aml": {
                    "type": "integer",
                    "description": "기존 AML 스크리닝이 모니터링 상태로 전환될 프로필 수(신규 스크리닝 없음)."
                  },
                  "needing_screening": {
                    "type": "integer",
                    "description": "AML 스크리닝 이력이 없어 먼저 스크리닝을 진행할 프로필 수(일반 AML 스크리닝으로 청구됨)."
                  },
                  "skipped_no_identity_data": {
                    "type": "integer",
                    "description": "신원 데이터가 누락되어 스크리닝할 수 없는 프로필 수입니다."
                  },
                  "skipped_blocked": {
                    "type": "integer",
                    "description": "건너뛸 차단된 사용자 수입니다(기업의 경우 항상 0)."
                  },
                  "estimated_screening_cost_usd": {
                    "type": "number",
                    "example": 0.2,
                    "description": "새 스크리닝의 일회성 비용입니다."
                  },
                  "estimated_annual_monitoring_cost_usd": {
                    "type": "number",
                    "example": 0.07,
                    "description": "모니터링 대상이 될 프로필의 연간 모니터링 비용입니다."
                  },
                  "balance_sufficient": {
                    "type": "boolean",
                    "description": "조직 잔액이 스크리닝과 첫해 모니터링 비용을 충당할 수 있는지 여부입니다."
                  }
                }
              },
              "unmatched": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "이 애플리케이션의 어떤 프로필과도 일치하지 않는 요청의 식별자로, 전송된 형태 그대로입니다. 작업의 일부가 아닙니다."
              }
            }
          }
        ]
      },
      "AMLMonitoringJob": {
        "type": "object",
        "properties": {
          "job_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "PROCESSING",
              "COMPLETED",
              "FAILED"
            ]
          },
          "is_enabled": {
            "type": "boolean",
            "description": "작업이 모니터링을 활성화하면 true, 비활성화하면 false입니다."
          },
          "target_type": {
            "type": "string",
            "enum": [
              "user",
              "business"
            ],
            "description": "작업이 전환하는 프로필 패밀리입니다."
          },
          "total": {
            "type": "integer",
            "description": "작업이 처리하는 프로필 수입니다."
          },
          "processed": {
            "type": "integer",
            "description": "지금까지 처리된 프로필 수입니다."
          },
          "outcomes": {
            "type": "object",
            "description": "레코드별 결과 카운터입니다. 선택된 모든 프로필은 정확히 하나의 카운터에 해당하며, 암묵적으로 건너뛰는 프로필은 없습니다.",
            "properties": {
              "enabled": {
                "type": "integer",
                "description": "기존 AML 스크리닝에서 모니터링이 활성화되었습니다."
              },
              "screened_and_enabled": {
                "type": "integer",
                "description": "새로운 AML 스크리닝이 생성되었으며(청구됨) 모니터링이 활성화되었습니다."
              },
              "already_enabled": {
                "type": "integer",
                "description": "모니터링이 이미 활성화되어 있었으며, 변경된 사항이 없고 청구되지 않았습니다."
              },
              "disabled": {
                "type": "integer",
                "description": "프로필의 모든 AML 스크리닝에서 모니터링이 꺼졌습니다."
              },
              "skipped_no_identity_data": {
                "type": "integer",
                "description": "건너뜀: 프로필에 스크리닝에 필요한 성명, 생년월일, 국가(사용자) 또는 이름(기업)이 없습니다."
              },
              "skipped_blocked": {
                "type": "integer",
                "description": "건너뜀: 사용자가 차단되었습니다."
              },
              "skipped_sandbox": {
                "type": "integer",
                "description": "건너뜀: 샌드박스 애플리케이션으로 스크리닝이 생성되지 않습니다."
              },
              "failed_provider": {
                "type": "integer",
                "description": "스크리닝을 완료할 수 없습니다. 나중에 다시 시도하세요."
              },
              "failed_insufficient_balance": {
                "type": "integer",
                "description": "작업이 실행되는 동안 잔액이 소진되었습니다."
              }
            }
          },
          "results": {
            "type": "array",
            "description": "처리 순서에 따른 처리된 프로필당 항목 1개입니다. 작업이 실행되는 동안 증가하며 상태가 COMPLETED가 되면 완료됩니다. API를 통해 시작된 작업에 대해 기록됩니다.",
            "items": {
              "type": "object",
              "properties": {
                "didit_internal_id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "프로필의 Didit 내부 ID입니다."
                },
                "vendor_data": {
                  "type": "string",
                  "nullable": true,
                  "description": "프로필에 대한 귀하 고유의 식별자입니다."
                },
                "outcome": {
                  "type": "string",
                  "enum": [
                    "enabled",
                    "screened_and_enabled",
                    "already_enabled",
                    "disabled",
                    "skipped_no_identity_data",
                    "skipped_blocked",
                    "skipped_sandbox",
                    "failed_provider",
                    "failed_insufficient_balance"
                  ]
                }
              }
            }
          },
          "error": {
            "type": "string",
            "nullable": true,
            "description": "상태가 FAILED일 때의 일반 실패 메시지입니다. 자세한 원인은 플랫폼 측에 보관됩니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "estimate": {
            "type": "object",
            "description": "예상 비용입니다. estimate_only가 true인 경우 직접 반환됩니다(아무것도 기록되지 않음).",
            "properties": {
              "users_total": {
                "type": "integer",
                "description": "선택 조건과 일치하는 프로필 수입니다."
              },
              "already_enabled": {
                "type": "integer",
                "description": "이미 모니터링 중인 프로필(활성화 시 수행할 작업 없음. 비활성화 시 해제되는 대상임)."
              },
              "with_existing_aml": {
                "type": "integer",
                "description": "기존 AML 스크리닝이 모니터링 상태로 전환될 프로필 수(신규 스크리닝 없음)."
              },
              "needing_screening": {
                "type": "integer",
                "description": "AML 스크리닝 이력이 없어 먼저 스크리닝을 진행할 프로필 수(일반 AML 스크리닝으로 청구됨)."
              },
              "skipped_no_identity_data": {
                "type": "integer",
                "description": "신원 데이터가 누락되어 스크리닝할 수 없는 프로필 수입니다."
              },
              "skipped_blocked": {
                "type": "integer",
                "description": "건너뛸 차단된 사용자 수입니다(기업의 경우 항상 0)."
              },
              "estimated_screening_cost_usd": {
                "type": "number",
                "example": 0.2,
                "description": "새 스크리닝의 일회성 비용입니다."
              },
              "estimated_annual_monitoring_cost_usd": {
                "type": "number",
                "example": 0.07,
                "description": "모니터링 대상이 될 프로필의 연간 모니터링 비용입니다."
              },
              "balance_sufficient": {
                "type": "boolean",
                "description": "조직 잔액이 스크리닝과 첫해 모니터링 비용을 충당할 수 있는지 여부입니다."
              }
            }
          },
          "unmatched": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "이 애플리케이션의 어떤 프로필과도 일치하지 않는 요청의 식별자로, 전송된 형태 그대로입니다. 작업의 일부가 아닙니다."
          }
        }
      },
      "OngoingMonitoringToggleRequest": {
        "type": "object",
        "required": [
          "is_enabled"
        ],
        "properties": {
          "is_enabled": {
            "type": "boolean",
            "description": "모니터링을 활성화하려면 true, 비활성화하려면 false입니다."
          },
          "estimate_only": {
            "type": "boolean",
            "default": false,
            "description": "true인 경우, 예상 비용을 반환하며 쓰기 작업을 수행하지 않습니다."
          },
          "update_all": {
            "type": "boolean",
            "default": false,
            "description": "애플리케이션의 모든 엔티티에 적용됩니다(있는 경우 filter_* 파라미터로 범위가 지정됨)."
          },
          "filter_search": {
            "type": "string"
          },
          "filter_status": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "filter_country": {
            "type": "string"
          },
          "filter_date_from": {
            "type": "string",
            "format": "date"
          },
          "filter_date_to": {
            "type": "string",
            "format": "date"
          },
          "didit_internal_id_list": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "상태를 전환할 엔티티입니다. update_all이 true가 아닌 경우 필수입니다."
          }
        }
      },
      "OngoingMonitoringJob": {
        "type": "object",
        "properties": {
          "job_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "PROCESSING",
              "COMPLETED",
              "FAILED"
            ]
          },
          "is_enabled": {
            "type": "boolean"
          },
          "total": {
            "type": "integer"
          },
          "processed": {
            "type": "integer"
          },
          "outcomes": {
            "type": "object",
            "description": "엔터티별 결과 카운터입니다. 어떤 항목도 누락 없이 처리되며, 요청된 모든 엔터티는 정확히 하나의 카운터로 매핑됩니다.",
            "properties": {
              "enabled": {
                "type": "integer",
                "description": "기존 AML 스크리닝에서 모니터링이 활성화되었습니다."
              },
              "screened_and_enabled": {
                "type": "integer",
                "description": "새로운 AML 스크리닝이 생성되었으며(청구됨) 모니터링이 활성화되었습니다."
              },
              "already_enabled": {
                "type": "integer",
                "description": "모니터링이 이미 활성화되어 있었습니다(기존 중복 행은 통합됨)."
              },
              "disabled": {
                "type": "integer",
                "description": "엔티티의 모든 AML 행에서 모니터링이 비활성화되었습니다."
              },
              "skipped_no_identity_data": {
                "type": "integer",
                "description": "건너뜀: 스크리닝할 성명 + 생년월일 + 국가 정보가 없습니다."
              },
              "skipped_blocked": {
                "type": "integer",
                "description": "건너뜀: 사용자가 차단되었습니다."
              },
              "skipped_sandbox": {
                "type": "integer",
                "description": "건너뜀: 샌드박스 애플리케이션입니다."
              },
              "failed_provider": {
                "type": "integer",
                "description": "스크리닝 제공업체 호출에 실패했습니다."
              },
              "failed_insufficient_balance": {
                "type": "integer",
                "description": "작업 도중 잔액이 소진되었습니다."
              }
            }
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "estimate": {
            "type": "object",
            "description": "예상 비용입니다. estimate_only가 true인 경우 직접 반환됩니다(쓰기 작업이 수행되지 않음).",
            "properties": {
              "users_total": {
                "type": "integer",
                "description": "선택 항목 내 엔티티입니다."
              },
              "already_enabled": {
                "type": "integer"
              },
              "with_existing_aml": {
                "type": "integer",
                "description": "기존 AML 스크리닝이 모니터링 대상으로 전환될 엔티티입니다."
              },
              "needing_screening": {
                "type": "integer",
                "description": "AML 스크리닝을 거치지 않아 먼저 스크리닝될 엔티티(결제 대상)."
              },
              "skipped_no_identity_data": {
                "type": "integer"
              },
              "skipped_blocked": {
                "type": "integer"
              },
              "estimated_screening_cost_usd": {
                "type": "number",
                "example": 0.2
              },
              "estimated_annual_monitoring_cost_usd": {
                "type": "number",
                "example": 0.07
              },
              "balance_sufficient": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "OngoingMonitoringToggleResult": {
        "oneOf": [
          {
            "type": "object",
            "description": "예상 비용입니다. estimate_only가 true인 경우 직접 반환됩니다(쓰기 작업이 수행되지 않음).",
            "properties": {
              "users_total": {
                "type": "integer",
                "description": "선택 항목 내 엔티티입니다."
              },
              "already_enabled": {
                "type": "integer"
              },
              "with_existing_aml": {
                "type": "integer",
                "description": "기존 AML 스크리닝이 모니터링 대상으로 전환될 엔티티입니다."
              },
              "needing_screening": {
                "type": "integer",
                "description": "AML 스크리닝을 거치지 않아 먼저 스크리닝될 엔티티(결제 대상)."
              },
              "skipped_no_identity_data": {
                "type": "integer"
              },
              "skipped_blocked": {
                "type": "integer"
              },
              "estimated_screening_cost_usd": {
                "type": "number",
                "example": 0.2
              },
              "estimated_annual_monitoring_cost_usd": {
                "type": "number",
                "example": 0.07
              },
              "balance_sufficient": {
                "type": "boolean"
              }
            }
          },
          {
            "$ref": "#/components/schemas/OngoingMonitoringJob"
          }
        ]
      },
      "CaseBlueprintPresetInstallResult": {
        "type": "object",
        "properties": {
          "created": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CaseBulkUpdateResult": {
        "type": "object",
        "properties": {
          "updated": {
            "type": "integer"
          },
          "failures": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "case_uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "detail": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "RegulatoryReportList": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "description": "일치하는 행 수이며, 성능을 위해 최대 100개로 제한됩니다."
          },
          "next": {
            "type": "string",
            "nullable": true
          },
          "previous": {
            "type": "string",
            "nullable": true
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RegulatoryReportDetail"
            }
          }
        }
      },
      "EntityNetworkMembershipList": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EntityNetworkMembership"
            }
          }
        }
      },
      "SessionDecision": {
        "type": "object",
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "세션의 고유 식별자입니다."
          },
          "session_kind": {
            "type": "string",
            "enum": [
              "user",
              "business"
            ],
            "description": "해당 세션이 사용자 인증(KYC)인지 기업 확인(KYB) 세션인지 나타내는 구분자입니다. `user`인 경우 KYC 기능 배열(`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `document_ai_documents`, `database_validations`, ...)이 적용되고 기업 배열은 제외됩니다. `business`인 경우 payload에는 대신 `registry_checks`, `document_verifications`, `key_people_checks`와 공유 배열(`aml_screenings`, `phone_verifications`, `email_verifications`, `ip_analyses`, `questionnaire_responses`)이 포함됩니다. **`include=events`가 전달된 경우 생략됩니다** — 이벤트 형태는 사용자 세션에만 존재하므로 해당 변형에서는 구분자가 제외됩니다."
          },
          "shared_from_session": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "`POST /v3/session/import-shared/`로 복제된 세션의 경우: 소스 애플리케이션의 원본 세션 `session_id`입니다. 다른 모든 세션의 경우 `null`입니다. `include=events`가 전달되면 생략됩니다."
          },
          "shared_from_session_number": {
            "type": "integer",
            "nullable": true,
            "description": "이 세션을 조직의 다른 애플리케이션에서 가져온 경우 소스 세션의 `session_number`입니다. 그렇지 않으면 `null`입니다."
          },
          "session_number": {
            "type": "integer",
            "description": "세션 번호입니다.",
            "nullable": true
          },
          "session_url": {
            "type": "string",
            "format": "uri",
            "description": "세션의 URL입니다.",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Started",
              "In Progress",
              "Awaiting User",
              "In Review",
              "Approved",
              "Declined",
              "Resubmitted",
              "Expired",
              "Kyc Expired",
              "Abandoned"
            ],
            "description": "세션의 전체 라이프사이클 상태 — 취합된 워크플로 결과입니다. 최종 값은 `Approved`, `Declined`, `In Review`, `Expired`, `Kyc Expired`, `Abandoned`이며, `Not Started`, `In Progress`, `Awaiting User`, `Resubmitted`는 세션이 아직 워크플로를 진행 중임을 나타냅니다."
          },
          "status_override": {
            "type": "object",
            "nullable": true,
            "description": "검토자가 `status`를 직접 설정했을 때 표시됩니다. 상태가 자동으로 지정된 경우 `null`입니다. 수동 승인과 자동 승인을 구분하는 데 사용합니다.",
            "properties": {
              "overridden_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "automatic_status": {
                "type": "string",
                "nullable": true,
                "description": "플랫폼 자체 검사 결과로 도출된 상태입니다."
              }
            }
          },
          "decision_trace": {
            "type": "object",
            "description": "상태에 도달한 방식: 설정한 주체 및 해당 상태를 유발한 경고입니다.",
            "properties": {
              "status": {
                "type": "string",
                "description": "세션 상태입니다."
              },
              "decided_by": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "manual",
                  "automatic",
                  "investigator",
                  null
                ],
                "description": "누가 상태를 설정했는지 나타냅니다. 세션이 결정되지 않은 동안에는 `null`입니다."
              },
              "decided_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "automatic_status": {
                "type": "string",
                "nullable": true,
                "description": "플랫폼 자체 검증이 내린 결론으로, 수동 결정 후의 `status`와는 다릅니다."
              },
              "terminal_node_id": {
                "type": "string",
                "nullable": true,
                "description": "세션을 종료한 워크플로 상태 노드(종료한 노드가 있는 경우)입니다."
              },
              "actor": {
                "type": "object",
                "nullable": true,
                "description": "수동 결정을 내린 검토자입니다.",
                "properties": {
                  "user": {
                    "type": "string",
                    "nullable": true
                  },
                  "actor_type": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "warning_counts": {
                "type": "object",
                "description": "`log_type`(`error`, `warning`, `information`)별 경고 및 `total`입니다.",
                "additionalProperties": {
                  "type": "integer"
                }
              },
              "status_warnings": {
                "type": "array",
                "description": "`Declined` 또는 `In Review` 상태를 설정한 경고 목록입니다.",
                "items": {
                  "type": "object",
                  "properties": {
                    "risk": {
                      "type": "string"
                    },
                    "feature": {
                      "type": "string",
                      "nullable": true
                    },
                    "node_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "log_type": {
                      "type": "string",
                      "nullable": true
                    },
                    "check_status": {
                      "type": "string",
                      "nullable": true
                    },
                    "source": {
                      "type": "string",
                      "description": "경고가 발생한 payload 목록입니다(예: `id_verifications`)."
                    },
                    "short_description": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "linked_records": {
            "type": "object",
            "nullable": true,
            "description": "세션에 연결된 다른 레코드의 요약입니다. 표시할 내용이 없거나 연령 확인 기준을 선언하는 워크플로의 경우 `null`입니다.",
            "properties": {
              "same_face": {
                "type": "object",
                "nullable": true,
                "description": "이 세션의 얼굴 검색 중 하나와 얼굴이 일치한 다른 사람들입니다.",
                "properties": {
                  "count": {
                    "type": "integer"
                  },
                  "best_match": {
                    "type": "object",
                    "nullable": true,
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true
                      },
                      "session_number": {
                        "type": "integer",
                        "nullable": true
                      },
                      "vendor_user_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true
                      },
                      "similarity_percentage": {
                        "type": "number",
                        "nullable": true
                      }
                    }
                  }
                }
              },
              "earlier_verifications": {
                "type": "object",
                "nullable": true,
                "properties": {
                  "count": {
                    "type": "integer"
                  },
                  "vendor_user_id": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true
                  }
                }
              },
              "networks": {
                "type": "object",
                "nullable": true,
                "properties": {
                  "count": {
                    "type": "integer"
                  },
                  "open": {
                    "type": "integer"
                  },
                  "dismissed": {
                    "type": "integer"
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "network_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "display_number": {
                          "type": "integer",
                          "nullable": true
                        },
                        "name": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "risk_score": {
                          "type": "number",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "workflow_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 세션을 생성한 워크플로 그룹의 안정적인 식별자입니다. 워크플로는 버전이 관리되며, 이 값은 특정 버전이 아닌 워크플로 자체를 식별합니다.",
            "nullable": true
          },
          "features": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "세션의 기능입니다."
            },
            "description": "이 세션에 구성된 인증 기능 목록이며, 표시 이름으로 제공됩니다: `ID_VERIFICATION`, `NFC`, `LIVENESS`, `FACE_MATCH`, `POA`, `PHONE`, `EMAIL_VERIFICATION`, `AML`, `IP_ANALYSIS`, `DATABASE_VALIDATION`, `QUESTIONNAIRE`, `AGE_ESTIMATION`, `FACE_SEARCH`, `GEOLOCATION`(위치 확인) (기업 확인(KYB) 세션은 KYB 기능 세트를 사용합니다: `KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`, `AML`, `PHONE`, `EMAIL_VERIFICATION`, `IP_ANALYSIS`, `QUESTIONNAIRE`). `include=events`를 사용하면 각 항목이 일반 문자열 대신 `{feature, node_id}` 객체가 되며, 이메일 기능의 이름이 변경됩니다. 여기에서 사용된 `EMAIL_VERIFICATION` 대신 이벤트 모드에서는 `EMAIL`로 표시됩니다."
          },
          "vendor_data": {
            "type": "string",
            "description": "세션의 벤더 데이터입니다.",
            "nullable": true
          },
          "metadata": {
            "type": "object",
            "description": "세션의 메타데이터입니다.",
            "nullable": true
          },
          "expected_details": {
            "type": "object",
            "description": "세션 생성 시 제공된 예상 세부정보 — 추출된 데이터와의 교차 검증(KYC)에 사용되거나 법인 등기부 검색 사전 입력(KYB)에 사용됩니다. 제공된 키를 그대로 다시 반환하며, 아무것도 제공되지 않은 경우 `null`입니다. KYC 세션에는 개인 필드가 포함되며, 기업 확인(KYB) 세션에는 `company_name`, `registry_country`, `registration_number`가 포함됩니다.",
            "properties": {
              "first_name": {
                "type": "string",
                "description": "사용자의 이름입니다. 예: `John`."
              },
              "last_name": {
                "type": "string",
                "description": "사용자의 성입니다. 예: `Doe`."
              },
              "date_of_birth": {
                "type": "string",
                "format": "date",
                "description": "사용자의 생년월일 형식: YYYY-MM-DD. 예: `1990-05-15`."
              },
              "gender": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "M",
                  "F"
                ],
                "default": null,
                "description": "사용자의 성별입니다. 'M', 'F' 또는 null이어야 합니다."
              },
              "nationality": {
                "type": "string",
                "description": "신청자의 출신 국가를 나타내는 ISO 3166-1 alpha-3 국가 코드입니다. 예: `USA`."
              },
              "country": {
                "type": "string",
                "description": "주소 증명 문서의 국가 또는 신청자의 신분증 문서의 국가를 나타내는 ISO 3166-1 alpha-3 국가 코드이며, 국적과 다를 수 있습니다. 예: `GBR`."
              },
              "address": {
                "type": "string",
                "description": "가능한 한 많은 정보를 포함한 사람이 읽을 수 있는 형식의 주소입니다. 예를 들어 `123 Main St, San Francisco, CA 94105, USA`입니다."
              },
              "identification_number": {
                "type": "string",
                "description": "사용자의 문서 번호, 개인 식별 번호 또는 납세자 번호입니다. 예를 들어 `123456789`입니다."
              },
              "ip_address": {
                "type": "string",
                "format": "ipv4",
                "description": "세션의 예상 IP 주소입니다. 실제 IP 주소가 이 값과 다르면 경고가 기록됩니다. 예: `192.168.1.100`."
              },
              "expected_document_types": {
                "type": "array",
                "description": "세션 생성 시 신분증 인증 단계가 제한되었던 문서 유형입니다. 비어 있거나 설정되지 않은 경우 제한이 없음을 의미합니다. 코드: `P`(여권), `ID`(주민등록증/신분증), `DL`(운전면허증), `RP`(거주 허가증), `HIC`(건강보험증), `TC`(세금 카드), `SSC`(사회보장 카드).",
                "items": {
                  "type": "string",
                  "enum": [
                    "P",
                    "ID",
                    "DL",
                    "RP",
                    "HIC",
                    "TC",
                    "SSC"
                  ]
                }
              },
              "id_country": {
                "type": "string",
                "nullable": true,
                "description": "생성 시 제한된 경우의 신분증 문서 발급 국가(ISO 3166-1 alpha-3) 예상 값입니다.",
                "example": "ESP"
              },
              "poa_country": {
                "type": "string",
                "nullable": true,
                "description": "생성 시 제한된 경우의 주소 증명 문서 국가(ISO 3166-1 alpha-3) 예상 값입니다.",
                "example": "ESP"
              },
              "company_name": {
                "type": "string",
                "description": "기업의 예상 법적 명칭입니다. 기업 확인(KYB) 세션 전용입니다."
              },
              "registry_country": {
                "type": "string",
                "description": "`XX` 또는 `XX-YY` 형식의 예상 등기 국가(ISO 3166-1 alpha-2, 주 단위 등기부의 경우 선택적으로 ISO 3166-2 하위 행정구역 포함, 예: `US-CA`)입니다. 기업 확인(KYB) 세션 전용입니다."
              },
              "registration_number": {
                "type": "string",
                "description": "예상 법인 등록번호입니다. 기업(KYB) 세션에만 해당합니다."
              }
            },
            "nullable": true
          },
          "contact_details": {
            "type": "object",
            "description": "세션 생성 시 제공된 연락처 세부 정보입니다(알림 이메일, 미리 채워진 전화번호/이메일 인증, 통신 언어에 사용됨). 이메일과 전화번호가 모두 제공되지 않은 경우 `null`입니다.",
            "properties": {
              "email": {
                "type": "string",
                "description": "이메일 인증 단계에서 사용될 사용자의 이메일 주소(예: \"john.doe@example.com\")입니다. 제공되지 않으면 사용자가 인증 플로우 중에 직접 입력해야 합니다."
              },
              "email_lang": {
                "type": "string",
                "description": "이메일 알림 언어 코드(ISO 639-1)입니다. 모든 이메일 커뮤니케이션의 언어를 제어합니다(예: \"en\", \"es\", \"fr\")."
              },
              "send_notification_emails": {
                "type": "boolean",
                "default": false,
                "description": "true이고 이메일이 제공된 경우, Didit은 사용자 인증(KYC) 또는 기업 확인(KYB) 세션이 생성될 때 초기 \"본인 확인\" 이메일을 비동기식으로 전송합니다. 또한 수동 검토가 필요한 세션의 경우 Didit은 제공된 이메일 주소로 인증 상태 알림을 전송합니다."
              },
              "phone": {
                "type": "string",
                "nullable": true,
                "description": "사용 가능한 경우 사용자의 E.164 형식 전화번호(예: +14155552671)입니다. 세션 생성 시 이메일만 제공된 경우 `null`입니다. 참고: 이 필드는 세션 생성 중에 제공된 원래 전화번호를 반환합니다. 번호가 유효하지 않았던 경우 E.164 형식이 아닐 수 있습니다."
              }
            },
            "nullable": true
          },
          "callback": {
            "type": "string",
            "format": "uri",
            "description": "세션의 콜백 URL입니다.",
            "nullable": true
          },
          "id_verifications": {
            "type": "array",
            "nullable": true,
            "description": "워크플로 그래프의 신분증 문서 단계에서 생성된 **신분증 인증(OCR) 보고서 배열**입니다. 항상 JSON 배열입니다. 워크플로에서 둘 이상의 신분증 확인(예: 기본 확인에 추가적인 스텝업 확인)을 실행할 수 있는 경우 `id_verifications[0]`을 읽고 반복 처리하십시오. 하나 이상의 신분증 단계에서 데이터가 생성될 때까지 `null`입니다. 각 항목은 `node_id`, 기능 수준 `status`, 추출된 문서 필드, 이미지 URL, 품질 점수, MRZ, 주소 파싱, 세션 간 일치 항목, `warnings[]`를 포함한 전체 보고서입니다.",
            "items": {
              "type": "object",
              "description": "단일 신분증 인증 보고서 - 단일 신분증 인증 단계에 대한 전체 보고서입니다. `verification_method`는 세 가지 방식(문서 캡처, 비문서 조회 또는 지갑 로그인) 중 어떤 방식으로 생성되었는지를 나타내며, 해당 방식에 맞는 증거 블록이 채워집니다.",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "이 보고서를 생성한 OCR 단계의 워크플로 그래프 노드 ID입니다."
                },
                "verification_method": {
                  "type": "string",
                  "enum": [
                    "document",
                    "id_lookup",
                    "wallet"
                  ],
                  "description": "이 보고서를 생성한 신분증 인증 방법입니다. `document` - 사용자가 실물 신분증을 촬영함(기본값이며 다른 방법이 존재하기 전에 생성된 모든 세션의 값임). `id_lookup` - 사용자가 주민등록번호 등의 국가 신분증 번호를 입력하고 해당 국가의 정부 등록부 또는 기타 공신력 있는 출처와 대조하여 확인함(`id_lookup.source`에 출처 명시). `wallet` - 사용자가 정부 또는 은행 디지털 신원 정보를 사용하여 로그인함."
                },
                "assurance": {
                  "type": "string",
                  "enum": [
                    "documentary",
                    "data_match",
                    "cryptographic"
                  ],
                  "description": "`verification_method`에서 파생된 보증 등급: 캡처 및 확인된 문서의 경우 `documentary`, 조회된 출처가 보유한 레코드와 세부 정보가 일치하는 경우 `data_match`, 신원 공급자가 인증하고 서명한 속성의 경우 `cryptographic`입니다."
                },
                "wallet_provider": {
                  "type": "string",
                  "nullable": true,
                  "description": "`verification_method`가 `wallet`인 경우의 카탈로그 지갑 id(`mitid`, `bankid_se`, `itsme` 등). 그렇지 않은 경우 `null`입니다."
                },
                "fallback_from": {
                  "type": "object",
                  "nullable": true,
                  "description": "비문서 방식이 신분증 단계를 종료하지 못한 이유입니다. 조회 또는 지갑 로그인이 실패했을 때 설정됩니다: 국가의 대체 전환 스위치가 `fallback_to_document`였을 때 사용자가 계속 진행한 문서 인증(`action`이 `fallback_to_document`) 또는 `decline`이었을 때 거부된 보고서에 표시됩니다. 그 외의 경우에는 `null`입니다.",
                  "properties": {
                    "method": {
                      "type": "string",
                      "enum": [
                        "id_lookup",
                        "wallet"
                      ],
                      "description": "실패한 메서드입니다."
                    },
                    "reason": {
                      "type": "string",
                      "description": "종료시킨 결과입니다(예: `no_match`, `provider_error`, `cancelled`, `timeout`)."
                    },
                    "action": {
                      "type": "string",
                      "enum": [
                        "fallback_to_document",
                        "decline"
                      ],
                      "description": "설정에 따라 수행된 작업: `fallback_to_document` 또는 `decline`."
                    }
                  }
                },
                "id_lookup": {
                  "type": "object",
                  "nullable": true,
                  "description": "법인 등기부 증빙 자료입니다. `verification_method`가 `id_lookup`인 경우에만 존재하며, 그렇지 않으면 `null`입니다.",
                  "properties": {
                    "source": {
                      "type": "string",
                      "description": "조회된 출처의 고객에게 표시되는 이름(예: 정부 등록부인 `Department of Home Affairs` 또는 정부 등록부가 아닌 `UK credit bureau and financial services records`)입니다. 이는 해당 조회에 대한 유일한 출처 명시이므로 무조건 정부 출처라고 가정하지 마세요."
                    },
                    "checked_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "등록기관이 응답한 시점입니다."
                    },
                    "attempts": {
                      "type": "integer",
                      "description": "이 보고서가 생성된 1부터 시작하는 시도 번호입니다."
                    },
                    "max_attempts": {
                      "type": "integer",
                      "description": "해당 국가에 대해 구성된 시도 횟수 예산입니다(1~5, 기본값 1)."
                    },
                    "outcome": {
                      "type": "string",
                      "enum": [
                        "match",
                        "partial_match",
                        "no_match",
                        "provider_error",
                        "format_rejected"
                      ],
                      "nullable": true,
                      "description": "등기부의 응답 내용입니다. `match`, `partial_match`, `no_match`만 시도 횟수 예산 및 청구 금액에 반영됩니다."
                    },
                    "comparison": {
                      "type": "array",
                      "description": "소스가 응답한 비교 가능한 필드당 한 행, 소스 오류당 한 행입니다. 여러 요청 필드(이름 및 성, 또는 식별자 별칭 중 하나)가 단일 비교로 축소되므로 비교 행에는 해당 국가의 요청 필드 키 대신 아래의 정규화된 필드 이름이 사용됩니다. 실패한 소스는 `field: \"provider\"` 및 `result: \"error\"`가 포함된 행을 추가하므로, 행을 필드 판정으로 처리하기 전에 `result`를 먼저 확인하십시오.",
                      "items": {
                        "type": "object",
                        "required": [
                          "field",
                          "label",
                          "provided",
                          "record",
                          "result"
                        ],
                        "properties": {
                          "field": {
                            "type": "string",
                            "enum": [
                              "identification_number",
                              "full_name",
                              "date_of_birth",
                              "address",
                              "provider"
                            ],
                            "description": "정규화된 비교 필드입니다. `provider`는 사용자 필드가 아니며, 소스 오류 행을 나타냅니다."
                          },
                          "label": {
                            "type": "string",
                            "description": "행의 표시 레이블입니다(예: `ID number`, `Full name`, `Provider`)."
                          },
                          "provided": {
                            "type": "string",
                            "nullable": true,
                            "description": "사용자가 입력한 내용입니다. `provider` 오류 행에서는 `null`입니다."
                          },
                          "record": {
                            "type": "string",
                            "nullable": true,
                            "description": "소스가 보유했던 데이터입니다. `provider` 오류 행에서는 대신 오류 메시지가 포함됩니다."
                          },
                          "result": {
                            "type": "string",
                            "enum": [
                              "match",
                              "partial",
                              "no_match",
                              "error"
                            ],
                            "description": "필드별 비교 결과입니다. `error`는 `provider` 행에만 나타나며 해당 소스가 응답하지 않았음을 의미합니다. 이는 쿼리에 관한 증거로 취급해야 하며, 필드 불일치로 처리해서는 안 됩니다."
                          }
                        }
                      }
                    },
                    "registry_portrait": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "소스에서 반환한 인물 사진에 대한 유효 기간이 짧은 사전 서명된 URL입니다. 인물 사진을 반환하는 4개의 정부 등록부(남아프리카 공화국, 나이지리아, 아르헨티나, 파나마)에만 해당합니다."
                    },
                    "face_match_score": {
                      "type": "number",
                      "nullable": true,
                      "description": "등기부 인물 사진과 셀피 간 대조 점수(0-100)입니다. 등기부에서 인물 사진을 반환하는 경우에만 해당합니다."
                    }
                  }
                },
                "wallet_verification": {
                  "type": "object",
                  "nullable": true,
                  "description": "자격 증명 증거입니다. `verification_method`가 `wallet`인 경우에만 존재하며, 그렇지 않은 경우 `null`입니다.",
                  "properties": {
                    "provider": {
                      "type": "string",
                      "description": "카탈로그 지갑 id(예: `mitid`)."
                    },
                    "provider_name": {
                      "type": "string",
                      "nullable": true,
                      "description": "최종 사용자에게 알려진 지갑 이름입니다(예: `MitID`)."
                    },
                    "issuing_authority": {
                      "type": "string",
                      "nullable": true,
                      "description": "지갑 배후의 기관입니다(예: `Danish Agency for Digital Government`)."
                    },
                    "issuing_country": {
                      "type": "string",
                      "description": "지갑이 제공된 ISO 3166-1 alpha-3 국가입니다."
                    },
                    "credential_type": {
                      "type": "string",
                      "nullable": true,
                      "description": "지갑이 제시한 자격 증명(예: `person_identification`)."
                    },
                    "level_of_assurance": {
                      "type": "string",
                      "enum": [
                        "low",
                        "substantial",
                        "high"
                      ],
                      "nullable": true,
                      "description": "지갑이 주장한 보증 수준입니다. 요청된 수준보다 낮은 수준을 주장하는 로그인은 다운그레이드되지 않고 실패합니다."
                    },
                    "verified_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "지갑의 인증 시각입니다."
                    },
                    "signature_valid": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "지갑이 반환한 서명된 어서션의 유효성이 검증되었는지 여부입니다."
                    },
                    "attributes": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "지갑이 공유한 속성이며, 지갑의 카탈로그 항목에 나열된 대로 키가 지정됩니다."
                    },
                    "portrait": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "지갑에서 인물 사진을 공유하는 경우, 해당 사진에 대한 유효 기간이 짧은 사전 서명된 URL입니다."
                    },
                    "face_match_score": {
                      "type": "number",
                      "nullable": true,
                      "description": "지갑 인물 사진과 셀피 간 대조 점수(0-100)로, 지갑에서 인물 사진을 공유하는 경우에 해당합니다."
                    }
                  }
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Expired"
                  ],
                  "description": "이 신분증 인증 단계의 기능 수준 상태입니다. 최상위 세션 `status`와는 독립적입니다. 개별 기능이 `In Review` 상태로 유지되는 동안에도 세션이 전체 결정에 도달할 수 있습니다."
                },
                "document_type": {
                  "type": "string",
                  "description": "신원 확인 문서 유형"
                },
                "document_subtype": {
                  "type": "string",
                  "nullable": true,
                  "description": "해당되는 경우 문서 지역을 포함하여 워크플로 문서 설정에서 수락된 문서 하위 유형 코드입니다. 예: `ID_CARD_GENERIC`, `QUEENSLAND_DRIVER_LICENSE_GENERIC`."
                },
                "document_number": {
                  "type": "string",
                  "description": "문서 식별 번호"
                },
                "personal_number": {
                  "type": "string",
                  "description": "개인 식별 번호"
                },
                "portrait_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "인물 사진 이미지의 URL"
                },
                "front_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "문서 앞면 이미지의 URL"
                },
                "front_video": {
                  "type": "string",
                  "format": "uri",
                  "description": "문서 앞면 동영상의 URL"
                },
                "back_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "문서 뒷면 이미지의 URL"
                },
                "back_video": {
                  "type": "string",
                  "format": "uri",
                  "description": "문서 뒷면 동영상의 URL"
                },
                "full_front_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "문서 앞면 전체 이미지의 URL"
                },
                "full_back_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "문서 뒷면 전체 이미지의 URL"
                },
                "front_image_camera_front": {
                  "type": "string",
                  "format": "uri",
                  "description": "전면 카메라로 촬영한 문서 앞면 이미지의 URL"
                },
                "back_image_camera_front": {
                  "type": "string",
                  "format": "uri",
                  "description": "전면 카메라로 촬영한 문서 뒷면 이미지의 URL"
                },
                "date_of_birth": {
                  "type": "string",
                  "format": "date",
                  "description": "문서에서 추출한 생년월일"
                },
                "age": {
                  "type": "integer",
                  "description": "생년월일로 계산된 연령"
                },
                "expiration_date": {
                  "type": "string",
                  "format": "date",
                  "description": "문서 만료일"
                },
                "date_of_issue": {
                  "type": "string",
                  "format": "date",
                  "description": "문서 발급일"
                },
                "issuing_state": {
                  "type": "string",
                  "description": "발급 주(State)의 ISO 코드"
                },
                "issuing_state_name": {
                  "type": "string",
                  "description": "발급 주의 전체 이름"
                },
                "first_name": {
                  "type": "string",
                  "description": "문서의 이름"
                },
                "last_name": {
                  "type": "string",
                  "description": "문서의 성"
                },
                "full_name": {
                  "type": "string",
                  "description": "문서에 기재된 성명"
                },
                "gender": {
                  "type": "string",
                  "description": "문서에 기재된 성별"
                },
                "address": {
                  "type": "string",
                  "description": "문서의 원시 주소"
                },
                "formatted_address": {
                  "type": "string",
                  "description": "포맷된 전체 주소입니다."
                },
                "place_of_birth": {
                  "type": "string",
                  "description": "문서상의 출생지"
                },
                "marital_status": {
                  "type": "string",
                  "description": "문서에 기재된 혼인 여부"
                },
                "nationality": {
                  "type": "string",
                  "description": "ISO 국적 코드"
                },
                "extra_fields": {
                  "type": "object",
                  "description": "추가 문서 필드입니다. 문서별 고유 속성(예: `dl_categories`, `blood_group`, `sponsor`, `employer`, `dl_class_code_b_from`, `dl_class_code_b_to`)을 포함합니다. 운전면허 등급 유효 기간은 `dl_class_code_<class>_from` 및 `dl_class_code_<class>_to`로 반환되며, 등급별 제한/정보 코드는 (예: 영국 면허증의 12번 열) `dl_class_code_<class>_notes`로 반환됩니다. 문서에 성명, 주소 또는 출생지가 여러 문자 체계로 기재되어 있는 경우, 이 객체에는 해당 필드의 대체 문자 체계 버전도 포함됩니다. 워크플로 설정인 `preferred_characters`(`latin` 또는 `non_latin`)에 따라 최상위 필드(`first_name`, `last_name`, `full_name`, `address`, `place_of_birth`)를 채울 문자 체계가 결정됩니다. 반대 문자 체계는 여기에 `first_name_non_latin` / `last_name_non_latin` / `full_name_non_latin` / `middle_name_non_latin` / `address_non_latin` / `place_of_birth_non_latin`(`preferred_characters`가 `latin`인 경우)으로 들어가거나 `_latin` 접미사(`preferred_characters`가 `non_latin`인 경우)가 붙어 들어갑니다. 키는 OCR이 실제 대체 문자 체계 값을 추출한 경우에만 나타나며, 대체 값이 선호하는 문자 체계와 동일한 필드(예: 키릴 문자로 표기된 필드의 OCR 값이 라틴어 동형 문자로 반환된 경우)는 건너뜁니다. `preferred_characters`가 `latin`이지만 문서에 비라틴 문자 텍스트만 있는 경우, Didit은 추출된 값을 음차 변환하여 대체 값으로 `first_name_latin` / `last_name_latin` 등을 제공합니다.",
                  "additionalProperties": true,
                  "properties": {
                    "dl_categories": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "blood_group": {
                      "type": "string",
                      "nullable": true
                    },
                    "first_name_non_latin": {
                      "type": "string",
                      "description": "`preferred_characters=latin`이고 문서에 비로마자 버전이 있는 경우 비로마자 문자 체계의 이름입니다(예: 키르기스스탄 신분증의 `Айна`)."
                    },
                    "last_name_non_latin": {
                      "type": "string",
                      "description": "`preferred_characters=latin`이고 문서에 비라틴 문자 체계 버전이 있는 경우 비라틴 문자 체계의 성입니다."
                    },
                    "middle_name_non_latin": {
                      "type": "string",
                      "description": "`preferred_characters=latin`이고 문서에 비라틴 문자 버전이 있는 경우의 비라틴 문자 중간 이름/부칭입니다."
                    },
                    "full_name_non_latin": {
                      "type": "string",
                      "description": "비라틴 문자 체계로 작성된 전체 성명입니다. 이름과 성이 모두 확인되면 개별 구성 요소로부터 재구성됩니다."
                    },
                    "address_non_latin": {
                      "type": "string",
                      "description": "`preferred_characters=latin`이고 문서에 비라틴 문자 버전이 기재되어 있을 때의 비라틴 문자 주소입니다."
                    },
                    "place_of_birth_non_latin": {
                      "type": "string",
                      "description": "`preferred_characters=latin`이고 문서에 비라틴 버전이 있는 경우 비라틴 문자 체계의 출생지입니다."
                    },
                    "first_name_latin": {
                      "type": "string",
                      "description": "로마자 문자 체계의 이름입니다. `preferred_characters=non_latin`이고 문서에 로마자 표기가 있는 경우, 또는 음차 대체 기능으로서 `preferred_characters=latin`이지만 문서에 비로마자 텍스트만 있는 경우 채워집니다."
                    },
                    "last_name_latin": {
                      "type": "string",
                      "description": "라틴 문자 체계의 성입니다. `first_name_latin`과 동일한 규칙이 적용됩니다."
                    },
                    "middle_name_latin": {
                      "type": "string",
                      "description": "라틴 문자로 된 중간 이름/부칭입니다. `first_name_latin`과 동일한 규칙이 적용됩니다."
                    },
                    "full_name_latin": {
                      "type": "string",
                      "description": "라틴 문자 체계로 작성된 전체 성명입니다. 이름과 성이 모두 확인되면 항상 개별 구성 요소로부터 재구성됩니다."
                    },
                    "address_latin": {
                      "type": "string",
                      "description": "라틴 문자로 표기된 주소입니다. `first_name_latin`과 동일한 규칙이 적용됩니다."
                    },
                    "place_of_birth_latin": {
                      "type": "string",
                      "description": "라틴 문자 체계의 출생지입니다. `first_name_latin`과 동일한 규칙이 적용됩니다."
                    }
                  }
                },
                "mrz": {
                  "type": "object",
                  "nullable": true,
                  "description": "문서에서 추출하여 파싱한 기계 판독 영역(MRZ) 필드입니다. MRZ가 감지되지 않은 경우 `null`입니다.",
                  "properties": {
                    "surname": {
                      "type": "string",
                      "example": "MARTINEZ<SANCHEZ"
                    },
                    "name": {
                      "type": "string",
                      "example": "ELENA"
                    },
                    "country": {
                      "type": "string",
                      "example": "ESP"
                    },
                    "nationality": {
                      "type": "string",
                      "example": "ESP"
                    },
                    "birth_date": {
                      "type": "string",
                      "example": "850315"
                    },
                    "expiry_date": {
                      "type": "string",
                      "example": "220821"
                    },
                    "sex": {
                      "type": "string",
                      "example": "F"
                    },
                    "document_type": {
                      "type": "string",
                      "example": "ID"
                    },
                    "document_number": {
                      "type": "string",
                      "example": "YZA123456"
                    },
                    "optional_data": {
                      "type": "string",
                      "example": "X9876543L"
                    },
                    "optional_data_2": {
                      "type": "string",
                      "example": ""
                    },
                    "birth_date_hash": {
                      "type": "string",
                      "example": "7"
                    },
                    "expiry_date_hash": {
                      "type": "string",
                      "example": "4"
                    },
                    "document_number_hash": {
                      "type": "string",
                      "example": "9"
                    },
                    "final_hash": {
                      "type": "string",
                      "example": "2"
                    },
                    "personal_number": {
                      "type": "string",
                      "example": "X9876543L"
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "mrz_type": {
                      "type": "string",
                      "example": "TD1"
                    },
                    "mrz_string": {
                      "type": "string",
                      "example": "IDESPMARTINEZ<SANCHEZ<<<<<<<<<<\nYZA123456<9ESP8503157F3208214<X9876543L<<<<<<<2\nMARTINEZ<SANCHEZ<<ELENA<<<<<<<<<<"
                    },
                    "mrz_key": {
                      "type": "string",
                      "example": "YZA123456985031573208214"
                    }
                  }
                },
                "parsed_address": {
                  "type": "object",
                  "description": "구조화된 주소 세부 정보",
                  "properties": {
                    "city": {
                      "type": "string"
                    },
                    "label": {
                      "type": "string"
                    },
                    "region": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string",
                      "description": "두 글자 국가 코드"
                    },
                    "category": {
                      "type": "string",
                      "description": "주소 카테고리(예: Residential, Commercial)"
                    },
                    "street_1": {
                      "type": "string"
                    },
                    "street_2": {
                      "type": "string",
                      "nullable": true
                    },
                    "is_verified": {
                      "type": "boolean",
                      "description": "주소가 검증되었는지 여부"
                    },
                    "postal_code": {
                      "type": "string"
                    },
                    "raw_results": {
                      "type": "object",
                      "properties": {
                        "types": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "geometry": {
                          "type": "object",
                          "properties": {
                            "location": {
                              "type": "object",
                              "properties": {
                                "lat": {
                                  "type": "number"
                                },
                                "lng": {
                                  "type": "number"
                                }
                              }
                            },
                            "viewport": {
                              "type": "object",
                              "properties": {
                                "northeast": {
                                  "type": "object",
                                  "properties": {
                                    "lat": {
                                      "type": "number"
                                    },
                                    "lng": {
                                      "type": "number"
                                    }
                                  }
                                },
                                "southwest": {
                                  "type": "object",
                                  "properties": {
                                    "lat": {
                                      "type": "number"
                                    },
                                    "lng": {
                                      "type": "number"
                                    }
                                  }
                                }
                              }
                            },
                            "location_type": {
                              "type": "string"
                            }
                          }
                        },
                        "place_id": {
                          "type": "string"
                        },
                        "formatted_address": {
                          "type": "string"
                        },
                        "navigation_points": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "location": {
                                "type": "object",
                                "properties": {
                                  "latitude": {
                                    "type": "number"
                                  },
                                  "longitude": {
                                    "type": "number"
                                  }
                                }
                              }
                            }
                          }
                        },
                        "address_components": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "types": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "long_name": {
                                "type": "string"
                              },
                              "short_name": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "address_type": {
                      "type": "string"
                    },
                    "document_location": {
                      "type": "object",
                      "properties": {
                        "latitude": {
                          "type": "number"
                        },
                        "longitude": {
                          "type": "number"
                        }
                      }
                    },
                    "formatted_address": {
                      "type": "string"
                    }
                  }
                },
                "extra_files": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "format": "uri"
                  },
                  "description": "추가 문서 인증 파일"
                },
                "front_image_camera_front_face_match_score": {
                  "type": "number",
                  "nullable": true,
                  "description": "문서 앞면 이미지에서 추출한 인물 사진과 전면 카메라 이미지 간의 얼굴 대조 점수"
                },
                "back_image_camera_front_face_match_score": {
                  "type": "number",
                  "nullable": true,
                  "description": "문서 뒷면 이미지에서 추출한 인물 사진과 전면 카메라 이미지 간의 얼굴 대조 점수"
                },
                "document_selfie_face_matches": {
                  "type": "array",
                  "description": "신분증 캡처 중 전면 카메라가 촬영한 셀피와 얼굴이 일치하는 이전 세션 또는 얼굴 차단 목록 항목(무음 캡처 얼굴 검색)입니다. `liveness_checks[].matches`와 동일한 항목 형식입니다. 이 필드가 존재하기 전에 생성된 세션이거나 검색이 실행되지 않은 경우 `null`이며, 실행되었지만 일치 항목을 찾지 못한 경우 빈 배열입니다. `match_image_url`은 만료되는 사전 서명된 URL입니다.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "일치하는 얼굴의 세션 ID입니다. `source`가 `imported`, `list_entry` 또는 `retained_template`인 경우 `null`입니다."
                      },
                      "session_number": {
                        "type": "integer",
                        "nullable": true
                      },
                      "similarity_percentage": {
                        "type": "number",
                        "description": "두 이미지 간의 얼굴 유사도로, 0–100 범위로 제한됩니다."
                      },
                      "vendor_data": {
                        "type": "string",
                        "nullable": true,
                        "description": "가져온 얼굴 및 보존된 템플릿 얼굴의 경우 일치하는 세션 또는 연결된 사용자의 `vendor_data`입니다."
                      },
                      "vendor_user_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "`imported` 및 `retained_template` 일치 항목과 사용자에 연결된 세션 일치 항목에 대한 연결된 User id입니다. 목록 항목 및 사용자가 없는 세션의 경우 `null`입니다."
                      },
                      "biometric_template_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "보존된 생체 인식 템플릿의 ID입니다. `source`가 `retained_template`일 때만 설정되며, 그 외의 경우 `null`입니다."
                      },
                      "verification_date": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "일치하는 얼굴이 캡처된 시점 또는 보존된 템플릿이 생성된 시점입니다. 목록 항목의 경우 `null`입니다."
                      },
                      "user_details": {
                        "type": "object",
                        "nullable": true,
                        "description": "일치하는 세션 또는 가져온 사용자 프로필의 신원 데이터입니다. `retained_template` 및 `list_entry` 일치의 경우 항상 `null`입니다.",
                        "properties": {
                          "full_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "document_type": {
                            "type": "string",
                            "nullable": true
                          },
                          "document_number": {
                            "type": "string",
                            "nullable": true
                          }
                        }
                      },
                      "match_image_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "이미지 기반 대조를 위한 기준 이미지입니다. 보존된 템플릿에는 이미지가 포함되어 있지 않으므로 `retained_template` 대조의 경우 항상 `null`입니다."
                      },
                      "status": {
                        "type": "string",
                        "nullable": true,
                        "description": "일치하는 세션의 수명 주기 상태입니다. 비세션 소스의 경우 `null`입니다."
                      },
                      "is_blocklisted": {
                        "type": "boolean",
                        "description": "일치하는 얼굴이 차단 목록에 있는지 여부입니다."
                      },
                      "is_allowlisted": {
                        "type": "boolean",
                        "description": "일치하는 얼굴이 허용 목록에 있는지 여부입니다."
                      },
                      "api_service": {
                        "type": "string",
                        "nullable": true,
                        "description": "일치하는 세션의 독립형 API 서비스입니다(예: `PASSIVE_LIVENESS`, `FACE_MATCH`). 워크플로 세션 및 세션이 아닌 소스의 경우 `null`입니다."
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "session",
                          "imported",
                          "list_entry",
                          "retained_template"
                        ],
                        "description": "일치하는 얼굴의 출처: `session`, `imported`(사용자 얼굴 업로드), `list_entry`(허용/차단 목록), 또는 `retained_template`(사용자에게 저장된 이미지가 없는 생체 인식 템플릿으로, `/v3/biometric-templates/` 아래 나열됨)."
                      }
                    }
                  },
                  "nullable": true
                },
                "front_image_quality_score": {
                  "type": "object",
                  "nullable": true,
                  "description": "문서 앞면 이미지에 대한 품질 지표입니다. 각 하위 점수의 범위는 0에서 100까지입니다.",
                  "properties": {
                    "focus_score": {
                      "type": "number",
                      "description": "상위 10% 로컬 라플라시안 분산을 통해 측정한 이미지의 선명도입니다. 균일한 배경이 넓게 차지하는 문서에도 안정적입니다. 값이 높을수록 이미지가 더 선명하고 흐림이 적음을 나타냅니다."
                    },
                    "brightness_score": {
                      "type": "number",
                      "description": "이미지의 조명 상태입니다. 너무 어둡거나 과다 노출된 이미지에 페널티를 부여하며, 중간 정도의 밝기가 이상적입니다."
                    },
                    "brightness_issue": {
                      "type": "string",
                      "enum": [
                        "ok",
                        "too_dark",
                        "too_bright"
                      ],
                      "description": "brightness_score가 낮을 때 밝기 문제의 방향을 나타냅니다. 'ok'는 밝기가 적절함을, 'too_dark'는 이미지가 노출 부족임을, 'too_bright'는 이미지가 과다 노출임을 의미합니다."
                    },
                    "is_document_fully_visible": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "문서의 네 모서리가 모두 이미지 프레임 내에 완전히 보이면 true, 모서리가 하나라도 잘리면 false입니다. 모서리 좌표를 사용할 수 없는 경우 Null입니다."
                    },
                    "resolution_score": {
                      "type": "number",
                      "description": "총 픽셀 수 기반 이미지의 유효 해상도입니다."
                    },
                    "overall_score": {
                      "type": "number",
                      "description": "하위 점수의 가중 종합 점수입니다(초점 45%, 밝기 30%, 해상도 25%)."
                    }
                  }
                },
                "back_image_quality_score": {
                  "type": "object",
                  "nullable": true,
                  "description": "문서 뒷면 이미지에 대한 품질 지표입니다. front_image_quality_score와 동일한 구조입니다.",
                  "properties": {
                    "focus_score": {
                      "type": "number",
                      "description": "상위 10% 로컬 라플라시안 분산을 통해 측정한 이미지의 선명도입니다. 균일한 배경이 넓게 차지하는 문서에도 안정적입니다. 값이 높을수록 이미지가 더 선명하고 흐림이 적음을 나타냅니다."
                    },
                    "brightness_score": {
                      "type": "number",
                      "description": "이미지의 조명 상태입니다. 너무 어둡거나 과다 노출된 이미지에 페널티를 부여하며, 중간 정도의 밝기가 이상적입니다."
                    },
                    "brightness_issue": {
                      "type": "string",
                      "enum": [
                        "ok",
                        "too_dark",
                        "too_bright"
                      ],
                      "description": "brightness_score가 낮을 때 밝기 문제의 방향을 나타냅니다. 'ok'는 밝기가 적절함을, 'too_dark'는 이미지가 노출 부족임을, 'too_bright'는 이미지가 과다 노출임을 의미합니다."
                    },
                    "is_document_fully_visible": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "문서의 네 모서리가 모두 이미지 프레임 내에 완전히 보이면 true, 모서리가 하나라도 잘리면 false입니다. 모서리 좌표를 사용할 수 없는 경우 Null입니다."
                    },
                    "resolution_score": {
                      "type": "number",
                      "description": "총 픽셀 수 기반 이미지의 유효 해상도입니다."
                    },
                    "overall_score": {
                      "type": "number",
                      "description": "하위 점수의 가중 종합 점수입니다(초점 45%, 밝기 30%, 해상도 25%)."
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "이 경고를 생성한 기능(예: `ID_VERIFICATION`, `NFC`, `LIVENESS`)입니다. 이 값은 경고가 속한 기능 블록을 식별합니다. 각 모듈의 경고 배열은 일반적으로 해당 모듈과 일치하는 값을 사용하지만, 결정 payload의 모든 기능 경고에 대해서는 위의 enum이 기준이 됩니다."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true,
                        "description": "경고에 대한 추가 맥락 데이터"
                      },
                      "log_type": {
                        "type": "string",
                        "description": "로그 유형: 정보, 경고 또는 오류"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "이 경고를 생성한 워크플로 그래프 노드 ID(그래프 기반 워크플로의 경우)"
                      }
                    }
                  },
                  "description": "문서 검증 경고"
                },
                "matches": {
                  "type": "array",
                  "description": "중복/차단 목록 감지 중 발견된 일치하는 문서(최대 5개 일치 항목)",
                  "items": {
                    "type": "object",
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "일치하는 문서의 세션 ID"
                      },
                      "session_number": {
                        "type": "integer",
                        "description": "일치하는 문서의 세션 번호"
                      },
                      "vendor_data": {
                        "type": "string",
                        "nullable": true,
                        "description": "일치하는 세션과 연결된 벤더 데이터입니다."
                      },
                      "verification_date": {
                        "type": "string",
                        "format": "date-time",
                        "description": "일치하는 세션이 인증된 날짜"
                      },
                      "user_details": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "description": "일치하는 문서의 성명"
                          },
                          "document_type": {
                            "type": "string",
                            "description": "일치하는 문서의 유형"
                          },
                          "document_number": {
                            "type": "string",
                            "description": "일치하는 문서의 문서 번호"
                          }
                        }
                      },
                      "status": {
                        "type": "string",
                        "description": "일치하는 세션의 상태"
                      },
                      "is_blocklisted": {
                        "type": "boolean",
                        "description": "일치하는 문서가 차단 목록에 있는지 여부"
                      },
                      "api_service": {
                        "type": "string",
                        "nullable": true,
                        "description": "일치하는 세션의 API 서비스 유형"
                      },
                      "front_image_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "일치하는 문서의 문서 앞면 이미지 URL"
                      }
                    }
                  }
                },
                "document_liveness": {
                  "type": "object",
                  "nullable": true,
                  "description": "사기 유형별 문서 라이브니스 점수로, 경고 발생 여부와 관계없이 보고되므로 승인된 문서도 감사할 수 있습니다. 검사가 실행되지 않은 경우 `null`입니다.",
                  "properties": {
                    "portrait_replace": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "score": {
                          "type": "number",
                          "nullable": true,
                          "description": "해당 사기 유형에 대해 문서가 진본일 가능성입니다 (0-100, 높을수록 진본일 가능성이 높음). 양면 중 더 낮은 값이며, 결정에 사용된 값입니다. 어느 쪽도 사용할 수 있는 점수를 생성하지 못한 경우 `null`입니다."
                        },
                        "front": {
                          "type": "number",
                          "nullable": true,
                          "description": "앞면에 대한 점수입니다. 캡처되지 않았거나 점수가 제외된 경우 `null`입니다."
                        },
                        "back": {
                          "type": "number",
                          "nullable": true,
                          "description": "뒷면에 대한 점수입니다. 캡처되지 않았거나 점수가 제외된 경우 `null`입니다."
                        },
                        "decline_threshold": {
                          "type": "number",
                          "nullable": true,
                          "description": "이 문서가 평가되었을 때 저장된 거부 임계값입니다. 이후의 워크플로 편집으로도 변경되지 않습니다. 과거 평가 증거를 사용할 수 없는 경우 Null입니다."
                        },
                        "review_threshold": {
                          "type": "number",
                          "nullable": true,
                          "description": "이 문서를 평가할 때 저장된 검토 임계값입니다. 이후 워크플로를 수정해도 변경되지 않습니다. 과거 평가 증거를 사용할 수 없는 경우 Null입니다."
                        },
                        "bucket": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "approve",
                            "review",
                            "decline",
                            null
                          ],
                          "description": "평가 시점에 저장된 사기 유형 버킷입니다. 사용 가능한 점수가 없거나, 검사가 적용되지 않았거나, 과거 평가 증거를 사용할 수 없는 경우 null입니다. 이후 워크플로를 수정해도 변경되지 않습니다."
                        }
                      }
                    },
                    "printed_copy": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "score": {
                          "type": "number",
                          "nullable": true,
                          "description": "해당 사기 유형에 대해 문서가 진본일 가능성입니다 (0-100, 높을수록 진본일 가능성이 높음). 양면 중 더 낮은 값이며, 결정에 사용된 값입니다. 어느 쪽도 사용할 수 있는 점수를 생성하지 못한 경우 `null`입니다."
                        },
                        "front": {
                          "type": "number",
                          "nullable": true,
                          "description": "앞면에 대한 점수입니다. 캡처되지 않았거나 점수가 제외된 경우 `null`입니다."
                        },
                        "back": {
                          "type": "number",
                          "nullable": true,
                          "description": "뒷면에 대한 점수입니다. 캡처되지 않았거나 점수가 제외된 경우 `null`입니다."
                        },
                        "decline_threshold": {
                          "type": "number",
                          "nullable": true,
                          "description": "이 문서가 평가되었을 때 저장된 거부 임계값입니다. 이후의 워크플로 편집으로도 변경되지 않습니다. 과거 평가 증거를 사용할 수 없는 경우 Null입니다."
                        },
                        "review_threshold": {
                          "type": "number",
                          "nullable": true,
                          "description": "이 문서를 평가할 때 저장된 검토 임계값입니다. 이후 워크플로를 수정해도 변경되지 않습니다. 과거 평가 증거를 사용할 수 없는 경우 Null입니다."
                        },
                        "bucket": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "approve",
                            "review",
                            "decline",
                            null
                          ],
                          "description": "평가 시점에 저장된 사기 유형 버킷입니다. 사용 가능한 점수가 없거나, 검사가 적용되지 않았거나, 과거 평가 증거를 사용할 수 없는 경우 null입니다. 이후 워크플로를 수정해도 변경되지 않습니다."
                        }
                      }
                    },
                    "screen_replay": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "score": {
                          "type": "number",
                          "nullable": true,
                          "description": "해당 사기 유형에 대해 문서가 진본일 가능성입니다 (0-100, 높을수록 진본일 가능성이 높음). 양면 중 더 낮은 값이며, 결정에 사용된 값입니다. 어느 쪽도 사용할 수 있는 점수를 생성하지 못한 경우 `null`입니다."
                        },
                        "front": {
                          "type": "number",
                          "nullable": true,
                          "description": "앞면에 대한 점수입니다. 캡처되지 않았거나 점수가 제외된 경우 `null`입니다."
                        },
                        "back": {
                          "type": "number",
                          "nullable": true,
                          "description": "뒷면에 대한 점수입니다. 캡처되지 않았거나 점수가 제외된 경우 `null`입니다."
                        },
                        "decline_threshold": {
                          "type": "number",
                          "nullable": true,
                          "description": "이 문서가 평가되었을 때 저장된 거부 임계값입니다. 이후의 워크플로 편집으로도 변경되지 않습니다. 과거 평가 증거를 사용할 수 없는 경우 Null입니다."
                        },
                        "review_threshold": {
                          "type": "number",
                          "nullable": true,
                          "description": "이 문서를 평가할 때 저장된 검토 임계값입니다. 이후 워크플로를 수정해도 변경되지 않습니다. 과거 평가 증거를 사용할 수 없는 경우 Null입니다."
                        },
                        "bucket": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "approve",
                            "review",
                            "decline",
                            null
                          ],
                          "description": "평가 시점에 저장된 사기 유형 버킷입니다. 사용 가능한 점수가 없거나, 검사가 적용되지 않았거나, 과거 평가 증거를 사용할 수 없는 경우 null입니다. 이후 워크플로를 수정해도 변경되지 않습니다."
                        }
                      }
                    }
                  }
                },
                "address_validation": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/AddressValidationResult"
                    }
                  ],
                  "nullable": true,
                  "description": "이 문서에 인쇄된 주소에 대한 주소 검증입니다. 문서에서 읽은 주소의 존재 여부 및 정규화된 형태를 나타냅니다(이후 `address`를 수정해도 다시 실행되지 않음). 이 신분증 인증 단계에서 주소 검증 추가 기능이 활성화되어 있는 경우에 제공되며, 그렇지 않으면 `null`입니다."
                },
                "region": {
                  "type": "string",
                  "nullable": true,
                  "description": "문서에 명시되어 있는 경우, 문서 발급 국가의 지역 또는 주입니다."
                },
                "extracted_data": {
                  "type": "object",
                  "nullable": true,
                  "additionalProperties": true,
                  "description": "사용자가 검토하도록 표시된 문서에서 추출된 데이터의 스냅샷입니다. 읽어낸 내용과 사용자가 확인한 내용을 비교할 수 있도록 확인된 값 옆에 보관됩니다. 사용자에게 검토를 요청하지 않은 경우 `null`입니다."
                },
                "barcodes": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "description": "문서의 바코드에서 읽은 데이터입니다. 문서에 바코드가 없거나 읽은 바코드가 없는 경우 비어 있습니다."
                }
              }
            }
          },
          "nfc_skip_reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "USER_SKIPPED",
              "DOCUMENT_WITHOUT_CHIP",
              "CHIP_CERTIFICATE_UNAVAILABLE",
              "DEVICE_WITHOUT_NFC",
              "INTEGRATION_WITHOUT_NFC_ACCESS",
              "MRZ_KEY_UNAVAILABLE",
              "JPKI_UNAVAILABLE"
            ],
            "description": "NFC 칩 인증이 실행되지 않은 이유로, 워크플로에 NFC 단계가 포함되어 있을 때마다 채워집니다. NFC가 대기 중이거나 칩을 실제로 읽은 경우에는 `null`입니다. 값: `USER_SKIPPED` - 사용자가 NFC 지원 기기에서 건너뛰기를 선택함(`allow_nfc_skip`에 의해 허용됨), `DOCUMENT_WITHOUT_CHIP` - 문서에 읽기 가능한 NFC 칩이 없음(ICAO 9303 전자 문서가 아님), `CHIP_CERTIFICATE_UNAVAILABLE` - 문서 발급 기간을 포함하는 발급 국가의 서명 인증서(CSCA)를 사용할 수 없어 칩 서명을 검증할 수 없음, `DEVICE_WITHOUT_NFC` - 기기에서 NFC 리더가 보고되지 않음, `INTEGRATION_WITHOUT_NFC_ACCESS` - 휴대폰의 NFC 리더에 접근할 수 없는 네이티브 SDK 없이(예: 웹 브라우저에서) 인증이 실행됨, `MRZ_KEY_UNAVAILABLE` - 문서의 MRZ에서 칩 접근 키를 도출할 수 없음, `JPKI_UNAVAILABLE` - 문서가 일본 마이넘버 카드이고 칩을 JPKI를 통해 읽는데, 해당 인증에서 JPKI를 사용할 수 없음(활성화되지 않았거나 앱의 네이티브 SDK가 마이넘버 카드를 읽을 수 없음)."
          },
          "nfc_verifications": {
            "type": "array",
            "nullable": true,
            "description": "워크플로 그래프의 NFC 단계에서 생성된 **NFC / 전자여권 보고서 배열**입니다. **단일 `nfc` 객체가 아닌 항상 JSON 배열입니다** — 워크플로에서 NFC를 두 번 이상 실행할 수 있는 경우 `nfc_verifications[0]`을 읽고 반복 처리하십시오. 하나 이상의 NFC 단계에서 데이터가 생성될 때까지 `null`입니다. 각 항목은 `node_id`, 기능 수준 `status`, `chip_protocol`, `chip_data`, `authenticity`(SOD + DG 무결성), `certificate_summary`, `warnings[]`를 포함한 전체 보고서입니다. 일본 마이넘버카드는 ICAO 9303 대신 JPKI를 통해 읽힙니다. 해당 항목은 `chip_protocol: \"jpki\"`를 가지며 증거를 `jpki` 아래에 포함하고 ICAO 필드는 `null`로 유지합니다. NFC 단계를 제시할 수 있기 전에 건너뛴 경우(칩이 없는 문서, 인증서 누락, 보고된 NFC 기능 없음, 읽을 수 없는 MRZ 키, 마이넘버카드에 JPKI를 사용할 수 없음) 이 필드는 `null`로 유지되며 `nfc_skip_reason`에 이유가 설명됩니다. 단계 자체에서 건너뛴 경우(사용자가 건너뛰기를 탭했거나 스캔 시점에 리더기를 사용할 수 없는 것으로 나타남)에는 `is_nfc_skipped: true`인 보고서가 생성됩니다.",
            "items": {
              "type": "object",
              "description": "단일 NFC 보고서: 단일 칩 판독에 대한 전체 보고서(ICAO 9303 전자여권 또는 eID 칩, 또는 JPKI를 통해 판독된 일본 마이넘버카드)입니다.",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "이 보고서를 생성한 NFC 단계의 워크플로 그래프 노드 ID입니다. 보고서를 워크플로 정의와 연결하는 데 사용합니다."
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ],
                  "description": "이 NFC 단계의 기능 수준 상태입니다. 최상위 세션 `status`와는 독립적입니다. 개별 기능이 `In Review` 상태로 유지되는 동안에도 세션이 전체 결정에 도달할 수 있습니다."
                },
                "is_nfc_skipped": {
                  "type": "boolean",
                  "description": "이 NFC 단계를 판독하지 않고 명시적으로 건너뛴 경우 `true`입니다. 건너뛴 이유는 `skip_reason`에 표시됩니다."
                },
                "skip_reason": {
                  "type": "string",
                  "nullable": true,
                  "enum": [
                    "USER_SKIPPED",
                    "DOCUMENT_WITHOUT_CHIP",
                    "CHIP_CERTIFICATE_UNAVAILABLE",
                    "DEVICE_WITHOUT_NFC",
                    "INTEGRATION_WITHOUT_NFC_ACCESS",
                    "MRZ_KEY_UNAVAILABLE",
                    "JPKI_UNAVAILABLE"
                  ],
                  "description": "이 NFC 단계를 건너뛴 이유입니다. `is_nfc_skipped`가 `true`일 때만 설정됩니다. NFC가 보고서를 전혀 생성하지 못한 경우까지 추가로 다루는 세션 수준의 `nfc_skip_reason`과 동일한 분류 체계를 따릅니다."
                },
                "chip_protocol": {
                  "type": "string",
                  "enum": [
                    "icao",
                    "jpki"
                  ],
                  "description": "NFC 단계에서 칩을 읽는 방식입니다. `icao`: MRZ의 액세스 키를 사용하여 개방하는 ICAO 9303 전자여권 또는 전자 신분증 칩입니다. `jpki`: 일본 마이넘버카드로, 네이티브 SDK에서 소지자가 카드 PIN을 입력한 후 카드가 일회용 챌린지에 서명하는 방식이며 결과는 `jpki` 아래에 제공됩니다. 건너뛴 단계에도 설정되므로 마이넘버카드 판독이 건너뛰어졌는지 구분할 수 있습니다."
                },
                "jpki": {
                  "type": "object",
                  "nullable": true,
                  "description": "JPKI를 통해 읽은 일본 마이넘버 카드로 증명된 내용입니다. `chip_protocol`이 `jpki`이고 카드를 읽었을 때 존재합니다. ICAO 칩, 건너뛴 단계 및 카드를 전혀 읽지 않고 NFC 단계가 종료된 경우(이 경우 `JPKI_SIGNATURE_INVALID`가 발생함)에는 `null`입니다. 인증서, 일련번호, 서명 또는 12자리 마이넘버는 절대 포함되지 않습니다.",
                  "properties": {
                    "certificate_types": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "user_authentication",
                          "signature"
                        ]
                      },
                      "description": "읽은 카드 인증서입니다. `user_authentication`(4자리 PIN)은 항상 읽으며, `signature`(서명 PIN)는 NFC 노드의 `jpki_request_attributes` 설정이 켜져 있을 때 읽습니다."
                    },
                    "chain_valid": {
                      "type": "boolean",
                      "description": "판독된 모든 인증서가 JPKI 인증 기관으로 연결되고, 유효 기간 내에 있으며, 해당 유형의 마이넘버 카드 인증서인 경우 `true`입니다."
                    },
                    "signature_valid": {
                      "type": "boolean",
                      "description": "일회용 챌린지에 대해 카드가 생성한 모든 서명이 검증되면 `true`입니다. 카드는 PIN이 입력된 후에만 서명하므로, 이는 카드의 소지와 PIN에 대한 인지를 증명합니다."
                    },
                    "revocation_status": {
                      "type": "string",
                      "enum": [
                        "good",
                        "revoked",
                        "unchecked"
                      ],
                      "description": "폐기 확인을 통해 모든 인증서가 유효함이 확인된 경우 `good`, 인증서 중 하나라도 폐기된 경우(예: 분실 신고된 카드) `revoked`, 폐기 확인 응답을 얻을 수 없는 경우 `unchecked`입니다. `unchecked`는 절대로 `good`으로 처리되지 않으며, NFC 노드의 `jpki_revocation_unchecked_action`에 따라 결과(기본값 `REVIEW`)가 결정됩니다."
                    },
                    "ca_generation": {
                      "type": "string",
                      "nullable": true,
                      "description": "인증서를 발급한 JPKI 인증 기관의 세대(예: `2023`). 해당 기관으로 체인 연결되는 인증서가 없는 경우 `null`입니다."
                    },
                    "certificate_expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "판독된 인증서 중 가장 이른 만료일입니다."
                    },
                    "certificates": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "description": "카드에서 읽은 하나의 인증서가 증명한 내용입니다. 인증서 자체나 해당 일련번호는 절대 포함되지 않습니다.",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "user_authentication",
                              "signature"
                            ],
                            "description": "이 항목이 설명하는 카드 인증서입니다."
                          },
                          "chain_valid": {
                            "type": "boolean",
                            "description": "인증서가 해당 유형의 JPKI 인증 기관으로 연결되고, 유효 기간 내에 있으며, 해당 유형의 마이넘버 카드 인증서인 경우 `true`입니다."
                          },
                          "signature_valid": {
                            "type": "boolean",
                            "description": "일회용 챌린지에 대한 카드의 서명이 이 인증서로 검증되면 `true`입니다."
                          },
                          "ca_generation": {
                            "type": "string",
                            "nullable": true,
                            "description": "인증서를 발급한 JPKI 인증 기관의 세대(예: `2023`). 신뢰할 수 있는 발급자를 찾을 수 없는 경우 `null`입니다."
                          },
                          "not_valid_before": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "인증서 유효 기간의 시작일입니다. 인증서를 읽을 수 없는 경우 `null`입니다."
                          },
                          "not_valid_after": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "인증서 유효 기간의 종료일입니다. 인증서를 읽을 수 없는 경우 `null`입니다."
                          },
                          "failure": {
                            "type": "string",
                            "nullable": true,
                            "enum": [
                              "unreadable_certificate",
                              "untrusted_issuer",
                              "expired",
                              "not_yet_valid",
                              "wrong_policy",
                              "key_usage",
                              null
                            ],
                            "description": "`chain_valid`가 `false`인 이유: `unreadable_certificate`, `untrusted_issuer`(해당 유형의 JPKI 인증 기관에서 발급하지 않음), `expired`, `not_yet_valid`, `wrong_policy`(해당 유형의 마이넘버 카드 인증서가 아님) 또는 `key_usage`(키로 서명할 수 없음). 체인이 유효한 경우 `null`입니다."
                          }
                        }
                      },
                      "description": "인증서별 결과로, 판독된 인증서당 하나의 항목이 포함됩니다."
                    },
                    "attributes": {
                      "type": "object",
                      "nullable": true,
                      "description": "체인이 유효한 경우 서명 인증서에서 가져온 명의인 데이터입니다. 서명 인증서를 요청하지 않았거나 JPKI 인증 기관으로 체인이 연결되지 않은 경우 `null`입니다.",
                      "properties": {
                        "full_name": {
                          "type": "string",
                          "nullable": true,
                          "description": "등록된 이름(주로 일본어 문자 체계)."
                        },
                        "date_of_birth": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "description": "생년월일, `YYYY-MM-DD`입니다. 등록된 날짜가 불완전한 경우 `null`입니다."
                        },
                        "gender": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "M",
                            "F",
                            null
                          ],
                          "description": "등록되지 않은 경우 `M`, `F` 또는 `null`."
                        },
                        "address": {
                          "type": "string",
                          "nullable": true,
                          "description": "등록 주소입니다."
                        },
                        "name_substitute_characters": {
                          "type": "string",
                          "nullable": true,
                          "description": "원래 문자가 표준 문자 집합을 벗어나 대체 문자로 변경된 `full_name`의 문자를 표시하는 위치 문자열입니다. 대체된 문자가 없는 경우 `null`입니다."
                        },
                        "address_substitute_characters": {
                          "type": "string",
                          "nullable": true,
                          "description": "`name_substitute_characters`와 마찬가지로 `address`에서 대체 문자를 표시하는 위치 문자열입니다."
                        }
                      }
                    },
                    "attributes_match_ocr": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "속성이 동일한 카드의 사진에서 판독한 데이터와 일치하면 `true`, 속성이 하나라도 다르면 `false`(`JPKI_AND_OCR_DATA_NOT_SAME`), `attributes`가 `null`인 경우를 포함하여 비교할 수 없는 경우 `null`입니다."
                    },
                    "mismatched_attributes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "full_name",
                          "date_of_birth",
                          "gender",
                          "address"
                        ]
                      },
                      "description": "사진 데이터와 일치하지 않는 속성의 이름이며, 속성 값은 포함되지 않습니다. 비교한 모든 항목이 일치하면 비어 있습니다."
                    }
                  }
                },
                "portrait_image": {
                  "type": "string",
                  "format": "uri",
                  "nullable": true,
                  "description": "칩에서 읽은 인물 사진의 사전 서명된 URL(ICAO DG2)입니다. JPKI 읽기(`chip_protocol: \"jpki\"`) 및 건너뛴 단계의 경우 `null`입니다."
                },
                "signature_image": {
                  "type": "string",
                  "format": "uri",
                  "nullable": true,
                  "description": "칩에 서명 이미지가 저장되어 있는 경우 칩에서 읽은 소지자 서명 이미지의 사전 서명된 URL(ICAO DG7)입니다. JPKI 읽기(`chip_protocol: \"jpki\"`) 및 건너뛴 단계의 경우 `null`입니다."
                },
                "chip_data": {
                  "type": "object",
                  "nullable": true,
                  "description": "ICAO 칩의 Data Groups에서 파싱된 개인 데이터입니다. JPKI 판독(`chip_protocol: \"jpki\"`) 및 건너뛴 단계의 경우 `null`입니다.",
                  "properties": {
                    "document_type": {
                      "type": "string"
                    },
                    "issuing_country": {
                      "type": "string"
                    },
                    "document_number": {
                      "type": "string"
                    },
                    "expiration_date": {
                      "type": "string",
                      "format": "date"
                    },
                    "first_name": {
                      "type": "string"
                    },
                    "last_name": {
                      "type": "string"
                    },
                    "birth_date": {
                      "type": "string",
                      "format": "date"
                    },
                    "gender": {
                      "type": "string"
                    },
                    "nationality": {
                      "type": "string"
                    },
                    "address": {
                      "type": "string"
                    },
                    "place_of_birth": {
                      "type": "string"
                    }
                  }
                },
                "authenticity": {
                  "type": "object",
                  "nullable": true,
                  "description": "ICAO 수동적 인증: SOD 서명(`sod_integrity`) 및 데이터 그룹 해시(`dg_integrity`). `jpki` 아래에 증명을 보고하는 JPKI 판독의 경우 `null`입니다.",
                  "properties": {
                    "sod_integrity": {
                      "type": "boolean"
                    },
                    "dg_integrity": {
                      "type": "boolean"
                    }
                  }
                },
                "certificate_summary": {
                  "type": "object",
                  "nullable": true,
                  "description": "ICAO 문서 서명자 인증서의 요약 정보입니다. JPKI 판독(`chip_protocol: \"jpki\"`) 및 건너뛴 단계의 경우 `null`입니다.",
                  "properties": {
                    "issuer": {
                      "type": "string"
                    },
                    "subject": {
                      "type": "string"
                    },
                    "serial_number": {
                      "type": "string"
                    },
                    "not_valid_after": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "not_valid_before": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "이 경고를 생성한 기능입니다. 이 값은 경고가 속한 기능 블록을 식별합니다. 각 모듈의 경고 배열은 일반적으로 해당 모듈과 일치하는 값을 사용하지만(예: `phone_verifications[].warnings` 내부의 `PHONE`), 결정 payload의 모든 기능 경고에 대해서는 위의 enum이 기준이 됩니다."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "이 경고를 생성한 워크플로 그래프 노드 ID"
                      }
                    }
                  }
                }
              }
            }
          },
          "liveness_checks": {
            "type": "array",
            "nullable": true,
            "description": "워크플로 그래프의 라이브니스 단계에서 생성된 **라이브니스 보고서 배열**입니다. 단일 `liveness` 객체가 아닌 항상 JSON 배열입니다. 하나 이상의 라이브니스 단계에서 데이터가 생성될 때까지 `null`입니다. 각 항목은 `node_id`, 기능 수준 `status`, `method`, `score`, `reference_image`, `video_url`, 선택 사항인 `age_estimation`, 세션 간 `matches[]`, `warnings[]`를 포함한 전체 보고서입니다.",
            "items": {
              "type": "object",
              "description": "라이브니스 보고서 1건 — 단일 라이브니스 검사 1회에 대한 전체 보고서입니다.",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "이 보고서를 생성한 라이브니스 단계의 워크플로 그래프 노드 ID입니다."
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ],
                  "description": "이 라이브니스 단계의 기능 수준 상태입니다. 최상위 세션 `status`와는 독립적입니다. 개별 기능이 `In Review` 상태로 유지되는 동안에도 세션이 전체 결정에 도달할 수 있습니다."
                },
                "method": {
                  "type": "string",
                  "description": "라이브니스 감지에 사용된 방식"
                },
                "score": {
                  "type": "number",
                  "description": "라이브니스 검사의 신뢰도 점수"
                },
                "reference_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "사용된 참조 이미지의 URL"
                },
                "video_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "라이브니스 확인 동영상의 URL"
                },
                "age_estimation": {
                  "type": "number",
                  "description": "인물의 추정 연령"
                },
                "matches": {
                  "type": "array",
                  "description": "중복 얼굴 검색을 통해 발견된 유사한 얼굴 목록입니다(상위 일치 항목, 차단 목록/허용 목록 항목 우선). 각 항목의 `source`는 일치하는 얼굴의 출처를 나타냅니다. `session`(다른 인증 세션), `imported`(벤더 사용자에 대해 업로드된 얼굴), `list_entry`(조직에서 관리하는 허용/차단 목록 얼굴), 또는 `retained_template`(`/v3/biometric-templates/` 아래에 나열된 사용자에게 저장된 이미지가 없는 생체 인식 템플릿)입니다. 세션이 아닌 출처의 경우 `session_id`, `session_number`, `status`, `api_service`는 `null`입니다. `imported` 일치 항목은 벤더 사용자 레코드의 `vendor_data`, `verification_date` 및 벤더 사용자의 이름이 등록되어 있는 경우 `user_details`(`full_name`만 포함)를 계속 채웁니다. `retained_template` 일치 항목은 `vendor_user_id`, `vendor_data`, `biometric_template_id`, `verification_date`를 채우는 반면 이미지 및 신원 필드는 `null`입니다. `list_entry` 일치 항목은 이들 모두를 `null`로 반환합니다.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "일치하는 얼굴의 세션 ID입니다. `source`가 `imported`, `list_entry` 또는 `retained_template`인 경우 `null`입니다."
                      },
                      "session_number": {
                        "type": "integer",
                        "nullable": true
                      },
                      "similarity_percentage": {
                        "type": "number",
                        "description": "두 이미지 간의 얼굴 유사도로, 0–100 범위로 제한됩니다."
                      },
                      "vendor_data": {
                        "type": "string",
                        "nullable": true,
                        "description": "가져온 얼굴 및 보존된 템플릿 얼굴의 경우 일치하는 세션 또는 연결된 사용자의 `vendor_data`입니다."
                      },
                      "vendor_user_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "`imported` 및 `retained_template` 일치 항목과 사용자에 연결된 세션 일치 항목에 대한 연결된 User id입니다. 목록 항목 및 사용자가 없는 세션의 경우 `null`입니다."
                      },
                      "biometric_template_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "보존된 생체 인식 템플릿의 ID입니다. `source`가 `retained_template`일 때만 설정되며, 그 외의 경우 `null`입니다."
                      },
                      "verification_date": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "일치하는 얼굴이 캡처된 시점 또는 보존된 템플릿이 생성된 시점입니다. 목록 항목의 경우 `null`입니다."
                      },
                      "user_details": {
                        "type": "object",
                        "nullable": true,
                        "description": "일치하는 세션 또는 가져온 사용자 프로필의 신원 데이터입니다. `retained_template` 및 `list_entry` 일치의 경우 항상 `null`입니다.",
                        "properties": {
                          "full_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "document_type": {
                            "type": "string",
                            "nullable": true
                          },
                          "document_number": {
                            "type": "string",
                            "nullable": true
                          }
                        }
                      },
                      "match_image_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "이미지 기반 대조를 위한 기준 이미지입니다. 보존된 템플릿에는 이미지가 포함되어 있지 않으므로 `retained_template` 대조의 경우 항상 `null`입니다."
                      },
                      "status": {
                        "type": "string",
                        "nullable": true,
                        "description": "일치하는 세션의 수명 주기 상태입니다. 비세션 소스의 경우 `null`입니다."
                      },
                      "is_blocklisted": {
                        "type": "boolean",
                        "description": "일치하는 얼굴이 차단 목록에 있는지 여부입니다."
                      },
                      "is_allowlisted": {
                        "type": "boolean",
                        "description": "일치하는 얼굴이 허용 목록에 있는지 여부입니다."
                      },
                      "api_service": {
                        "type": "string",
                        "nullable": true,
                        "description": "일치하는 세션의 독립형 API 서비스입니다(예: `PASSIVE_LIVENESS`, `FACE_MATCH`). 워크플로 세션 및 세션이 아닌 소스의 경우 `null`입니다."
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "session",
                          "imported",
                          "list_entry",
                          "retained_template"
                        ],
                        "description": "일치하는 얼굴의 출처: `session`, `imported`(사용자 얼굴 업로드), `list_entry`(허용/차단 목록), 또는 `retained_template`(사용자에게 저장된 이미지가 없는 생체 인식 템플릿으로, `/v3/biometric-templates/` 아래 나열됨)."
                      }
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "이 경고를 생성한 기능입니다. 이 값은 경고가 속한 기능 블록을 식별합니다. 각 모듈의 경고 배열은 일반적으로 해당 모듈과 일치하는 값을 사용하지만(예: `phone_verifications[].warnings` 내부의 `PHONE`), 결정 payload의 모든 기능 경고에 대해서는 위의 enum이 기준이 됩니다."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "이 경고를 생성한 워크플로 그래프 노드 ID"
                      }
                    }
                  }
                },
                "face_quality": {
                  "type": "number",
                  "nullable": true,
                  "description": "얼굴 이미지 품질 점수(0-100%). 패시브 라이브니스에서만 사용할 수 있습니다."
                },
                "face_luminance": {
                  "type": "number",
                  "nullable": true,
                  "description": "얼굴 휘도/밝기 점수(0-100%). 패시브 라이브니스에서만 사용할 수 있습니다."
                }
              }
            }
          },
          "face_matches": {
            "type": "array",
            "nullable": true,
            "description": "워크플로 그래프의 얼굴 대조 단계에서 생성된 **얼굴 대조 보고서 배열**입니다. 단일 `face_match` 객체가 아닌 항상 JSON 배열입니다. 하나 이상의 얼굴 대조 단계에서 데이터가 생성될 때까지 `null`입니다. 각 항목은 `node_id`, 기능 수준 `status`, 유사도 `score`, `source_image`, `target_image`, `warnings[]`를 포함한 전체 보고서입니다.",
            "items": {
              "type": "object",
              "description": "얼굴 대조 보고서 1건 — 전체 보고서입니다.",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "이 보고서를 생성한 얼굴 대조 단계의 워크플로 그래프 노드 ID입니다."
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ],
                  "description": "이 얼굴 대조 단계의 기능 수준 상태입니다. 최상위 세션 `status`와는 독립적입니다. 개별 기능이 `In Review` 상태로 유지되는 동안에도 세션이 전체 결정에 도달할 수 있습니다."
                },
                "score": {
                  "type": "number",
                  "description": "얼굴 대조의 신뢰도 점수"
                },
                "source_image_session_id": {
                  "type": "string",
                  "format": "uuid",
                  "nullable": true,
                  "description": "원본(참조) 인물 사진이 저장된 세션 id입니다. 생체 인증 흐름에서 이는 세션 자체의 id입니다(제출된 인물 사진은 새 세션 아래에 저장됨). 원본 이미지가 동일한 세션의 신분증 인물 사진인 경우 `null`입니다."
                },
                "source_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "비교에 사용된 소스 이미지의 URL"
                },
                "target_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "비교에 사용된 대상 이미지의 URL"
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "이 경고를 생성한 기능입니다. 이 값은 경고가 속한 기능 블록을 식별합니다. 각 모듈의 경고 배열은 일반적으로 해당 모듈과 일치하는 값을 사용하지만(예: `phone_verifications[].warnings` 내부의 `PHONE`), 결정 payload의 모든 기능 경고에 대해서는 위의 enum이 기준이 됩니다."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "이 경고를 생성한 워크플로 그래프 노드 ID"
                      }
                    }
                  },
                  "description": "얼굴 대조 인증 경고"
                },
                "face_coverage": {
                  "type": "object",
                  "nullable": true,
                  "description": "촬영된 이미지에서 눈, 입, 얼굴이 가려져 있는지 여부입니다. `GET /v3/session/{sessionId}/decision/`에서만 반환되며, webhook payload에는 포함되지 않습니다. 가림 판독 결과가 없는 경우 `null`입니다.",
                  "properties": {
                    "eyes": {
                      "type": "object",
                      "properties": {
                        "covered": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "calibrated": {
                          "type": "boolean",
                          "nullable": true,
                          "description": "`false`는 판독 결과가 참고용 증거로만 사용되며 이에 따라 작동하는 경고가 없음을 의미합니다."
                        },
                        "visibility_score": {
                          "type": "number",
                          "nullable": true
                        }
                      }
                    },
                    "mouth": {
                      "type": "object",
                      "properties": {
                        "covered": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "calibrated": {
                          "type": "boolean",
                          "nullable": true,
                          "description": "`false`는 판독 결과가 참고용 증거로만 사용되며 이에 따라 작동하는 경고가 없음을 의미합니다."
                        },
                        "visibility_score": {
                          "type": "number",
                          "nullable": true
                        }
                      }
                    },
                    "face": {
                      "type": "object",
                      "properties": {
                        "covered": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "calibrated": {
                          "type": "boolean",
                          "nullable": true,
                          "description": "`false`는 판독 결과가 참고용 증거로만 사용되며 이에 따라 작동하는 경고가 없음을 의미합니다."
                        },
                        "visibility_score": {
                          "type": "number",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "phone_verifications": {
            "type": "array",
            "nullable": true,
            "description": "**전화번호 인증 보고서 배열** — 단일 `phone` 객체가 아닌 항상 JSON 배열입니다. 하나 이상의 전화번호 단계에서 데이터가 생성될 때까지 `null`입니다. 각 항목은 `node_id`, 기능 수준 `status`, 전화번호 및 국가 메타데이터, `lifecycle[]`, `matches[]`, `warnings[]`를 포함한 전체 보고서입니다.",
            "items": {
              "type": "object",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "워크플로 그래프에서 이 전화번호 단계의 고유 식별자입니다."
                },
                "status": {
                  "type": "string",
                  "description": "이 전화번호 인증 단계의 기능 수준 상태입니다. 최상위 세션 `status`와는 독립적입니다. 개별 기능이 `In Review` 상태로 유지되는 동안에도 세션이 전체 결정에 도달할 수 있습니다.",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Expired"
                  ]
                },
                "phone_number_prefix": {
                  "type": "string",
                  "description": "국가 전화번호 접두사"
                },
                "phone_number": {
                  "type": "string",
                  "description": "국가 접두사 없는 전화번호"
                },
                "full_number": {
                  "type": "string",
                  "description": "국가 접두사가 포함된 전체 전화번호"
                },
                "country_code": {
                  "type": "string",
                  "description": "두 글자 국가 코드(ISO 3166-1 alpha-2)"
                },
                "country_name": {
                  "type": "string",
                  "description": "전체 국가명"
                },
                "carrier": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "통신사 이름"
                    },
                    "type": {
                      "type": "string",
                      "description": "전화 회선 유형(모바일, 유선 등)"
                    }
                  }
                },
                "is_disposable": {
                  "type": "boolean",
                  "description": "전화번호가 일회용 서비스의 번호인지 여부"
                },
                "is_virtual": {
                  "type": "boolean",
                  "description": "전화번호가 가상 번호인지 여부"
                },
                "verification_method": {
                  "type": "string",
                  "description": "전화번호 인증에 사용된 방식"
                },
                "verification_attempts": {
                  "type": "integer",
                  "description": "수행된 인증 시도 횟수"
                },
                "verified_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "전화번호가 인증된 시점의 타임스탬프"
                },
                "lifecycle": {
                  "type": "array",
                  "description": "전화번호 인증 수명 주기의 시간순 이벤트 목록입니다.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string"
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "details": {
                        "type": "object",
                        "nullable": true,
                        "description": "이벤트 관련 payload입니다. 발송 이벤트는 `status`, `reason`, `channel`, `actual_channel`을 포함하고, 전송 이벤트는 `channel`, `status`를 포함하며, 코드 확인 이벤트는 `code_tried`, `status`를 포함하고, 최종 상태 이벤트는 `reason`을 포함합니다(보고할 이유가 없는 경우(예: `PHONE_VERIFICATION_APPROVED`) `null`).",
                        "properties": {
                          "status": {
                            "type": "string"
                          },
                          "reason": {
                            "type": "string",
                            "nullable": true
                          },
                          "channel": {
                            "type": "string",
                            "nullable": true
                          },
                          "actual_channel": {
                            "type": "string",
                            "nullable": true
                          },
                          "code_tried": {
                            "type": "string"
                          }
                        }
                      },
                      "fee": {
                        "type": "number"
                      }
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "description": "전화번호 인증과 관련된 경고 목록",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "이 경고를 생성한 기능입니다. 이 값은 경고가 속한 기능 블록을 식별합니다. 각 모듈의 경고 배열은 일반적으로 해당 모듈과 일치하는 값을 사용하지만(예: `phone_verifications[].warnings` 내부의 `PHONE`), 결정 payload의 모든 기능 경고에 대해서는 위의 enum이 기준이 됩니다."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "이 경고를 생성한 워크플로 그래프 노드 ID"
                      }
                    }
                  }
                },
                "matches": {
                  "type": "array",
                  "description": "이 전화번호에 대해 발견된 일치 항목입니다. 각 일치 항목에는 `source`가 있습니다. `session`(애플리케이션 내의 다른 인증 세션이 동일한 번호와 일치함, `session_id`/`session_number`/`vendor_data`/`verification_date`와 함께 반환됨) 또는 `list_entry`(해당 번호가 조직에서 관리하는 허용/차단 목록에 있음 — `/management-api/lists/overview` 참조). 세션 간 일치 항목은 서로 다른 `vendor_data`를 사용하며 최대 5개로 제한됩니다.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true
                      },
                      "session_number": {
                        "type": "integer",
                        "nullable": true
                      },
                      "vendor_data": {
                        "type": "string",
                        "nullable": true
                      },
                      "verification_date": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                      },
                      "phone_number": {
                        "type": "string"
                      },
                      "status": {
                        "type": "string",
                        "nullable": true
                      },
                      "is_blocklisted": {
                        "type": "boolean"
                      },
                      "api_service": {
                        "type": "string",
                        "nullable": true
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "session",
                          "list_entry"
                        ],
                        "description": "이 일치 항목의 출처입니다. `session`은 애플리케이션의 다른 인증 세션이 이 값과 일치했음을 의미합니다. `list_entry`는 조직에서 관리하는 목록(허용 목록/차단 목록)과 값이 일치했음을 의미합니다. 해당 목록을 관리하는 방법은 `/management-api/lists/overview`의 관리 API 목록 개요를 참조하십시오."
                      }
                    }
                  }
                },
                "phone_intelligence": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PhoneIntelligence"
                    }
                  ],
                  "description": "전화번호 인텔리전스 신호입니다. 이 번호에 대해 전화번호 인텔리전스 애드온이 실행된 경우에만 존재합니다."
                },
                "phone_social": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PhoneSocialFootprint"
                    }
                  ],
                  "description": "전화번호의 소셜 풋프린트입니다. 해당 번호에 대해 소셜 풋프린트 애드온이 실행된 경우에만 존재합니다."
                }
              }
            }
          },
          "email_verifications": {
            "type": "array",
            "nullable": true,
            "description": "**이메일 인증 보고서 배열** — 단일 `email` 객체가 아닌 항상 JSON 배열입니다. 하나 이상의 이메일 단계에서 데이터가 생성될 때까지 `null`입니다. 각 항목은 `node_id`, 기능 수준 `status`, 이메일 주소, 유출 데이터, `lifecycle[]`, `matches[]`, `warnings[]`를 포함한 전체 보고서입니다.",
            "items": {
              "type": "object",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "워크플로 그래프에서 이 이메일 단계의 고유 식별자입니다."
                },
                "status": {
                  "type": "string",
                  "description": "이 이메일 인증 단계의 기능 수준 상태입니다. 최상위 세션 `status`와는 독립적입니다. 개별 기능이 `In Review` 상태로 유지되는 동안에도 세션이 전체 결정에 도달할 수 있습니다.",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Expired"
                  ]
                },
                "email": {
                  "type": "string",
                  "description": "인증 중인 이메일 주소"
                },
                "is_breached": {
                  "type": "boolean",
                  "description": "알려진 데이터 침해 건에서 이메일이 발견되었는지 여부를 나타냅니다"
                },
                "breaches": {
                  "type": "array",
                  "description": "이 이메일이 발견된 알려진 유출 건 목록",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string",
                        "description": "침해 사건의 이름"
                      },
                      "domain": {
                        "type": "string",
                        "description": "침해 사고의 영향을 받은 도메인"
                      },
                      "logo_path": {
                        "type": "string",
                        "description": "침해된 서비스 로고의 URL"
                      },
                      "breach_date": {
                        "type": "string",
                        "format": "date",
                        "description": "위반이 발생한 날짜"
                      },
                      "description": {
                        "type": "string",
                        "description": "위반에 대한 설명"
                      },
                      "is_verified": {
                        "type": "boolean",
                        "description": "유출 검증 여부"
                      },
                      "data_classes": {
                        "type": "array",
                        "description": "유출 사건에서 노출된 데이터 유형",
                        "items": {
                          "type": "string"
                        }
                      },
                      "breach_emails_count": {
                        "type": "integer",
                        "description": "유출 피해를 입은 이메일 주소 수"
                      }
                    }
                  }
                },
                "is_disposable": {
                  "type": "boolean",
                  "description": "이메일이 일회용 제공업체에서 생성되었는지 여부를 나타냅니다"
                },
                "is_undeliverable": {
                  "type": "boolean",
                  "description": "이메일 주소의 전송 가능 여부를 나타냅니다"
                },
                "verification_attempts": {
                  "type": "integer",
                  "description": "이 이메일에 대한 인증 시도 횟수"
                },
                "verified_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "이메일이 인증된 시점의 타임스탬프"
                },
                "warnings": {
                  "type": "array",
                  "description": "이메일 인증과 관련된 경고 목록",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "이 경고를 생성한 기능입니다. 이 값은 경고가 속한 기능 블록을 식별합니다. 각 모듈의 경고 배열은 일반적으로 해당 모듈과 일치하는 값을 사용하지만(예: `phone_verifications[].warnings` 내부의 `PHONE`), 결정 payload의 모든 기능 경고에 대해서는 위의 enum이 기준이 됩니다."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "이 경고를 생성한 워크플로 그래프 노드 ID"
                      }
                    }
                  }
                },
                "lifecycle": {
                  "type": "array",
                  "description": "이메일 인증 수명 주기의 시간순 이벤트 목록입니다.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string"
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "details": {
                        "type": "object",
                        "nullable": true,
                        "description": "이벤트 관련 payload입니다. 발송 이벤트는 `status`, `reason`을 포함하고, 코드 확인 이벤트는 `code_tried`, `status`를 포함하며, 최종 상태 이벤트는 `reason`을 포함합니다(보고할 이유가 없는 경우(예: `EMAIL_VERIFICATION_APPROVED`) `null`).",
                        "properties": {
                          "status": {
                            "type": "string"
                          },
                          "reason": {
                            "type": "string",
                            "nullable": true
                          },
                          "code_tried": {
                            "type": "string"
                          }
                        }
                      },
                      "fee": {
                        "type": "number"
                      }
                    }
                  }
                },
                "matches": {
                  "type": "array",
                  "description": "이 이메일 주소에 대해 발견된 일치 항목입니다. 각 일치 항목에는 `source`가 있습니다. `session`(애플리케이션 내의 다른 인증 세션이 동일한 이메일과 일치함, `session_id`/`session_number`/`vendor_data`/`verification_date`와 함께 반환됨) 또는 `list_entry`(해당 이메일이 조직에서 관리하는 허용/차단 목록에 있음 — `/management-api/lists/overview` 참조). 세션 간 일치 항목은 서로 다른 `vendor_data`를 사용하며 최대 5개로 제한됩니다.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true
                      },
                      "session_number": {
                        "type": "integer",
                        "nullable": true
                      },
                      "vendor_data": {
                        "type": "string",
                        "nullable": true
                      },
                      "verification_date": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                      },
                      "email": {
                        "type": "string",
                        "format": "email"
                      },
                      "status": {
                        "type": "string",
                        "nullable": true
                      },
                      "is_blocklisted": {
                        "type": "boolean"
                      },
                      "api_service": {
                        "type": "string",
                        "nullable": true
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "session",
                          "list_entry"
                        ],
                        "description": "이 일치 항목의 출처입니다. `session`은 애플리케이션의 다른 인증 세션이 이 값과 일치했음을 의미합니다. `list_entry`는 조직에서 관리하는 목록(허용 목록/차단 목록)과 값이 일치했음을 의미합니다. 해당 목록을 관리하는 방법은 `/management-api/lists/overview`의 관리 API 목록 개요를 참조하십시오."
                      }
                    }
                  }
                },
                "email_intelligence": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailIntelligence"
                    }
                  ],
                  "description": "이메일 인텔리전스 신호입니다. 이 주소에 대해 이메일 인텔리전스 애드온이 실행된 경우에만 표시됩니다."
                },
                "email_social": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailSocialFootprint"
                    }
                  ],
                  "description": "주소의 소셜 풋프린트입니다. 해당 주소에 대해 소셜 풋프린트 애드온이 실행된 경우에만 존재합니다."
                }
              }
            }
          },
          "poa_verifications": {
            "type": "array",
            "nullable": true,
            "description": "**주소 증명(POA) 보고서 배열** — 단일 `poa` 객체가 아닌 항상 JSON 배열입니다. 하나 이상의 POA 단계에서 데이터가 생성될 때까지 `null`입니다. 각 항목은 `node_id`, 기능 수준 `status`, 문서 파일 URL, 발급자, 날짜, 파싱된 주소, `warnings[]`를 포함한 전체 보고서입니다.",
            "items": {
              "type": "object",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "워크플로 그래프 내 이 주소 증명 단계의 고유 식별자입니다."
                },
                "status": {
                  "type": "string",
                  "description": "이 주소 증명 단계의 기능 수준 상태입니다. 최상위 세션 `status`와는 독립적입니다. 개별 기능이 `In Review` 상태로 유지되는 동안에도 세션이 전체 결정에 도달할 수 있습니다.",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ]
                },
                "document_file": {
                  "type": "string",
                  "format": "uri",
                  "description": "주소 증명 문서의 URL"
                },
                "issuing_state": {
                  "type": "string",
                  "description": "발급 국가의 두 글자 국가 코드"
                },
                "document_type": {
                  "type": "string",
                  "description": "주소 증명 문서 유형"
                },
                "document_subtype": {
                  "type": "string",
                  "nullable": true,
                  "description": "감지된 경우 해당 `document_type` 내에서 주소 증명(POA) 문서의 보다 구체적인 분류입니다. 그렇지 않은 경우 `null`입니다."
                },
                "document_language": {
                  "type": "string",
                  "description": "문서의 언어 코드"
                },
                "document_metadata": {
                  "type": "object",
                  "properties": {
                    "file_size": {
                      "type": "integer",
                      "description": "문서 크기"
                    },
                    "content_type": {
                      "type": "string",
                      "description": "문서의 콘텐츠 유형"
                    },
                    "creation_date": {
                      "type": "string",
                      "format": "date",
                      "description": "문서가 생성된 날짜"
                    },
                    "modified_date": {
                      "type": "string",
                      "format": "date",
                      "description": "문서가 수정된 날짜"
                    },
                    "overlay_manipulation": {
                      "type": "object",
                      "nullable": true,
                      "description": "오버레이 텍스트 조작 의심에 대한 PDF 포렌식 분석입니다. 오버레이 조작 증거가 발견되지 않았거나 문서가 PDF가 아닌 경우 null입니다.",
                      "properties": {
                        "detected": {
                          "type": "boolean",
                          "description": "오버레이 텍스트 조작 흔적이 감지되었는지 여부입니다."
                        },
                        "analyzed": {
                          "type": "boolean",
                          "description": "PDF를 분석할 수 있었는지 여부입니다."
                        },
                        "analysis_incomplete": {
                          "type": "boolean",
                          "description": "파일 전체를 확인할 수 없는 경우에만 존재하며 참(true)입니다. 확인된 부분은 가능한 범위에서 그 결과를 유지하고, 문서는 검증되지 않은 텍스트 대체 경고를 표시합니다."
                        },
                        "signals": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "duplicate_font_subset 또는 glyph_fragmentation과 같이 감지된 포렌식 신호입니다."
                        },
                        "manipulated_regions": {
                          "type": "array",
                          "description": "PDF 페이지 좌표 기준 위변조 의심 영역입니다.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "page": {
                                "type": "integer"
                              },
                              "x": {
                                "type": "number"
                              },
                              "y": {
                                "type": "number"
                              },
                              "width": {
                                "type": "number"
                              },
                              "height": {
                                "type": "number"
                              },
                              "page_width": {
                                "type": "number"
                              },
                              "page_height": {
                                "type": "number"
                              }
                            }
                          }
                        }
                      }
                    },
                    "creator": {
                      "type": "string",
                      "nullable": true,
                      "description": "문서 메타데이터에 기록된 생성자 애플리케이션입니다."
                    },
                    "producer": {
                      "type": "string",
                      "nullable": true,
                      "description": "PDF 메타데이터에 기록된 생성 소프트웨어입니다."
                    },
                    "software": {
                      "type": "string",
                      "nullable": true,
                      "description": "파일 메타데이터에 기록된 편집/처리 소프트웨어입니다."
                    },
                    "encryption": {
                      "type": "string",
                      "nullable": true,
                      "description": "문서가 암호화된 경우, 문서의 암호화 방식입니다."
                    },
                    "is_signed": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "PDF에 전자 서명이 포함되어 있는지 여부입니다."
                    },
                    "is_tampered": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "서명 검증 결과 서명 후 파일이 수정되었는지 여부입니다."
                    },
                    "signature_info": {
                      "type": "object",
                      "nullable": true,
                      "description": "디지털 서명의 세부 정보(있는 경우)입니다."
                    },
                    "exif_original_date": {
                      "type": "string",
                      "nullable": true,
                      "description": "이미지 업로드의 EXIF 원본 촬영 날짜입니다."
                    },
                    "exif_digitized_date": {
                      "type": "string",
                      "nullable": true,
                      "description": "이미지 업로드의 EXIF 디지털화 날짜입니다."
                    },
                    "processed_by_known_editor": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "파일 메타데이터에 알려진 문서 편집기로 처리된 이력이 표시되는지 여부입니다."
                    },
                    "has_different_creation_mod_date": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "생성 날짜와 수정 날짜가 서로 다른지 여부(일반적인 위변조 신호)입니다."
                    }
                  },
                  "description": "업로드된 POA 문서에서 추출된 파일 포렌식 메타데이터입니다. 항상 아래 키가 포함됩니다(해당하지 않는 경우 값은 `null`입니다. 예: PDF의 EXIF 날짜). 메타데이터를 추출할 수 없는 경우 `null`입니다.",
                  "nullable": true
                },
                "issuer": {
                  "type": "string",
                  "description": "문서 발급 기관 이름"
                },
                "issue_date": {
                  "type": "string",
                  "format": "date",
                  "description": "문서가 발급된 날짜"
                },
                "expiration_date": {
                  "type": "string",
                  "format": "date",
                  "nullable": true,
                  "description": "문서의 만료일(해당하는 경우)"
                },
                "poa_address": {
                  "type": "string",
                  "description": "주소 증명 문서의 원시 주소"
                },
                "poa_formatted_address": {
                  "type": "string",
                  "description": "주소 증명 문서의 포맷된 주소입니다."
                },
                "poa_parsed_address": {
                  "type": "object",
                  "properties": {
                    "address_type": {
                      "type": "string",
                      "description": "주소 유형(도로명, 거리 등)"
                    },
                    "street_1": {
                      "type": "string",
                      "description": "주 도로 주소"
                    },
                    "street_2": {
                      "type": "string",
                      "nullable": true,
                      "description": "보조 도로 주소"
                    },
                    "city": {
                      "type": "string",
                      "description": "도시 이름"
                    },
                    "region": {
                      "type": "string",
                      "description": "지역 또는 주 이름"
                    },
                    "country": {
                      "type": "string",
                      "description": "두 글자 국가 코드"
                    },
                    "postal_code": {
                      "type": "string",
                      "description": "우편번호"
                    },
                    "document_location": {
                      "type": "object",
                      "properties": {
                        "latitude": {
                          "type": "number",
                          "description": "위도 좌표"
                        },
                        "longitude": {
                          "type": "number",
                          "description": "경도 좌표"
                        }
                      }
                    }
                  }
                },
                "name_on_document": {
                  "type": "string",
                  "nullable": true,
                  "description": "이름 일치 확인에 사용되는 POA 문서에서 추출한 계정 보유자/수신인 성명입니다. 이름을 추출할 수 없는 경우 `null`입니다."
                },
                "name_match_score_expected_details": {
                  "type": "number",
                  "nullable": true,
                  "description": "`name_on_document`와 세션 생성 시 제공된 예상 이름 간의 유사도 점수(0-100)입니다. 어느 한쪽이 누락된 경우 `null`입니다."
                },
                "name_match_score_id_verification": {
                  "type": "number",
                  "nullable": true,
                  "description": "`name_on_document`와 신분증 인증 단계에서 추출된 이름 간의 유사도 점수(0-100)입니다. 어느 한쪽이 누락된 경우 `null`입니다."
                },
                "expected_details_address": {
                  "type": "string",
                  "nullable": true,
                  "description": "인증을 위한 예상 원시 주소"
                },
                "expected_details_formatted_address": {
                  "type": "string",
                  "nullable": true,
                  "description": "인증을 위한 서식화된 예상 주소"
                },
                "expected_details_parsed_address": {
                  "type": "object",
                  "description": "인증을 위한 파싱된 예상 주소 세부정보"
                },
                "extra_fields": {
                  "type": "object",
                  "description": "문서에서 추출한 추가 은행 및 연락처 세부 정보입니다.",
                  "properties": {
                    "bank_account_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "bank_iban": {
                      "type": "string",
                      "nullable": true
                    },
                    "bank_sort_code": {
                      "type": "string",
                      "nullable": true
                    },
                    "bank_routing_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "bank_swift_bic": {
                      "type": "string",
                      "nullable": true
                    },
                    "bank_branch_name": {
                      "type": "string",
                      "nullable": true
                    },
                    "bank_branch_address": {
                      "type": "string",
                      "nullable": true
                    },
                    "document_phone_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "additional_names": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "extra_files": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "format": "uri"
                  },
                  "description": "추가 주소 증명 파일"
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "이 경고를 생성한 기능입니다. 이 값은 경고가 속한 기능 블록을 식별합니다. 각 모듈의 경고 배열은 일반적으로 해당 모듈과 일치하는 값을 사용하지만(예: `phone_verifications[].warnings` 내부의 `PHONE`), 결정 payload의 모든 기능 경고에 대해서는 위의 enum이 기준이 됩니다."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "이 경고를 생성한 워크플로 그래프 노드 ID"
                      }
                    }
                  }
                },
                "detected_codes": {
                  "type": "array",
                  "description": "문서의 처리된 모든 페이지에서 감지된 QR 코드 및 바코드입니다. 발견되지 않으면 비어 있습니다. 위치는 식별되었으나 디코딩할 수 없는 QR 코드는 `parsed_payload: null`을 가집니다.",
                  "items": {
                    "$ref": "#/components/schemas/DocumentAIDetectedCode"
                  }
                },
                "address_validation": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/AddressValidationResult"
                    }
                  ],
                  "nullable": true,
                  "description": "이 주소 증명에 기재된 주소에 대한 주소 검증입니다. 문서에서 읽은 주소의 존재 여부 및 정규화된 형태를 나타냅니다(이후 `poa_address`를 수정해도 다시 실행되지 않음). 이 주소 증명 단계에서 주소 검증 추가 기능이 활성화되어 있고 업로드된 파일이 문서 확인을 통과한 경우에 제공되며, 그렇지 않으면 `null`입니다."
                }
              }
            }
          },
          "document_ai_documents": {
            "type": "array",
            "nullable": true,
            "description": "**워크플로 노드별로 그룹화된 Document AI 보고서** — 항상 JSON 배열이며 단일 객체가 아닙니다. 최소 하나의 Document AI 단계에서 데이터가 생성될 때까지 `null`입니다. `session_kind = user`일 때만 표시됩니다. 각 항목은 집계된 `status`, `node_id`, 문서별 결과(구성된 필드 키를 키로 하는 추출된 데이터)의 `items[]` 배열, 그리고 `warnings`를 포함하는 노드 그룹입니다.",
            "items": {
              "type": "object",
              "description": "워크플로 노드별로 그룹화된 Document AI 결과입니다.",
              "properties": {
                "status": {
                  "type": "string",
                  "description": "해당 노드의 집계된 Document AI 상태로, `items[]`에서 롤업됩니다.",
                  "enum": [
                    "Approved",
                    "Declined",
                    "In Review",
                    "Not Finished"
                  ]
                },
                "node_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "워크플로 그래프 내 이 Document AI 단계의 고유 식별자입니다."
                },
                "items": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "uuid": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "node_id": {
                        "type": "string",
                        "nullable": true,
                        "description": "이 문서를 생성한 워크플로 그래프 노드입니다."
                      },
                      "document_key": {
                        "type": "string",
                        "description": "이 파일이 해당하는 구성된 Document AI 문서의 키입니다."
                      },
                      "original_filename": {
                        "type": "string",
                        "nullable": true,
                        "description": "사용자가 업로드한 파일 이름입니다."
                      },
                      "file_size": {
                        "type": "integer",
                        "nullable": true,
                        "description": "바이트 단위의 파일 크기입니다."
                      },
                      "file_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "업로드된 파일로 연결되는 유효 기간이 짧은 사전 서명된 링크입니다."
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "Approved",
                          "Declined",
                          "In Review",
                          "Not Finished"
                        ],
                        "description": "문서별 Document AI 상태입니다."
                      },
                      "extracted_data": {
                        "type": "object",
                        "additionalProperties": true,
                        "nullable": true,
                        "description": "Document AI가 추출한 값으로, 구성된 필드 `key`를 키로 합니다. 각 값은 문자열, 숫자 또는 `null`입니다."
                      },
                      "detected_codes": {
                        "type": "array",
                        "description": "처리된 모든 페이지에서 감지된 QR 코드 및 바코드입니다. 발견되지 않으면 비어 있습니다. 위치는 식별되었으나 디코딩할 수 없는 QR 코드는 `parsed_payload: null`을 가집니다.",
                        "items": {
                          "$ref": "#/components/schemas/DocumentAIDetectedCode"
                        }
                      },
                      "fields": {
                        "type": "array",
                        "description": "이 문서에 대해 구성된 추출 필드입니다.",
                        "items": {
                          "type": "object",
                          "properties": {
                            "key": {
                              "type": "string",
                              "description": "`extracted_data`에서 키로 사용되는 안정적인 필드 키입니다."
                            },
                            "name": {
                              "type": "string",
                              "description": "사람이 읽기 쉬운 필드 이름입니다."
                            },
                            "instruction": {
                              "type": "string",
                              "description": "모델에 표시되는 추출 지침입니다."
                            },
                            "type": {
                              "type": "string",
                              "enum": [
                                "text",
                                "number",
                                "date"
                              ],
                              "description": "추출된 필드의 예상 값 유형입니다."
                            },
                            "required": {
                              "type": "boolean",
                              "description": "Whether this field is required."
                            }
                          }
                        }
                      },
                      "document_metadata": {
                        "type": "object",
                        "nullable": true,
                        "description": "업로드된 문서에서 추출된 파일 포렌식 메타데이터(예: `is_tampered`)입니다. 아무것도 추출할 수 없는 경우 `null`입니다."
                      },
                      "cross_check_result": {
                        "type": "object",
                        "nullable": true,
                        "description": "추출된 문서 필드와 다른 세션 데이터 간의 상호 대조 결과입니다. 교차 검사가 수행되지 않은 경우 `null`입니다."
                      },
                      "created_at": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "nullable": true,
                  "items": {
                    "type": "object"
                  },
                  "description": "이 Document AI 노드에 대해 발생한 경고 로그입니다."
                }
              }
            }
          },
          "questionnaire_responses": {
            "type": "array",
            "nullable": true,
            "description": "**설문지 응답 보고서 배열** — 단일 `questionnaire` 객체가 아닌 항상 JSON 배열입니다. 하나 이상의 설문지 단계에서 데이터가 생성될 때까지 `null`입니다. 각 항목은 `node_id`, 설문지 메타데이터, 양식 요소가 포함된 섹션, 사용자의 답변을 포함한 전체 보고서입니다.",
            "items": {
              "type": "object",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "워크플로 그래프에서 이 설문지 단계의 고유 식별자입니다."
                },
                "questionnaire_id": {
                  "type": "string",
                  "description": "설문지의 고유 식별자"
                },
                "title": {
                  "type": "string",
                  "description": "설문지 제목"
                },
                "description": {
                  "type": "string",
                  "description": "설문지에 대한 설명"
                },
                "languages": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "지원되는 언어"
                },
                "default_language": {
                  "type": "string",
                  "description": "기본 언어"
                },
                "is_active": {
                  "type": "boolean",
                  "description": "설문지가 활성 상태인지 여부"
                },
                "is_simple_questionnaire": {
                  "type": "boolean",
                  "description": "설문지가 단순 선형 양식(분기 그래프 없음)인지 여부입니다."
                },
                "questionnaire_group_id": {
                  "type": "string",
                  "format": "uuid",
                  "nullable": true,
                  "description": "버전 간에 유지되는 설문지 그룹의 고유 식별자입니다."
                },
                "version": {
                  "type": "integer",
                  "nullable": true,
                  "description": "응답한 설문지의 버전 번호입니다."
                },
                "published_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true,
                  "description": "이 설문지 버전이 게시된 타임스탬프입니다."
                },
                "sections": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "title": {
                        "type": "string",
                        "nullable": true,
                        "description": "섹션 제목"
                      },
                      "description": {
                        "type": "string",
                        "nullable": true,
                        "description": "섹션 설명"
                      },
                      "items": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "uuid": {
                              "type": "string",
                              "description": "항목의 고유 식별자"
                            },
                            "value": {
                              "type": "string",
                              "nullable": true,
                              "description": "설문지 그래프 내 이 양식 요소의 고정 노드 식별자입니다."
                            },
                            "element_type": {
                              "type": "string",
                              "description": "설문지 요소의 유형"
                            },
                            "is_required": {
                              "type": "boolean",
                              "description": "항목이 필수인지 여부"
                            },
                            "title": {
                              "type": "string",
                              "description": "항목의 제목"
                            },
                            "description": {
                              "type": "string",
                              "nullable": true,
                              "description": "항목에 대한 설명"
                            },
                            "placeholder": {
                              "type": "string",
                              "nullable": true,
                              "description": "플레이스홀더 텍스트"
                            },
                            "choices": {
                              "type": "array",
                              "nullable": true,
                              "items": {
                                "type": "object",
                                "properties": {
                                  "label": {
                                    "type": "string"
                                  },
                                  "value": {
                                    "type": "string"
                                  },
                                  "requires_text_input": {
                                    "type": "boolean",
                                    "description": "이 선택지에 추가 텍스트 입력이 필요한지 여부",
                                    "nullable": true
                                  }
                                },
                                "required": [
                                  "label",
                                  "value"
                                ]
                              },
                              "description": "드롭다운 또는 단일 선택 요소의 선택지"
                            },
                            "max_files": {
                              "type": "integer",
                              "description": "허용되는 최대 파일 수",
                              "nullable": true
                            },
                            "answer": {
                              "type": "object",
                              "description": "항목에 대해 제공된 답변",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "text": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "files": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  },
                                  "nullable": true
                                }
                              }
                            },
                            "required_if": {
                              "type": "object",
                              "nullable": true,
                              "description": "해당 요소가 특정 답변에만 필요한 경우의 조건부 필수 규칙입니다."
                            },
                            "repeatable_config": {
                              "type": "object",
                              "nullable": true,
                              "description": "해당하는 경우, 반복 가능한 요소 그룹에 대한 구성입니다."
                            }
                          },
                          "required": [
                            "uuid",
                            "value",
                            "element_type",
                            "is_required",
                            "title"
                          ]
                        }
                      }
                    }
                  }
                },
                "status": {
                  "type": "string",
                  "description": "설문지의 상태"
                }
              }
            }
          },
          "bank_verifications": {
            "type": "array",
            "nullable": true,
            "description": "사용자 인증 및 기업 확인(KYB)에 대한 은행 인증 단계별 한 항목씩의 은행 인증 결과입니다. 단계에서 결과가 생성될 때까지 `null`입니다. 각 항목의 `method`는 계좌가 어떻게 인증되었는지를 나타냅니다: `open_banking`(은행 로그인) 또는 `account_lookup`(계좌 조회), 또는 `statement`나 `microdeposits` 대체 수단, 그리고 시도가 평가되기 전에 사용자가 은행 없이 계속 진행한 경우(`continued_without_bank`) `none`입니다. [은행 인증 방법](/ko/core-technology/bank-verification/verification-methods)을 참조하십시오.",
            "items": {
              "$ref": "#/components/schemas/BankVerificationResult"
            }
          },
          "signatures": {
            "type": "array",
            "description": "사용자 인증 및 기업 확인(KYB)에 대한 서명자 및 서명 단계별 전자 서명 결과 항목입니다. 워크플로에 전자 서명 단계가 있는 경우에만 표시되며, 서명자가 해당 단계에 도달할 때까지는 빈 배열입니다. [전자 서명 보고서](/ko/core-technology/electronic-signature/report-electronic-signature)를 참조하세요.",
            "items": {
              "$ref": "#/components/schemas/SignatureResult"
            }
          },
          "aml_screenings": {
            "type": "array",
            "nullable": true,
            "description": "**AML 스크리닝 보고서 배열** — 단일 `aml` 객체가 아닌 항상 JSON 배열입니다. 하나 이상의 AML 단계에서 데이터가 생성될 때까지 `null`입니다. 각 항목은 `node_id`, 기능 수준 `status`, `total_hits`, `entity_type`, `hits[]`, `score`, `screened_data`, `is_ongoing_monitoring_enabled` 및 `warnings[]`를 포함한 전체 보고서입니다.",
            "items": {
              "$ref": "#/components/schemas/AMLScreening"
            }
          },
          "ip_analyses": {
            "type": "array",
            "nullable": true,
            "description": "**기기 및 IP 분석 보고서 배열** — 단일 `ip_analysis` 객체가 아닌 항상 JSON 배열입니다. 하나 이상의 IP 분석 단계에서 데이터가 생성될 때까지 `null`입니다. 각 항목은 `node_id`, 기능 수준 `status`, IP 및 지리적 위치 데이터, 기기 핑거프린트, `warnings[]`를 포함한 전체 보고서입니다. 중복된 `(node_id, ip_address, device_fingerprint)` 항목은 서버 측에서 중복 제거됩니다.",
            "items": {
              "type": "object",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "워크플로 그래프 내 이 기기 및 IP 분석 단계의 고유 식별자입니다."
                },
                "status": {
                  "type": "string",
                  "description": "이 기기 및 IP 분석 항목의 기능 수준 상태입니다. 최상위 세션 `status`와는 독립적입니다. 개별 기능이 `In Review` 상태로 유지되는 동안에도 세션이 전체 결정에 도달할 수 있습니다.",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ]
                },
                "device_brand": {
                  "type": "string",
                  "description": "사용된 기기의 브랜드"
                },
                "device_model": {
                  "type": "string",
                  "description": "사용된 기기의 모델"
                },
                "browser_family": {
                  "type": "string",
                  "description": "사용된 브라우저 계열"
                },
                "os_family": {
                  "type": "string",
                  "description": "운영체제 제품군"
                },
                "platform": {
                  "type": "string",
                  "description": "플랫폼 유형(mobile, desktop 등)입니다."
                },
                "device_fingerprint": {
                  "type": "string",
                  "nullable": true,
                  "description": "고유 기기 핑거프린트 식별자"
                },
                "ip_country": {
                  "type": "string",
                  "description": "IP에서 감지된 국가"
                },
                "ip_country_code": {
                  "type": "string",
                  "description": "IP에서 가져온 두 글자 국가 코드"
                },
                "ip_state": {
                  "type": "string",
                  "description": "IP에서 감지된 주/지역"
                },
                "ip_city": {
                  "type": "string",
                  "description": "IP에서 감지된 도시"
                },
                "latitude": {
                  "type": "number",
                  "description": "IP 위치의 위도 좌표"
                },
                "longitude": {
                  "type": "number",
                  "description": "IP 위치의 경도 좌표"
                },
                "ip_address": {
                  "type": "string",
                  "description": "주소"
                },
                "isp": {
                  "type": "string",
                  "nullable": true,
                  "description": "인터넷 서비스 제공업체"
                },
                "organization": {
                  "type": "string",
                  "nullable": true,
                  "description": "IP와 연결된 조직"
                },
                "is_vpn_or_tor": {
                  "type": "boolean",
                  "description": "IP가 VPN 또는 Tor 네트워크에서 유래했는지 여부"
                },
                "is_data_center": {
                  "type": "boolean",
                  "description": "IP가 데이터 센터에서 유래했는지 여부"
                },
                "time_zone": {
                  "type": "string",
                  "description": "IP에서 감지된 시간대"
                },
                "time_zone_offset": {
                  "type": "string",
                  "description": "시간대 오프셋"
                },
                "ip": {
                  "type": "object",
                  "description": "이 항목의 IP 지리적 위치 및 신분증 문서 주소와 주소 증명(POA) 문서 주소까지의 대권 거리(km)입니다. 양쪽 중 어느 한쪽이라도 확인할 수 있는 위치가 없는 경우 거리는 `null`입니다.",
                  "properties": {
                    "location": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "latitude": {
                          "type": "number",
                          "example": 41.2706327
                        },
                        "longitude": {
                          "type": "number",
                          "example": 1.9770097
                        }
                      },
                      "description": "좌표이며, 사용할 수 없는 경우 `null`입니다."
                    },
                    "distance_from_id_document": {
                      "type": "number",
                      "nullable": true,
                      "example": 23.4
                    },
                    "distance_from_poa_document": {
                      "type": "number",
                      "nullable": true,
                      "example": 12.3
                    }
                  }
                },
                "id_document": {
                  "type": "object",
                  "description": "신분증 문서 주소에서 추출된 위치 및 IP 지리적 위치와 주소 증명(POA) 문서 주소까지의 거리(km)입니다. 문서 주소를 지오코딩할 수 없는 경우 `location`은 `null`입니다.",
                  "properties": {
                    "location": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "latitude": {
                          "type": "number",
                          "example": 41.2706327
                        },
                        "longitude": {
                          "type": "number",
                          "example": 1.9770097
                        }
                      },
                      "description": "좌표이며, 사용할 수 없는 경우 `null`입니다."
                    },
                    "distance_from_ip": {
                      "type": "number",
                      "nullable": true,
                      "example": 23.4
                    },
                    "distance_from_poa_document": {
                      "type": "number",
                      "nullable": true,
                      "example": 18.7
                    }
                  }
                },
                "poa_document": {
                  "type": "object",
                  "description": "주소 증명 문서에서 추출된 위치 및 IP 지리적 위치와 신분증 문서 주소까지의 거리(km)입니다. 세션에 POA 단계가 없거나 주소를 지오코딩할 수 없는 경우 `location`은 `null`입니다.",
                  "properties": {
                    "location": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "latitude": {
                          "type": "number",
                          "example": 41.2706327
                        },
                        "longitude": {
                          "type": "number",
                          "example": 1.9770097
                        }
                      },
                      "description": "좌표이며, 사용할 수 없는 경우 `null`입니다."
                    },
                    "distance_from_ip": {
                      "type": "number",
                      "nullable": true,
                      "example": 12.3
                    },
                    "distance_from_id_document": {
                      "type": "number",
                      "nullable": true,
                      "example": 18.7
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "이 경고를 생성한 기능입니다. 이 값은 경고가 속한 기능 블록을 식별합니다. 각 모듈의 경고 배열은 일반적으로 해당 모듈과 일치하는 값을 사용하지만(예: `phone_verifications[].warnings` 내부의 `PHONE`), 결정 payload의 모든 기능 경고에 대해서는 위의 enum이 기준이 됩니다."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "이 경고를 생성한 워크플로 그래프 노드 ID"
                      }
                    }
                  }
                },
                "matches": {
                  "type": "array",
                  "description": "이 항목의 IP 주소 또는 기기 식별자에 대해 발견된 교차 세션 일치 항목입니다. 모든 일치 항목은 동일한 값을 공유하는 애플리케이션 내의 다른 인증 세션(`source`는 항상 `session`)이며, 항상 현재 세션과 다른 벤더 사용자 / `vendor_data`에 속하고 수집기당 최대 5개로 제한됩니다(`device_fingerprint`는 독립적으로 제한되는 두 개의 수집기를 합산하므로 최대 10개 항목 가능). 각 항목에는 `match_source`, `confidence`, `match_mode`, `device_info`, `location_info`가 포함되며, `recovery_similarity`, `tls_ja4_corroborated`, `recovery_gate_reason` 키는 `match_source`가 `recovered_high`인 경우에만 존재합니다.",
                  "items": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "일치하는 세션의 세션 ID입니다."
                      },
                      "session_number": {
                        "type": "integer",
                        "description": "일치하는 세션의 순차 번호입니다."
                      },
                      "vendor_data": {
                        "type": "string",
                        "nullable": true,
                        "description": "일치하는 세션의 `vendor_data`입니다. 현재 세션의 벤더 사용자와 항상 다릅니다."
                      },
                      "verification_date": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "일치하는 세션의 생성 일자(`YYYY-MM-DDTHH:MM:SSZ`)."
                      },
                      "match_type": {
                        "type": "string",
                        "enum": [
                          "ip_address",
                          "device_fingerprint"
                        ],
                        "description": "일치가 IP 주소 또는 기기 핑거프린트를 기준으로 이루어졌는지 여부"
                      },
                      "match_source": {
                        "type": "string",
                        "enum": [
                          "ip_address",
                          "persistent_id",
                          "legacy_fp",
                          "recovered_high"
                        ],
                        "description": "이 일치 항목에 도달한 방식: `ip_address`(공유 IP 주소 — 기기 신원 주장이 아닌 네트워크 공동 배치), `persistent_id`(저장된 정확한 지속적 기기 식별자), `legacy_fp`(레거시 `didit-fp-*` 기기 지문 해시), 또는 `recovered_high`(신뢰도 높은 유사 지문 복구 적중). 신뢰도가 낮은 복구 후보는 위험 경고로만 표시되며 이 배열에는 절대 포함되지 않습니다."
                      },
                      "matched_value": {
                        "type": "string",
                        "nullable": true,
                        "description": "일치한 값입니다. 공유 IP 주소, 영구 기기 식별자 또는 레거시 지문 해시이며, `recovered_high`의 경우 복구된 기기의 UUID입니다."
                      },
                      "status": {
                        "type": "string",
                        "description": "일치하는 세션의 수명 주기 상태입니다."
                      },
                      "is_blocklisted": {
                        "type": "boolean",
                        "description": "일치하는 값이 차단 목록에 있는지 여부입니다. 기기/IP 일치의 경우 현재 항상 `false`입니다."
                      },
                      "api_service": {
                        "type": "string",
                        "nullable": true,
                        "description": "일치하는 세션의 독립형 API 서비스입니다. 워크플로 세션의 경우 `null`입니다."
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "session"
                        ],
                        "description": "기기/IP 일치의 경우 항상 `session`입니다. 모든 일치 항목은 애플리케이션의 또 다른 인증 세션입니다."
                      },
                      "device_info": {
                        "type": "object",
                        "description": "일치하는 세션에서 확인된 기기 세부 정보입니다.",
                        "properties": {
                          "device_brand": {
                            "type": "string",
                            "nullable": true
                          },
                          "device_model": {
                            "type": "string",
                            "nullable": true
                          },
                          "browser_family": {
                            "type": "string",
                            "nullable": true
                          },
                          "os_family": {
                            "type": "string",
                            "nullable": true
                          },
                          "platform": {
                            "type": "string",
                            "nullable": true
                          },
                          "device_fingerprint": {
                            "type": "string",
                            "nullable": true
                          }
                        }
                      },
                      "location_info": {
                        "type": "object",
                        "description": "일치하는 세션에서 확인된 네트워크 및 지리적 위치 세부 정보입니다.",
                        "properties": {
                          "ip_address": {
                            "type": "string",
                            "nullable": true
                          },
                          "ip_country": {
                            "type": "string",
                            "nullable": true
                          },
                          "ip_country_code": {
                            "type": "string",
                            "nullable": true
                          },
                          "ip_state": {
                            "type": "string",
                            "nullable": true
                          },
                          "ip_city": {
                            "type": "string",
                            "nullable": true
                          },
                          "is_vpn_or_tor": {
                            "type": "boolean"
                          },
                          "is_data_center": {
                            "type": "boolean"
                          }
                        }
                      },
                      "confidence": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1,
                        "description": "서버 측 식별 신뢰도로, `1 - P(false positive)`로 계산됩니다. 결정론적 일치(`persistent_id` 또는 하드웨어 기반 `recovered_high`)의 경우 `1.0`, `legacy_fp`의 경우 `0.5`, `ip_address`(동일 위치 기반에 불과함)의 경우 `0.0`이며, 확률적 복구 일치의 경우 확증에 따라 조정된 `1.0` 미만의 값입니다(TLS JA4 지문과 IP 국가가 독립적으로 일치할수록 높아짐)."
                      },
                      "match_mode": {
                        "type": "string",
                        "enum": [
                          "deterministic",
                          "probabilistic",
                          "co_occurrence"
                        ],
                        "description": "일치의 근거 클래스: `deterministic`(물리적 기기간 충돌할 수 없는 정확한 저장 식별자 또는 하드웨어 기반 식별자), `probabilistic`(퍼지 핑거프린트 근거), 또는 `co_occurrence`(공유 네트워크 전용, 기기 신원 주장 없음)."
                      },
                      "recovery_similarity": {
                        "type": "number",
                        "description": "핑거프린트 복구 일치의 코사인 유사도로, 소수점 4자리로 반올림됩니다. `match_source`가 `recovered_high`인 경우에만 제공됩니다."
                      },
                      "tls_ja4_corroborated": {
                        "type": "boolean",
                        "description": "두 관측값의 TLS JA4 핑거프린트가 일치하는지 여부(브라우저가 스푸핑할 수 없는 서버 관측 신호)입니다. `match_source`가 `recovered_high`인 경우에만 제공됩니다."
                      },
                      "recovery_gate_reason": {
                        "type": "string",
                        "description": "복구 일치가 오탐 하드 게이트를 통과한 이유입니다: `hardware_root_match`(하드웨어 기반 기기 식별자가 정확히 일치함) 또는 프로브 전용 증거를 허용하는 구성의 경우 `exact_composite_plus_<n>_families` / `very_high_similarity_plus_<n>_families`입니다. `match_source`가 `recovered_high`일 때만 존재합니다."
                      }
                    }
                  }
                },
                "browser_version": {
                  "type": "string",
                  "nullable": true
                },
                "os_version": {
                  "type": "string",
                  "nullable": true
                },
                "user_agent": {
                  "type": "string",
                  "nullable": true,
                  "description": "브라우저의 사용자 에이전트 문자열입니다."
                },
                "accept_language": {
                  "type": "string",
                  "nullable": true,
                  "description": "브라우저가 전송한 `Accept-Language` 헤더입니다."
                },
                "session_identifier": {
                  "type": "string",
                  "nullable": true,
                  "description": "인증이 실행된 브라우징 세션의 식별자입니다."
                },
                "session_age_ms": {
                  "type": "integer",
                  "nullable": true,
                  "description": "해당 단계가 실행되었을 때 해당 브라우징 세션의 경과 시간(밀리초)입니다."
                },
                "coords_accuracy": {
                  "type": "number",
                  "nullable": true,
                  "description": "기기가 보고한 좌표의 정확도 반경(미터 단위)입니다."
                },
                "raw_device_data": {
                  "type": "object",
                  "nullable": true,
                  "additionalProperties": true,
                  "description": "해당 단계를 위해 수집된 원시 기기 신호입니다."
                }
              }
            }
          },
          "geolocation_checks": {
            "type": "array",
            "nullable": true,
            "description": "위치 검증 단계마다 하나씩 생성되며, 각 단계에서 수락된 시도를 나타내는 **위치 검증 결과 배열**입니다. 위치 검증 단계에서 데이터가 생성될 때까지 `null`입니다. 동일한 단계의 이전 시도는 `geolocation_attempts`에 포함됩니다.",
            "items": {
              "$ref": "#/components/schemas/GeolocationCheck"
            }
          },
          "geolocation_attempts": {
            "type": "array",
            "nullable": true,
            "description": "이 세션의 모든 위치 인증 단계 시도 내역(오래된 순)입니다. 재제출로 대체된 시도는 제외됩니다. 응답 속성을 통해 `geolocation_checks`를 보류하는 워크플로는 이 목록도 보류합니다.",
            "items": {
              "$ref": "#/components/schemas/GeolocationAttempt"
            }
          },
          "database_validations": {
            "type": "array",
            "nullable": true,
            "description": "**데이터베이스 검증 보고서 배열** — 단일 `database_validation` 객체가 아닌 항상 JSON 배열입니다. 하나 이상의 DB 검증 단계에서 데이터가 생성될 때까지 `null`입니다. 각 항목은 `node_id`, 기능 수준의 `status`, `screened_data`, 서비스별 `validations[]`(각각 레지스트리 `source_data` 포함), `warnings[]`를 포함하는 전체 보고서입니다. `screened_data` 및 `source_data` 필드는 국가별로 다릅니다:\n\n**ARG (아르헨티나)**: screened_data: {document_number, selfie, gender, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, date_of_birth, date_of_death, tax_id, tax_id_type, face_match_score, sit_1_since, banks, last_position, highest_position, rejected_checks}. RENAPER 생체 얼굴 대조 검증을 사용합니다. 신분증(예: 운전면허증)에 성별이 명시되어 있지 않은 경우 얼굴 분석 또는 이름에서 자동으로 추론됩니다.\n\n**BOL (볼리비아)**: screened_data: {document_number, date_of_birth, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, date_of_birth, gender}\n\n**BRA (브라질)**: screened_data: {tax_number, first_name, last_name, date_of_birth}. 일치하는 CPF 조회가 성공한 경우 source_data에는 항상 {identification_number, first_name, last_name, date_of_birth, lgpd_minor, minor_under_18, minor_under_16}이 포함됩니다. 성인 조회가 성공하면 해당 플래그는 false로 설정됩니다. Receita Federal Consulta CPF 서비스는 LGPD로 인해 보류된 데이터와 함께 HTTP 422(18세 미만 미성년자) 또는 451(16세 미만 미성년자)을 반환할 수 있습니다. 이러한 경우 source_data는 미성년자 플래그를 적절하게 true로 설정하고, 업스트림 HTTP 상태를 포함하며, 필드 수준 검증은 no_match가 됩니다. 전체 코드 목록은 데이터베이스 검증 결과 코드 참조 문서의 브라질 섹션을 확인하세요.\n\n**CHL (칠레)**: screened_data: {personal_number, first_name, last_name, date_of_birth}. source_data: {identification_number, first_name, last_name, date_of_birth, gender}\n\n**COL (콜롬비아)**: screened_data: {document_number, document_type, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, date_of_birth, document_type}\n\n**CRI (코스타리카)**: screened_data: {personal_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name}\n\n**DOM (도미니카 공화국)**: screened_data: {personal_number}. source_data: {identification_number} (유효/무효만 반환)\n\n**ECU (에콰도르)**: screened_data: {personal_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, street, formatted_address, gender, nationality, education, marital_status, spouse, mother_name, father_name, profession}\n\n**ESP (스페인)**: screened_data: {personal_number, document_type, expiration_date, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, document_type, expiration_date}\n\n**GTM (과테말라)**: screened_data: {document_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name}\n\n**HND (온두라스)**: screened_data: {document_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name}\n\n**MEX (멕시코)**: screened_data: {personal_number (CURP), first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, date_of_birth, gender, nationality, curp_status, state_of_birth, doc_probatorio, registration_year, registration_state, registration_municipality, num_acta, crip, issuing_state_code, foreign_registry_number, folio_carta, folio_certificado}. RENAPO 주민등록 레지스트리를 사용합니다. 멕시코의 경우 추가적인 개별 검증으로 별도의 INE 유효성 검사 서비스도 이용할 수 있습니다.\n\n**PAN (파나마)**: screened_data: {personal_number, selfie}. source_data: {identification_number}. SIB 생체 인식 검증을 사용합니다\n\n**PER (페루)**: screened_data: {personal_number (DNI), first_name, last_name}. source_data: {identification_number, first_name, last_name, paternal_name, maternal_name, verification_number, verification_letter}\n\n**PRY (파라과이)**: screened_data: {document_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name}\n\n**SLV (엘살바도르)**: screened_data: {document_number, date_of_birth, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name}\n\n**URY (우루과이)**: screened_data: {personal_number, date_of_birth, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name}\n\n**VEN (베네수엘라)**: screened_data: {document_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, gender, date_of_birth, document_type}",
            "items": {
              "type": "object",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "워크플로 그래프에서 이 데이터베이스 검증 단계의 고유 식별자입니다."
                },
                "issuing_state": {
                  "type": "string",
                  "description": "정부/등록부 출처를 조회한 국가의 ISO 3166-1 alpha-3 코드입니다(예: `BRA`, `MEX`, `ESP`, `NGA`, `IDN`). 데이터베이스 검증은 아메리카, 유럽, 아프리카, 중동 및 아시아 태평양 지역의 60+개국과 글로벌 다국가 출처를 지원합니다. 지원 범위는 정기적으로 확장되므로 이 값을 고정된 enum이 아닌 개방형 집합으로 처리하십시오."
                },
                "validation_type": {
                  "type": "string",
                  "enum": [
                    "one_by_one",
                    "two_by_two",
                    "not_enabled"
                  ],
                  "description": "결과가 검증된 방식입니다. `one_by_one`(단일 서비스 결과), `two_by_two`(두 개 이상의 개별 서비스에서 식별 번호를 독립적으로 완전 일치 확인), 또는 `not_enabled`(사용 가능한 일치 항목을 생성한 서비스가 없을 때 유지됨). 이 값은 절대 `null`이 될 수 없습니다. 전용 생체 인식 2x2 검증 모드는 현재 `ECU` 및 `PER`에서 지원됩니다."
                },
                "screened_data": {
                  "type": "object",
                  "description": "검증에 사용된 입력 데이터입니다. 필드는 국가별로 다르며, 국가별 형식은 데이터베이스 검증 문서(`/core-technology/database-validation/overview`)를 참고하세요.",
                  "properties": {
                    "last_name": {
                      "type": "string"
                    },
                    "first_name": {
                      "type": "string"
                    },
                    "tax_number": {
                      "type": "string",
                      "description": "브라질: CPF(11자리)"
                    },
                    "personal_number": {
                      "type": "string",
                      "description": "칠레: RUT, 도미니카 공화국: Cédula(11자리), 에콰도르: Cédula(10자리), 스페인: DNI/NIE, 멕시코: CURP(18자), 페루: DNI(8자리), 우루과이: CI"
                    },
                    "document_number": {
                      "type": "string",
                      "description": "ARG: DNI, BOL: CI, COL: Cédula, GTM: DPI, HND: DNI, PAN: Cédula, PRY: CI, SLV: DUI, VEN: Cédula"
                    },
                    "date_of_birth": {
                      "type": "string",
                      "format": "date"
                    },
                    "document_type": {
                      "type": "string",
                      "description": "COL: CC/CE/TI/NIT, ESP: ID/PASSPORT"
                    },
                    "expiration_date": {
                      "type": "string",
                      "format": "date",
                      "description": "ESP에 필수"
                    }
                  }
                },
                "validations": {
                  "type": "array",
                  "description": "검증 payload를 반환한 등기 서비스당 항목 1개입니다. 각 항목은 서비스(`service_id`, `service_name`)를 식별하며 필드별 `validation` 비교 결과, 보고된 경우 서비스 `outcome_code` / `outcome_detail`, `source_data` 내 정규화된 등기 기록을 포함합니다.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "service_id": {
                        "type": "string",
                        "description": "이 검증 결과를 생성한 등기소 서비스의 식별자입니다.",
                        "example": "bra_cpf"
                      },
                      "service_name": {
                        "type": "string",
                        "description": "등록부 서비스의 사람이 읽기 쉬운 이름입니다.",
                        "example": "Brazil - CPF status check"
                      },
                      "validation": {
                        "type": "object",
                        "description": "필드 검증 결과입니다.",
                        "properties": {
                          "full_name": {
                            "type": "string",
                            "description": "성명 일치 결과입니다(예: 'full_match', 'partial_match', 'no_match')."
                          },
                          "date_of_birth": {
                            "type": "string",
                            "description": "생년월일 일치 결과입니다."
                          },
                          "identification_number": {
                            "type": "string",
                            "description": "식별 번호 일치 결과입니다."
                          }
                        }
                      },
                      "outcome_code": {
                        "type": "string",
                        "nullable": true,
                        "description": "등기부 조회의 기계 판독 가능한 결과(예: `MATCH`, `NO_MATCH`, `PARTIAL_MATCH`, `INCONCLUSIVE`, 소스별 고유 코드). 서비스에서 보고할 때 표시됩니다."
                      },
                      "outcome_detail": {
                        "type": "string",
                        "nullable": true,
                        "description": "서비스에서 제공하는 경우 `outcome_code`에 대한 사람이 읽기 쉬운 설명입니다."
                      },
                      "source_data": {
                        "type": "object",
                        "description": "정부 데이터베이스에서 반환된 데이터입니다. 공통 필드: identification_number, first_name, last_name, full_name, date_of_birth, gender. 국가별 추가 필드: BRA는 CPF 일치에 성공한 경우 항상 lgpd_minor, minor_under_18, minor_under_16을 포함하며, LGPD에 따라 CPF 데이터가 보류될 때 업스트림 HTTP 상태 코드(HTTP 422/451)도 포함합니다. ECU는 street, formatted_address, nationality, education, marital_status, spouse, mother_name, father_name, profession을 추가합니다. PER는 paternal_name, maternal_name, verification_number, verification_letter를 추가합니다. ESP는 document_type, expiration_date를 추가합니다. VEN/COL은 document_type을 추가합니다.",
                        "additionalProperties": true
                      }
                    }
                  }
                },
                "errors": {
                  "type": "array",
                  "description": "검증 중 등기부 서비스에서 반환된 오류이며, 각각 이를 생성한 `service_id` 태그가 지정됩니다. **오류가 없는 경우 이 키는 완전히 생략됩니다.**",
                  "items": {
                    "type": "object",
                    "description": "있는 그대로 전개된 업스트림 서비스의 오류 객체(키는 서비스마다 다르며 일반적으로 메시지/코드 및 공급자별 세부 정보 포함) 및 오류가 발생한 서비스를 식별하는 `service_id`입니다.",
                    "properties": {
                      "service_id": {
                        "type": "string",
                        "nullable": true,
                        "description": "오류가 발생한 등기소 서비스의 식별자입니다."
                      }
                    },
                    "additionalProperties": true
                  }
                },
                "match_type": {
                  "type": "string",
                  "enum": [
                    "no_match",
                    "partial_match",
                    "full_match"
                  ],
                  "nullable": true,
                  "description": "조회된 서비스 전반에 걸친 종합 일치 결과입니다. 검증이 평가될 때까지 `null`입니다."
                },
                "status": {
                  "type": "string",
                  "description": "이 데이터베이스 검증의 기능 수준 상태입니다. 최상위 세션 `status`와는 독립적입니다. 개별 기능이 `In Review` 상태로 유지되는 동안에도 세션이 전체 결정에 도달할 수 있습니다.",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ]
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "이 경고를 생성한 기능입니다. 이 값은 경고가 속한 기능 블록을 식별합니다. 각 모듈의 경고 배열은 일반적으로 해당 모듈과 일치하는 값을 사용하지만(예: `phone_verifications[].warnings` 내부의 `PHONE`), 결정 payload의 모든 기능 경고에 대해서는 위의 enum이 기준이 됩니다."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "이 경고를 생성한 워크플로 그래프 노드 ID"
                      }
                    }
                  },
                  "description": "데이터베이스 검증과 관련된 경고입니다."
                }
              }
            }
          },
          "database_validation_not_performed_reason": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "설정된 데이터베이스 검증에서 결과가 생성되지 않은 이유로, `{code, message}`와 컨텍스트 필드로 표시됩니다. 해당 단계가 포함된 워크플로에서 `database_validations`가 `null`일 때만 표시되므로, \"등기소가 일치함을 확인함\"과 \"아무것도 실행되지 않음\"을 구분할 수 있습니다. 그 외의 경우에는 `null`입니다.",
            "properties": {
              "code": {
                "type": "string",
                "description": "기계 판독 가능한 고정 사유입니다."
              },
              "message": {
                "type": "string",
                "description": "사람이 읽기 쉬운 설명입니다."
              }
            }
          },
          "reviews": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "user": {
                  "type": "string",
                  "description": "누가 검토를 수행했는지 나타냅니다. 일반적으로 콘솔 검토자의 식별자(이메일)이지만, API 키로 상태를 업데이트한 경우 값은 `\"API Client\"`이고 행위자를 확인할 수 없는 경우 `\"Unknown\"`이므로 이 필드를 이메일 주소로 파싱하지 마십시오."
                },
                "new_status": {
                  "type": "string"
                },
                "comment": {
                  "type": "string"
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "assignee": {
            "type": "object",
            "nullable": true,
            "description": "세션이 할당된 콘솔 검토자 또는 담당자가 없는 경우 `null`입니다.",
            "properties": {
              "email": {
                "type": "string",
                "format": "email"
              },
              "assigned_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          },
          "waiting_since": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "세션이 검토 대기를 시작한 시점입니다. 세션이 `In Review` 상태이고 애플리케이션에서 검토 기한을 설정한 경우가 아니면 `null`입니다."
          },
          "sla_due_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "검토가 완료되어야 하는 시점입니다. 세션이 `In Review` 상태이고 애플리케이션에서 검토 기한을 설정한 경우가 아니면 `null`입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "세션이 생성된 타임스탬프(ISO 8601, UTC)입니다."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "이 세션이 만료되도록 예약된 타임스탬프입니다. 생성 시 만료가 구성되었거나(`Approved` 상태가 되어 KYC 만료 계산이 트리거된 경우) 사용자 인증(KYC) 세션에 설정됩니다. 만료가 구성되지 않은 세션 및 만료를 사용하지 않는 종류(예: `expires_at`을 수신하지 않은 기업 확인(KYB) 세션)의 경우 `null`입니다."
          },
          "registry_checks": {
            "type": "array",
            "nullable": true,
            "description": "법인 등기부 확인입니다. `session_kind = business`인 경우에만 존재합니다. 각 항목은 전체 법인 등기부 payload를 포함합니다.",
            "items": {
              "type": "object",
              "description": "법인 등기부 확인 1건 — 소유 구조 및 경고 정보가 보강된 전체 법인 등기부 payload입니다. `session_kind = business`인 경우에만 표시됩니다.",
              "properties": {
                "status": {
                  "type": "string",
                  "description": "기능 라이프사이클 상태."
                },
                "node_id": {
                  "type": "string",
                  "nullable": true
                },
                "data_resolved": {
                  "type": "boolean"
                },
                "company": {
                  "type": "object",
                  "description": "기업의 전체 등기부 payload(등기부 기록과 사용자가 제공하거나 콘솔에서 수정한 데이터를 병합한 결과)입니다.",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "node_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "status": {
                      "type": "string"
                    },
                    "registry_status": {
                      "type": "string",
                      "nullable": true
                    },
                    "data_resolved": {
                      "type": "boolean"
                    },
                    "company_name": {
                      "type": "string"
                    },
                    "registration_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "country_code": {
                      "type": "string",
                      "description": "설립 국가(ISO 3166-1 alpha-2, 예: `GB`, `DE`, `US`)."
                    },
                    "region": {
                      "type": "string",
                      "nullable": true,
                      "description": "해당하는 경우 ISO 3166-2 행정 구역 코드(예: 미국 주의 경우 `CA`, `NY`)입니다."
                    },
                    "company_type": {
                      "type": "string",
                      "nullable": true
                    },
                    "incorporation_date": {
                      "type": "string",
                      "format": "date",
                      "nullable": true
                    },
                    "registered_address": {
                      "type": "string",
                      "nullable": true
                    },
                    "tax_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "risk_level": {
                      "type": "string",
                      "enum": [
                        "LOW",
                        "MEDIUM",
                        "HIGH"
                      ],
                      "nullable": true
                    },
                    "verification_status": {
                      "type": "string",
                      "nullable": true
                    },
                    "is_from_registry": {
                      "type": "boolean"
                    },
                    "fetch_status": {
                      "type": "string",
                      "nullable": true
                    },
                    "alternative_names": {
                      "type": "string",
                      "nullable": true,
                      "description": "보고된 경우, 텍스트 형태의 대체명, 상호명, 이전 명칭 또는 원어 기업명입니다."
                    },
                    "nature_of_business": {
                      "type": "string",
                      "nullable": true
                    },
                    "registered_capital": {
                      "type": "string",
                      "nullable": true
                    },
                    "registered_capital_amount": {
                      "type": "string",
                      "format": "decimal",
                      "nullable": true,
                      "description": "법인 등기부 제출 서류에서 파싱된 십진수 문자열 형식의 등록/자본금 금액(예: `\"100.00\"`)입니다. 제공되지 않는 경우 `null`입니다."
                    },
                    "registered_capital_currency": {
                      "type": "string",
                      "nullable": true,
                      "description": "`registered_capital_amount`의 ISO 4217 통화 코드(예: `\"GBP\"`)입니다. 사용할 수 없는 경우 `null`입니다."
                    },
                    "website": {
                      "type": "string",
                      "nullable": true
                    },
                    "email": {
                      "type": "string",
                      "format": "email",
                      "nullable": true
                    },
                    "phone": {
                      "type": "string",
                      "nullable": true
                    },
                    "legal_entity_identifier": {
                      "type": "string",
                      "nullable": true
                    },
                    "location_of_registration": {
                      "type": "string",
                      "nullable": true
                    },
                    "vat_number": {
                      "type": "string",
                      "nullable": true,
                      "description": "호스팅 법인 등기부 단계에서 수집되었거나 이후 편집된 EU VAT 번호입니다."
                    },
                    "vat_validation_status": {
                      "type": "string",
                      "enum": [
                        "valid",
                        "invalid",
                        "format_valid",
                        "invalid_format",
                        "could_not_validate",
                        "not_applicable"
                      ],
                      "description": "법인 등기부 제출 시 VAT 번호 또는 없는 경우 `tax_number`를 검증한 결과입니다. `valid` / `invalid`: 해당 국가의 공식 등기소(EU VIES, 노르웨이, 스위스, 브라질, 콜롬비아, 코스타리카, 에콰도르, 파라과이, 폴란드의 경우 국내 VAT 등록부 포함)에서 결정됩니다. `format_valid` / `invalid_format`: 등기소 조회가 불가능한 경우 해당 국가의 서식 및 체크 디지트 규칙에 따라 결정됩니다. `could_not_validate`: 등기소를 사용할 수 없습니다. `not_applicable`: 번호가 없거나, 등기소나 규칙이 없는 국가이거나, 샌드박스 세션인 경우입니다."
                    },
                    "vat_validated_number": {
                      "type": "string",
                      "nullable": true,
                      "description": "출처가 인식하는 확인된 번호입니다(예: 프랑스 SIREN 또는 네덜란드 RSIN에서 파생된 VAT 번호). 확인이 실행되지 않은 경우 `null`입니다."
                    },
                    "vat_validation_source": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "eu_vies",
                        "pl_vat_white_list",
                        "no_brreg",
                        "ch_uid_register",
                        "br_receita_federal",
                        "co_rues",
                        "cr_hacienda",
                        "ec_sri",
                        "py_dnit",
                        "format_rules",
                        null
                      ],
                      "description": "`vat_validation_status`를 결정한 소스(공식 등기소 또는 `format_rules`)입니다. 검사가 실행되지 않은 경우 `null`입니다."
                    },
                    "vat_validated_name": {
                      "type": "string",
                      "nullable": true,
                      "description": "해당 번호를 검증한 소스에 등록된 이름(소스를 통해 공개된 경우). 상태가 `valid`인 경우에만 설정됩니다."
                    },
                    "vat_validated_address": {
                      "type": "string",
                      "nullable": true,
                      "description": "번호를 검증한 출처에 등록된 주소(출처에서 제공하는 경우)입니다. 상태가 `valid`일 때만 설정됩니다."
                    },
                    "vat_checked_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "검사의 타임스탬프입니다. 검사가 실행되지 않은 경우 `null`입니다."
                    },
                    "financial_summary": {
                      "type": "object",
                      "nullable": true
                    },
                    "officers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string"
                          },
                          "designation": {
                            "type": "string",
                            "nullable": true
                          },
                          "role": {
                            "type": "string",
                            "nullable": true
                          },
                          "nationality": {
                            "type": "string",
                            "nullable": true
                          },
                          "is_active": {
                            "type": "boolean"
                          },
                          "kyc_status": {
                            "type": "string",
                            "enum": [
                              "Approved",
                              "Declined",
                              "Pending"
                            ],
                            "nullable": true
                          },
                          "kyc_session_url": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true
                          },
                          "first_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "등기소에서 명시적으로 보고한 경우의 이름입니다. 성명에서 유추되지 않습니다."
                          },
                          "last_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "등기소에서 명시적으로 보고한 경우의 성입니다."
                          },
                          "address": {
                            "type": "string",
                            "nullable": true,
                            "description": "등기부에서 보고된 임원 주소입니다."
                          },
                          "appointment_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "임원이 선임된 날짜입니다.",
                            "format": "date"
                          },
                          "termination_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "보고된 경우 선임 종료일입니다.",
                            "format": "date"
                          },
                          "date_of_birth": {
                            "type": "string",
                            "nullable": true,
                            "description": "법인 등기부에 보고된 전체 생년월일입니다. 출생 연도 또는 월만 알려진 경우 null입니다.",
                            "format": "date"
                          },
                          "date_of_birth_year": {
                            "type": "integer",
                            "nullable": true,
                            "minimum": 1,
                            "maximum": 9999,
                            "description": "전체 날짜를 알 수 없는 경우를 포함하여, 법인 등기부에 보고된 출생 연도입니다."
                          },
                          "date_of_birth_month": {
                            "type": "integer",
                            "nullable": true,
                            "minimum": 1,
                            "maximum": 12,
                            "description": "법인 등기부에 보고된 출생 월입니다. 연도만 알려진 경우 null입니다."
                          }
                        }
                      }
                    },
                    "beneficial_owners": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string"
                          },
                          "first_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "last_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "entity_type": {
                            "type": "string",
                            "enum": [
                              "person",
                              "company"
                            ]
                          },
                          "roles": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "ownership_min_shares": {
                            "type": "string",
                            "nullable": true,
                            "description": "등기소에서 보고한 소유 지분율의 하한값. 자유 형식 문자열(예: `\"25.00\"`, `\"50\"`). 파싱된 숫자 값은 `effective_ownership_percent`를 사용하십시오."
                          },
                          "ownership_max_shares": {
                            "type": "string",
                            "nullable": true,
                            "description": "등기부에서 보고된 소유 구조 비율의 상한입니다. 자유 형식 문자열이며, 파싱된 숫자 값은 `effective_ownership_percent`를 사용하십시오."
                          },
                          "is_active": {
                            "type": "boolean"
                          },
                          "kyc_status": {
                            "type": "string",
                            "enum": [
                              "Approved",
                              "Declined",
                              "Pending"
                            ],
                            "nullable": true
                          },
                          "kyc_session_url": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true
                          },
                          "effective_ownership_percent": {
                            "type": "number",
                            "nullable": true
                          },
                          "company_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "registration_number": {
                            "type": "string",
                            "nullable": true
                          },
                          "country_of_birth": {
                            "type": "string",
                            "nullable": true
                          },
                          "email": {
                            "type": "string",
                            "nullable": true
                          },
                          "nationality": {
                            "type": "string",
                            "nullable": true
                          },
                          "designation": {
                            "type": "string",
                            "nullable": true
                          },
                          "voting_min_shares": {
                            "type": "string",
                            "nullable": true
                          },
                          "voting_max_shares": {
                            "type": "string",
                            "nullable": true
                          },
                          "date_of_birth": {
                            "type": "string",
                            "nullable": true,
                            "description": "보고된 전체 생년월일입니다.",
                            "format": "date"
                          },
                          "appointment_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "신고된 선임일입니다.",
                            "format": "date"
                          },
                          "shareholding": {
                            "$ref": "#/components/schemas/KYBRegistryShareholding"
                          }
                        }
                      }
                    },
                    "addresses": {
                      "type": "array",
                      "nullable": true,
                      "description": "등기부에 기재된 모든 주소의 표준 형식입니다. 기재된 내용이 없으면 null입니다.",
                      "items": {
                        "$ref": "#/components/schemas/KYBRegistryAddress"
                      }
                    },
                    "industries": {
                      "type": "array",
                      "nullable": true,
                      "description": "등기부에서 기업을 분류하는 표준 형태의 활동입니다. 명시된 활동이 없는 경우 null입니다.",
                      "items": {
                        "$ref": "#/components/schemas/KYBRegistryIndustry"
                      }
                    },
                    "accounts": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "제공되는 경우 법인 등기부 제출 날짜입니다. 연차 보고서 및 주주총회에는 last_annual_return_date 및 last_agm_date를 사용하며, 재무제표와는 구별됩니다."
                    },
                    "registry_data": {
                      "$ref": "#/components/schemas/KYBRegistryData"
                    },
                    "user_provided_data": {
                      "type": "object",
                      "description": "최종 사용자가 확인하거나 수정한 데이터입니다."
                    },
                    "confirmed_by_user_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "last_console_edit_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "is_editable": {
                      "type": "boolean"
                    },
                    "ownership": {
                      "$ref": "#/components/schemas/KYBRegistryOwnership"
                    },
                    "registry_tier": {
                      "type": "string",
                      "nullable": true,
                      "description": "워크플로가 주문한 등기소 등급(`basic`, `shareholders` 또는 `ubo`)입니다. `ownership.tier_requested`에도 포함됩니다."
                    },
                    "registry_tier_delivered": {
                      "type": "string",
                      "nullable": true,
                      "description": "등기부에서 제공되어 결제 청구된 등급입니다. `ownership.tier_delivered`에도 포함됩니다."
                    },
                    "registry_ownership_status": {
                      "type": "string",
                      "nullable": true,
                      "description": "`not_requested`, `pending`, `delivered`, `not_held` 또는 `unavailable`입니다. `ownership.status`에도 포함됩니다."
                    },
                    "registry_monitoring": {
                      "type": "object",
                      "nullable": true,
                      "description": "기업의 최신 등기부 모니터링 정보 또는 존재하지 않는 경우 `null`입니다.",
                      "properties": {
                        "uuid": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string"
                        },
                        "unavailable_reason": {
                          "type": "string",
                          "nullable": true
                        },
                        "enrolled_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "cancelled_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "last_bill_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true
                        },
                        "next_bill_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true
                        },
                        "last_event_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "events_count": {
                          "type": "integer"
                        },
                        "watched_fields": {
                          "description": "모니터가 감시하는 기업 필드입니다."
                        }
                      }
                    }
                  }
                },
                "ownership_structure": {
                  "$ref": "#/components/schemas/KYBOwnershipStructure"
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          },
          "key_people_checks": {
            "type": "array",
            "nullable": true,
            "description": "종합 주요 인물 확인입니다. `session_kind = business`인 경우에만 표시됩니다. 각 항목은 2개 버킷 형태(`registry`, `submitted`, `ubo_kyc_summary`)를 사용합니다.",
            "items": {
              "type": "object",
              "description": "기업의 임원 및 실소유자(UBO)에 대한 종합 점검입니다. `registry` / `submitted` 형식을 사용합니다. session_kind = business인 경우에만 표시됩니다.",
              "properties": {
                "status": {
                  "type": "string"
                },
                "node_id": {
                  "type": "string",
                  "nullable": true
                },
                "registry": {
                  "type": "object",
                  "description": "법인 등기부 조회를 통해 발견된 당사자입니다.",
                  "properties": {
                    "officers": {
                      "type": "array",
                      "description": "등기부 확인을 통해 발견된 임원 목록으로, 각각에 대해 생성된 하위 KYC 세션 및 AML 스크리닝 상태가 포함되어 있습니다.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "등기부에 기록된 임원의 성명입니다."
                          },
                          "designation": {
                            "type": "string",
                            "nullable": true,
                            "description": "등기부상 자유 형식 직책입니다(예: `Director`, `Company Secretary`)."
                          },
                          "role": {
                            "type": "string",
                            "enum": [
                              "director",
                              "non_executive_director",
                              "secretary",
                              "chairman",
                              "ubo",
                              "shareholder",
                              "representative",
                              "founder",
                              "legal_advisor",
                              "authorized_signatory",
                              "trustee",
                              "beneficiary",
                              "settlor",
                              "protector",
                              "company_officer",
                              "investor",
                              "other"
                            ],
                            "description": "정규화된 임원 역할입니다."
                          },
                          "nationality": {
                            "type": "string",
                            "nullable": true
                          },
                          "appointment_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "임원이 선임된 날짜입니다.",
                            "format": "date"
                          },
                          "termination_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "보고된 경우 선임 종료일입니다.",
                            "format": "date"
                          },
                          "is_active": {
                            "type": "boolean"
                          },
                          "address": {
                            "type": "string",
                            "nullable": true,
                            "description": "등기부에서 보고된 임원 주소입니다."
                          },
                          "aml_status": {
                            "type": "string",
                            "enum": [
                              "Not Finished",
                              "Approved",
                              "Declined",
                              "In Review",
                              "Resub Requested"
                            ],
                            "nullable": true,
                            "description": "이 임원에 대해 실행된 AML 스크리닝의 상태입니다. AML 스크리닝이 실행되지 않은 경우 `null`입니다."
                          },
                          "kyc_status": {
                            "type": "string",
                            "enum": [
                              "Not Started",
                              "In Progress",
                              "Approved",
                              "Declined",
                              "In Review",
                              "Expired",
                              "Abandoned",
                              "Kyc Expired",
                              "Resubmitted",
                              "Awaiting User"
                            ],
                            "nullable": true,
                            "description": "이 임원을 위해 생성된 하위 KYC 세션의 원시 라이프사이클 상태입니다. 이는 축소된 승인됨/거부됨/대기 중 세트가 아닌 전체 세션 상태 enum입니다. 하위 KYC 세션이 없으면 `null`입니다."
                          },
                          "kyc_session_url": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true,
                            "description": "하위 KYC 세션의 공유 가능한 URL입니다. 하위 세션이 없으면 `null`입니다."
                          },
                          "kyc_session_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "하위 KYC 세션의 세션 id입니다. 해당 인물의 전체 KYC 보고서를 가져오려면 동일한 결정 endpoint에 전달하십시오. 하위 세션이 없는 경우 `null`입니다."
                          },
                          "verification_workflow_type": {
                            "type": "string",
                            "nullable": true,
                            "description": "하위 세션 워크플로의 기본 워크플로 유형입니다(예: `kyc`). 그래프 기반 워크플로이거나 하위 세션이 없는 경우 `null`입니다."
                          },
                          "verification_workflow_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "자식 세션에서 사용한 워크플로 ID입니다. 자식 세션이 없으면 `null`입니다."
                          },
                          "verification_workflow_label": {
                            "type": "string",
                            "nullable": true,
                            "description": "하위 세션 워크플로의 사람이 읽기 쉬운 라벨입니다. 설정되지 않은 경우 `null`입니다."
                          },
                          "verification_workflow_features": {
                            "type": "array",
                            "nullable": true,
                            "description": "하위 인증 세션의 기능별 진행 상황입니다(예: `[{\"feature\": \"ID_VERIFICATION\", \"status\": \"Approved\"}]`). 하위 세션에 확인할 수 있는 기능 목록이 없으면 `null`입니다.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "feature": {
                                  "type": "string",
                                  "description": "기능 표시 이름(예: `ID_VERIFICATION`, `LIVENESS`, `AML`)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "Not Finished",
                                    "Approved",
                                    "Declined",
                                    "In Review",
                                    "Resub Requested"
                                  ],
                                  "description": "하위 세션 내부의 기능 수준 상태입니다."
                                }
                              }
                            }
                          },
                          "didit_internal_id": {
                            "type": "string",
                            "nullable": true,
                            "description": "하위 세션의 인증된 개인에 대한 고정 내부 식별자입니다. 세션 간 연결에 유용합니다. 하위 세션이 없거나 사용자가 아직 확인되지 않은 경우 `null`입니다."
                          },
                          "kyc_document_type": {
                            "type": "string",
                            "nullable": true,
                            "description": "하위 KYC 세션에 제시된 문서 유형(예: `P`, `ID`, `DL`)입니다. 하위 세션에 신분증 인증 결과가 나올 때까지는 `null`입니다."
                          },
                          "kyc_nationality": {
                            "type": "string",
                            "nullable": true,
                            "description": "하위 KYC 세션의 문서에서 추출한 국적입니다. 사용 가능해질 때까지 `null`입니다."
                          },
                          "kyc_liveness_passed": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "하위 KYC 세션의 라이브니스 검사가 통과되었는지 여부입니다. 라이브니스 검사가 실행되지 않은 경우 `null`입니다."
                          },
                          "kyc_verified_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "하위 KYC 세션이 `Approved` 상태에 도달한 시점입니다. 하위 세션이 다른 상태인 동안에는 `null`입니다."
                          },
                          "kyc_aml_categories": {
                            "type": "object",
                            "nullable": true,
                            "description": "해당 인물의 AML 일치 항목에서 도출된 카테고리별 요약입니다. 일치 항목이 없으면 `null`입니다.",
                            "properties": {
                              "sanctions": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              },
                              "pep": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              },
                              "adverse_media": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              },
                              "warnings": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              }
                            }
                          },
                          "kyc_notification_sent_at": {
                            "type": "string",
                            "nullable": true,
                            "description": "이 인물의 하위 세션에 대해 마지막으로 전송된 인증 초대 알림의 ISO 8601 타임스탬프입니다. 전송된 내역이 없으면 `null`입니다."
                          },
                          "first_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "등기소에서 명시적으로 보고한 경우의 이름입니다. 성명에서 유추되지 않습니다."
                          },
                          "last_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "등기소에서 명시적으로 보고한 경우의 성입니다."
                          },
                          "date_of_birth": {
                            "type": "string",
                            "nullable": true,
                            "description": "법인 등기부에 보고된 전체 생년월일입니다. 출생 연도 또는 월만 알려진 경우 null입니다.",
                            "format": "date"
                          },
                          "date_of_birth_year": {
                            "type": "integer",
                            "nullable": true,
                            "minimum": 1,
                            "maximum": 9999,
                            "description": "전체 날짜를 알 수 없는 경우를 포함하여, 법인 등기부에 보고된 출생 연도입니다."
                          },
                          "date_of_birth_month": {
                            "type": "integer",
                            "nullable": true,
                            "minimum": 1,
                            "maximum": 12,
                            "description": "법인 등기부에 보고된 출생 월입니다. 연도만 알려진 경우 null입니다."
                          }
                        }
                      }
                    },
                    "beneficial_owners": {
                      "type": "array",
                      "description": "등기부 조회를 통해 확인된 실소유자로, 각각에 대해 생성된 하위 KYC 세션 및 AML 스크리닝 상태 정보가 포함됩니다.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "실소유자의 성명(법인 UBO의 경우 회사명)."
                          },
                          "first_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "last_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "date_of_birth": {
                            "type": "string",
                            "nullable": true,
                            "description": "보고된 전체 생년월일입니다.",
                            "format": "date"
                          },
                          "country_of_birth": {
                            "type": "string",
                            "nullable": true
                          },
                          "email": {
                            "type": "string",
                            "nullable": true
                          },
                          "company_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "registration_number": {
                            "type": "string",
                            "nullable": true
                          },
                          "entity_type": {
                            "type": "string",
                            "enum": [
                              "person",
                              "company"
                            ]
                          },
                          "nationality": {
                            "type": "string",
                            "nullable": true
                          },
                          "designation": {
                            "type": "string",
                            "nullable": true
                          },
                          "roles": {
                            "type": "array",
                            "description": "이 소유자가 보유한 역할 이름(예: `[\"ubo\", \"shareholder\"]`).",
                            "items": {
                              "type": "string"
                            }
                          },
                          "ownership_min_shares": {
                            "type": "string",
                            "nullable": true,
                            "description": "등기소에서 보고한 소유 지분율의 하한값. 자유 형식 문자열(예: `\"25\"`, `\"25-50%\"`). 파싱된 숫자 값은 `effective_ownership_percent`를 사용하십시오."
                          },
                          "ownership_max_shares": {
                            "type": "string",
                            "nullable": true,
                            "description": "등기부에서 보고된 소유 구조 비율의 상한입니다. 자유 형식 문자열이며, 파싱된 숫자 값은 `effective_ownership_percent`를 사용하십시오."
                          },
                          "is_active": {
                            "type": "boolean"
                          },
                          "aml_status": {
                            "type": "string",
                            "enum": [
                              "Not Finished",
                              "Approved",
                              "Declined",
                              "In Review",
                              "Resub Requested"
                            ],
                            "nullable": true,
                            "description": "이 실소유자에 대해 실행된 AML 스크리닝의 상태입니다. AML 스크리닝이 실행되지 않은 경우 `null`입니다."
                          },
                          "kyc_status": {
                            "type": "string",
                            "enum": [
                              "Not Started",
                              "In Progress",
                              "Approved",
                              "Declined",
                              "In Review",
                              "Expired",
                              "Abandoned",
                              "Kyc Expired",
                              "Resubmitted",
                              "Awaiting User"
                            ],
                            "nullable": true,
                            "description": "이 실소유자를 위해 생성된 하위 KYC 세션의 원시 라이프사이클 상태입니다. 이는 축소된 승인됨/거부됨/대기 중 세트가 아닌 전체 세션 상태 enum입니다. 하위 KYC 세션이 없으면 `null`입니다."
                          },
                          "kyc_session_url": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true,
                            "description": "하위 KYC 세션의 공유 가능한 URL입니다. 하위 세션이 없으면 `null`입니다."
                          },
                          "kyc_session_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "하위 KYC 세션의 세션 id입니다. 해당 인물의 전체 KYC 보고서를 가져오려면 동일한 결정 endpoint에 전달하십시오. 하위 세션이 없는 경우 `null`입니다."
                          },
                          "verification_workflow_type": {
                            "type": "string",
                            "nullable": true,
                            "description": "하위 세션 워크플로의 기본 워크플로 유형입니다(예: `kyc`). 그래프 기반 워크플로이거나 하위 세션이 없는 경우 `null`입니다."
                          },
                          "verification_workflow_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "자식 세션에서 사용한 워크플로 ID입니다. 자식 세션이 없으면 `null`입니다."
                          },
                          "verification_workflow_label": {
                            "type": "string",
                            "nullable": true,
                            "description": "하위 세션 워크플로의 사람이 읽기 쉬운 라벨입니다. 설정되지 않은 경우 `null`입니다."
                          },
                          "verification_workflow_features": {
                            "type": "array",
                            "nullable": true,
                            "description": "하위 인증 세션의 기능별 진행 상황입니다(예: `[{\"feature\": \"ID_VERIFICATION\", \"status\": \"Approved\"}]`). 하위 세션에 확인할 수 있는 기능 목록이 없으면 `null`입니다.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "feature": {
                                  "type": "string",
                                  "description": "기능 표시 이름(예: `ID_VERIFICATION`, `LIVENESS`, `AML`)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "Not Finished",
                                    "Approved",
                                    "Declined",
                                    "In Review",
                                    "Resub Requested"
                                  ],
                                  "description": "하위 세션 내부의 기능 수준 상태입니다."
                                }
                              }
                            }
                          },
                          "didit_internal_id": {
                            "type": "string",
                            "nullable": true,
                            "description": "하위 세션의 인증된 개인에 대한 고정 내부 식별자입니다. 세션 간 연결에 유용합니다. 하위 세션이 없거나 사용자가 아직 확인되지 않은 경우 `null`입니다."
                          },
                          "kyc_document_type": {
                            "type": "string",
                            "nullable": true,
                            "description": "하위 KYC 세션에 제시된 문서 유형(예: `P`, `ID`, `DL`)입니다. 하위 세션에 신분증 인증 결과가 나올 때까지는 `null`입니다."
                          },
                          "kyc_nationality": {
                            "type": "string",
                            "nullable": true,
                            "description": "하위 KYC 세션의 문서에서 추출한 국적입니다. 사용 가능해질 때까지 `null`입니다."
                          },
                          "kyc_liveness_passed": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "하위 KYC 세션의 라이브니스 검사가 통과되었는지 여부입니다. 라이브니스 검사가 실행되지 않은 경우 `null`입니다."
                          },
                          "kyc_verified_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "하위 KYC 세션이 `Approved` 상태에 도달한 시점입니다. 하위 세션이 다른 상태인 동안에는 `null`입니다."
                          },
                          "kyc_aml_categories": {
                            "type": "object",
                            "nullable": true,
                            "description": "해당 인물의 AML 일치 항목에서 도출된 카테고리별 요약입니다. 일치 항목이 없으면 `null`입니다.",
                            "properties": {
                              "sanctions": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              },
                              "pep": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              },
                              "adverse_media": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              },
                              "warnings": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              }
                            }
                          },
                          "kyc_notification_sent_at": {
                            "type": "string",
                            "nullable": true,
                            "description": "이 인물의 하위 세션에 대해 마지막으로 전송된 인증 초대 알림의 ISO 8601 타임스탬프입니다. 전송된 내역이 없으면 `null`입니다."
                          },
                          "child_beneficial_owners": {
                            "type": "array",
                            "description": "법인 UBO의 경우: 등기부에서 추출한 원시 객체 형태의 소유 법인 자체 실소유자입니다. 해당 사항이 없는 경우 빈 배열입니다.",
                            "items": {
                              "type": "object"
                            }
                          },
                          "effective_ownership_percent": {
                            "type": "number",
                            "nullable": true,
                            "description": "파싱된 숫자 소유 구조 백분율 — 가능한 경우 최댓값, 그렇지 않은 경우 최솟값입니다. 두 경계값 모두 파싱할 수 없는 경우 `null`입니다."
                          },
                          "voting_min_shares": {
                            "type": "string",
                            "nullable": true
                          },
                          "voting_max_shares": {
                            "type": "string",
                            "nullable": true
                          },
                          "appointment_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "신고된 선임일입니다.",
                            "format": "date"
                          }
                        }
                      }
                    }
                  }
                },
                "submitted": {
                  "type": "object",
                  "description": "주요 인물 워크플로 중 기업 관리자가 제출한 당사자입니다(source=USER인 BusinessParty 행).",
                  "properties": {
                    "parties": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "description": "주요 인물 워크플로를 통해 기업 관리자가 제출한 당사자입니다(source=USER).",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "entity_type": {
                            "type": "string",
                            "enum": [
                              "person",
                              "company"
                            ]
                          },
                          "source": {
                            "type": "string",
                            "enum": [
                              "USER"
                            ],
                            "description": "여기서는 항상 `USER`입니다. 이 버킷에는 주요 인물 워크플로에서 최종 사용자가 입력하거나 확인한 당사자만 포함됩니다(등기부에서 발견된 인물은 `registry` 아래에 표시됨)."
                          },
                          "name": {
                            "type": "string"
                          },
                          "first_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "last_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "company_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "registration_number": {
                            "type": "string",
                            "nullable": true
                          },
                          "email": {
                            "type": "string",
                            "format": "email",
                            "nullable": true
                          },
                          "nationality": {
                            "type": "string",
                            "nullable": true,
                            "description": "개인의 경우 국적, 기업 당사자의 경우 법인 설립 국가입니다."
                          },
                          "phone_number": {
                            "type": "string",
                            "nullable": true
                          },
                          "date_of_birth": {
                            "type": "string",
                            "format": "date",
                            "nullable": true
                          },
                          "position": {
                            "type": "string",
                            "nullable": true,
                            "description": "자유 형식 직함/직책입니다(개인 전용)."
                          },
                          "custom_fields": {
                            "type": "object",
                            "description": "이 당사자에 대해 수집된 워크플로 정의 커스텀 필드입니다. 키는 워크플로의 주요 인물 필드 디스크립터에 의해 정의됩니다."
                          },
                          "is_active": {
                            "type": "boolean"
                          },
                          "is_skipped": {
                            "type": "boolean",
                            "description": "최종 사용자가 이 당사자에 대한 인증을 건너뛴 경우 true입니다(역할에서 건너뛰기를 허용하는 경우에만 가능)."
                          },
                          "requires_verification": {
                            "type": "boolean",
                            "description": "역할 설정 및 소유권 임계값을 기반으로 이 당사자에게 하위 KYC/KYB 하위 세션이 필요한 경우 true입니다."
                          },
                          "roles": {
                            "type": "array",
                            "description": "이 당사자가 보유한 모든 역할이며, 각 역할마다 고유한 소유 비율 및 의결권 비율이 포함됩니다. 당사자 자체에는 스칼라 `role`/`ownership_percent`가 없습니다.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "role": {
                                  "type": "string",
                                  "enum": [
                                    "director",
                                    "non_executive_director",
                                    "secretary",
                                    "chairman",
                                    "ubo",
                                    "shareholder",
                                    "representative",
                                    "founder",
                                    "legal_advisor",
                                    "authorized_signatory",
                                    "trustee",
                                    "beneficiary",
                                    "settlor",
                                    "protector",
                                    "company_officer",
                                    "investor",
                                    "other"
                                  ]
                                },
                                "ownership_percent": {
                                  "type": "number",
                                  "nullable": true
                                },
                                "voting_percent": {
                                  "type": "number",
                                  "nullable": true
                                }
                              }
                            }
                          },
                          "kyc_session_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "확인이 필요한 개인 당사자의 하위 KYC 세션 ID입니다. 그렇지 않은 경우 `null`입니다."
                          },
                          "kyc_session_status": {
                            "type": "string",
                            "enum": [
                              "Not Started",
                              "In Progress",
                              "Approved",
                              "Declined",
                              "In Review",
                              "Expired",
                              "Abandoned",
                              "Kyc Expired",
                              "Resubmitted",
                              "Awaiting User"
                            ],
                            "nullable": true,
                            "description": "하위 KYC 세션의 수명 주기 상태입니다. 하위 KYC 세션이 없으면 `null`입니다."
                          },
                          "kyc_session_url": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true
                          },
                          "kyb_sub_session_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "확인이 필요한 법인 당사자의 하위 KYB 하위 세션 ID입니다. 그렇지 않은 경우 `null`입니다."
                          },
                          "kyb_sub_session_status": {
                            "type": "string",
                            "enum": [
                              "Not Started",
                              "In Progress",
                              "Approved",
                              "Declined",
                              "In Review",
                              "Expired",
                              "Abandoned",
                              "Kyc Expired",
                              "Resubmitted",
                              "Awaiting User"
                            ],
                            "nullable": true,
                            "description": "하위 KYB 서브세션의 수명 주기 상태입니다. 서브세션이 없으면 `null`입니다."
                          },
                          "kyb_sub_session_url": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true,
                            "description": "하위 KYB 서브세션의 공유 가능한 URL입니다. 서브세션이 없으면 `null`입니다."
                          },
                          "verification_workflow_type": {
                            "type": "string",
                            "nullable": true,
                            "description": "하위 세션 워크플로의 기본 워크플로 유형입니다(KYC 세션 우선, 없으면 KYB 하위 세션으로 대체). 그래프 기반 워크플로이거나 하위 세션이 없는 경우 `null`입니다."
                          },
                          "verification_workflow_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "자식 세션에서 사용한 워크플로 ID입니다. 자식 세션이 없으면 `null`입니다."
                          },
                          "verification_workflow_label": {
                            "type": "string",
                            "nullable": true,
                            "description": "하위 세션 워크플로의 사람이 읽기 쉬운 라벨입니다. 설정되지 않은 경우 `null`입니다."
                          },
                          "verification_workflow_features": {
                            "type": "array",
                            "nullable": true,
                            "description": "하위 인증 세션의 기능별 진행 상황입니다(예: `[{\"feature\": \"ID_VERIFICATION\", \"status\": \"Approved\"}]`). 하위 세션에 확인할 수 있는 기능 목록이 없으면 `null`입니다.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "feature": {
                                  "type": "string",
                                  "description": "기능 표시 이름(예: `ID_VERIFICATION`, `LIVENESS`, `AML`)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "Not Finished",
                                    "Approved",
                                    "Declined",
                                    "In Review",
                                    "Resub Requested"
                                  ],
                                  "description": "하위 세션 내부의 기능 수준 상태입니다."
                                }
                              }
                            }
                          },
                          "didit_internal_id": {
                            "type": "string",
                            "nullable": true,
                            "description": "하위 세션의 인증된 개인에 대한 고정 내부 식별자입니다. 확인되지 않은 경우 `null`입니다."
                          }
                        }
                      }
                    }
                  }
                },
                "ubo_kyc_summary": {
                  "type": "object",
                  "nullable": true,
                  "description": "집계된 UBO KYC 진행 상황이며, 연결된 KYC 세션이 있는 UBO가 없는 경우 null입니다.",
                  "properties": {
                    "total": {
                      "type": "integer"
                    },
                    "approved": {
                      "type": "integer"
                    },
                    "flagged": {
                      "type": "integer",
                      "description": "KYC가 거부됨 또는 검토 중인 UBO입니다."
                    },
                    "pending": {
                      "type": "integer"
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          },
          "document_verifications": {
            "type": "array",
            "nullable": true,
            "description": "워크플로 노드별로 그룹화된 문서 검증 확인 항목입니다. `session_kind = business`인 경우에만 표시됩니다.",
            "items": {
              "type": "object",
              "description": "워크플로 노드별로 그룹화된 문서입니다. session_kind = business인 경우에만 표시됩니다.",
              "properties": {
                "status": {
                  "type": "string"
                },
                "node_id": {
                  "type": "string",
                  "nullable": true
                },
                "items": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "uuid": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "document_type": {
                        "type": "string",
                        "enum": [
                          "LEGAL_PRESENCE",
                          "COMPANY_DETAILS",
                          "OWNERSHIP_STRUCTURE",
                          "REPRESENTATIVES_AUTHORIZATION",
                          "OTHER"
                        ],
                        "nullable": true,
                        "description": "파일이 분류된 상위 KYB 문서 그룹입니다. 분류되지 않은 동안에는 `null`입니다."
                      },
                      "document_subtype": {
                        "type": "string",
                        "nullable": true,
                        "description": "OCR로 감지된 구체적인 하위 유형입니다(예: `CERTIFICATE_OF_INCORPORATION`, `SHAREHOLDER_REGISTRY`). OCR이 문서를 확실하게 분류할 수 없는 경우 `UNKNOWN`입니다."
                      },
                      "document_group": {
                        "type": "string",
                        "enum": [
                          "LEGAL_PRESENCE",
                          "COMPANY_DETAILS",
                          "OWNERSHIP_STRUCTURE",
                          "REPRESENTATIVES_AUTHORIZATION",
                          "OTHER"
                        ],
                        "nullable": true,
                        "description": "`document_type`의 별칭으로, `groups` 및 `required_groups`에서 사용하는 그룹 이름입니다."
                      },
                      "file_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "업로드된 파일로 연결되는 유효 기간이 짧은 사전 서명된 링크입니다. 아직 처리되지 않은 분석가 생성 문서 요청 자리표시자(`is_requested = true`)의 경우 `null`입니다."
                      },
                      "original_filename": {
                        "type": "string",
                        "nullable": true,
                        "description": "사용자 또는 분석가가 업로드한 파일 이름입니다."
                      },
                      "file_size": {
                        "type": "integer",
                        "nullable": true,
                        "description": "바이트 단위의 파일 크기입니다."
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "Not Finished",
                          "Approved",
                          "Declined",
                          "In Review",
                          "Resub Requested"
                        ],
                        "description": "문서별 인증 상태입니다."
                      },
                      "created_at": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "cross_check_result": {
                        "type": "object",
                        "nullable": true,
                        "description": "OCR로 추출한 문서 필드와 등기부 회사 프로필 간의 상호 대조 결과입니다. `critical`, `non_critical`, `people` 섹션이 포함된 객체로, 각 섹션은 필드 이름(예: `company_name`, `registration_number`, `incorporation_date`, `registered_address`)을 `{\"document\": \"...\", \"registry\": \"...\", \"match\": true, \"score\": 0.97}`과 같은 비교 기록에 매핑합니다. 문서에 OCR 데이터가 없거나 비교할 등기부 회사가 없는 경우 `null`입니다."
                      },
                      "document_metadata": {
                        "type": "object",
                        "nullable": true,
                        "description": "업로드된 기업 문서에서 추출한 메타데이터입니다. 메타데이터 추출에 성공하면 16개 키가 항상 모두 존재하며(파일 형식에 적용되지 않는 개별 값은 `null`), 아무것도 추출할 수 없는 경우 전체 객체가 `null`이 됩니다. PDF의 경우 `overlay_manipulation`에 포렌식 오버레이 텍스트 분석 결과가 포함됩니다.",
                        "properties": {
                          "file_size": {
                            "type": "integer",
                            "nullable": true,
                            "description": "문서 크기입니다."
                          },
                          "content_type": {
                            "type": "string",
                            "nullable": true,
                            "description": "문서의 콘텐츠 유형입니다."
                          },
                          "creation_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "문서가 생성된 날짜입니다."
                          },
                          "modified_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "문서가 수정된 날짜입니다."
                          },
                          "creator": {
                            "type": "string",
                            "nullable": true,
                            "description": "파일 메타데이터(PDF `Creator`)에 기록된 작성 도구/사용자입니다."
                          },
                          "producer": {
                            "type": "string",
                            "nullable": true,
                            "description": "파일을 생성한 소프트웨어(PDF `Producer`)입니다."
                          },
                          "software": {
                            "type": "string",
                            "nullable": true,
                            "description": "파일 메타데이터에 기록된 편집 소프트웨어입니다."
                          },
                          "encryption": {
                            "type": "string",
                            "nullable": true,
                            "description": "파일이 암호화된 경우, 파일의 암호화 방식입니다."
                          },
                          "is_signed": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "문서에 전자 서명이 포함되어 있는지 여부입니다."
                          },
                          "is_tampered": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "전자 서명 검증에 실패했는지(서명 후 수정) 여부입니다."
                          },
                          "signature_info": {
                            "type": "object",
                            "nullable": true,
                            "description": "디지털 서명의 세부 정보(있는 경우)입니다."
                          },
                          "exif_original_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "이미지 업로드의 EXIF 원본 촬영 날짜입니다."
                          },
                          "exif_digitized_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "이미지 업로드의 EXIF 디지털화 날짜입니다."
                          },
                          "processed_by_known_editor": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "메타데이터를 통해 파일이 알려진 이미지/PDF 편집기를 거쳤는지 여부를 나타냅니다."
                          },
                          "has_different_creation_mod_date": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "생성 날짜와 수정 날짜가 다른지 여부입니다. 편집 신호일 수 있지만 확정적인 것은 아닙니다."
                          },
                          "overlay_manipulation": {
                            "type": "object",
                            "nullable": true,
                            "description": "오버레이 텍스트 조작 의심에 대한 PDF 포렌식 분석입니다. 오버레이 조작 증거가 발견되지 않았거나 문서가 PDF가 아닌 경우 null입니다.",
                            "properties": {
                              "detected": {
                                "type": "boolean",
                                "description": "오버레이 텍스트 조작 흔적이 감지되었는지 여부입니다."
                              },
                              "analyzed": {
                                "type": "boolean",
                                "description": "PDF를 분석할 수 있었는지 여부입니다."
                              },
                              "analysis_incomplete": {
                                "type": "boolean",
                                "description": "파일 전체를 확인할 수 없는 경우에만 존재하며 참(true)입니다. 확인된 부분은 가능한 범위에서 그 결과를 유지하고, 문서는 검증되지 않은 텍스트 대체 경고를 표시합니다."
                              },
                              "signals": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "duplicate_font_subset 또는 glyph_fragmentation과 같이 감지된 포렌식 신호입니다."
                              },
                              "manipulated_regions": {
                                "type": "array",
                                "description": "PDF 페이지 좌표 기준 위변조 의심 영역입니다.",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "page": {
                                      "type": "integer"
                                    },
                                    "x": {
                                      "type": "number"
                                    },
                                    "y": {
                                      "type": "number"
                                    },
                                    "width": {
                                      "type": "number"
                                    },
                                    "height": {
                                      "type": "number"
                                    },
                                    "page_width": {
                                      "type": "number"
                                    },
                                    "page_height": {
                                      "type": "number"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      },
                      "description": {
                        "type": "string",
                        "nullable": true,
                        "description": "문서 요청에 대해 분석가가 제공한 라벨 또는 사유. 일반 업로드의 경우 `null`입니다."
                      },
                      "is_requested": {
                        "type": "boolean",
                        "description": "업로드를 대기 중인 분석가가 생성한 문서 요청 자리표시자인 경우 true입니다."
                      },
                      "ocr_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "is_console_upload": {
                        "type": "boolean",
                        "description": "최종 사용자 흐름이 아닌 콘솔에서 업로드된 문서인 경우 true입니다. 콘솔 업로드는 기능 수준 집계 상태를 변경하지 않습니다."
                      },
                      "is_confirmed": {
                        "type": "boolean",
                        "description": "콘솔 업로드는 `false`로 시작하여 관리자가 확인하면 `true`로 전환됩니다. 최종 사용자 업로드는 항상 `true`입니다."
                      }
                    }
                  }
                },
                "groups": {
                  "type": "object",
                  "description": "그룹 이름(예: legal_presence, ownership_structure)을 키로 하는 그룹별 진행률 카운터입니다.",
                  "additionalProperties": {
                    "type": "object",
                    "properties": {
                      "total": {
                        "type": "integer"
                      },
                      "approved": {
                        "type": "integer"
                      },
                      "pending": {
                        "type": "integer"
                      },
                      "declined": {
                        "type": "integer"
                      },
                      "in_review": {
                        "type": "integer"
                      },
                      "other": {
                        "type": "integer"
                      },
                      "missing": {
                        "type": "integer",
                        "description": "아직 파일이 업로드되지 않은 요청된 플레이스홀더입니다."
                      }
                    }
                  }
                },
                "required_groups": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          },
          "environment": {
            "type": "string",
            "enum": [
              "live",
              "sandbox"
            ],
            "description": "세션이 프로덕션 애플리케이션(`live`)에서 생성되었는지 또는 샌드박스 애플리케이션(`sandbox`)에서 생성되었는지 여부입니다. 샌드박스 세션은 무료이며 완전히 시뮬레이션되고 크레딧이 청구되지 않습니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "nullable": true,
            "description": "세션 생성 시 사용된 샌드박스 시나리오입니다. 라이브 세션 및 시나리오 없이 생성된 샌드박스 세션의 경우 `null`입니다."
          },
          "resubmissions": {
            "type": "array",
            "description": "사용자 및 기업 세션에 대해 `include=resubmissions`가 포함된 경우에만 반환됩니다. 재제출 요청당 하나의 항목이 오래된 순서대로 반환됩니다. 각 항목에는 요청 전 재제출된 단계가 반환한 결과가 포함되어 있으므로 이전 제출 내용을 계속 읽을 수 있습니다. 세션을 삭제하면 모든 제출 내용이 삭제됩니다.",
            "items": {
              "type": "object",
              "properties": {
                "number": {
                  "type": "integer",
                  "description": "세션의 첫 번째 재제출인 경우 1, 두 번째 재제출인 경우 2 등입니다."
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "재제출이 요청된 시점입니다."
                },
                "previous_status": {
                  "type": "string",
                  "description": "요청 직전의 세션 상태입니다."
                },
                "nodes": {
                  "type": "array",
                  "description": "사용자에게 다시 전송된 워크플로 단계 목록입니다.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "node_id": {
                        "type": "string"
                      },
                      "feature": {
                        "type": "string"
                      }
                    }
                  }
                },
                "reasons": {
                  "type": "object",
                  "nullable": true,
                  "additionalProperties": {
                    "type": "string"
                  },
                  "description": "`node_id`를 키로 하는 각 단계별 제공된 사유입니다."
                },
                "requested_by": {
                  "type": "object",
                  "nullable": true,
                  "description": "누가 재제출을 요청했는지 나타냅니다.",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "email": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string"
                    }
                  }
                },
                "results": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "재제출된 단계들이 요청 전에 반환했던 결과로, 이 응답의 현재 결과(`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `phone_verifications`, `email_verifications`, `aml_screenings`, `ip_analyses`, `database_validations`, `questionnaire_responses`, `document_ai_documents`, `geolocation_checks`, 기업 세션의 경우 `document_verifications` 포함)와 동일한 키 및 형태로 제공됩니다. 다시 전송된 단계의 키만 표시됩니다."
                }
              }
            }
          },
          "biometric_consent": {
            "type": "object",
            "nullable": true,
            "description": "세션에서 얼굴 캡처 전 명시적인 생체 인식 동의가 필요했는지 여부, 그 이유 및 응답 증거입니다. 사용자 인증(KYC) 세션 전용이며, 세션 webhook의 `decision`에도 동일한 객체가 포함됩니다. 얼굴 캡처가 없는 워크플로 등 세션이 평가된 적이 없는 경우 `null`입니다. 기록된 값이 없는 필드는 `null`입니다. 4.10.0 미만의 네이티브 SDK 또는 버전을 보고하지 않는 SDK는 동의 단계를 표시할 수 없습니다. 이 경우 얼굴 캡처는 이전과 동일하게 실행되며, 동의가 필요했던 세션은 `status: \"pending\"`과 함께 `reason: \"BIOMETRIC_CONSENT_UNSUPPORTED_SDK\"`를 보고합니다. [생체 인식 동의](/ko/getting-started/biometric-consent)를 참조하세요.",
            "properties": {
              "required": {
                "type": "boolean",
                "description": "Whether the session must collect explicit biometric consent. Never goes back to `false`."
              },
              "trigger": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "declared_state",
                  "ip_state",
                  "ip_unknown",
                  "document_issuer",
                  "forced",
                  "customer_collected"
                ],
                "description": "동의가 필요한 이유 또는 동의가 충족된 방식입니다. `declared_state`: 적용 대상 주(`user_state` 또는 `expected_details`의 미국 주소)를 선언했습니다. `ip_state`: 사용자의 IP가 적용 대상 주(일리노이, 텍사스, 콜로라도)에 있습니다. `ip_unknown`: 증거상 사용자가 미국에 있는 것으로 보이지만 주를 확인할 수 없습니다(IP가 주 정보 없이 미국에 있거나 귀하의 세부 정보 또는 문서상 사용자가 미국에 있는 것으로 표시되지만 위치를 파악할 수 없음). `document_issuer`: 신분증이 적용 대상 주에서 발급되었습니다. `forced`: 애플리케이션의 모드가 Always입니다. `customer_collected`: 세션 생성 시 `biometric_consent`를 전달했습니다. 필요하지 않은 경우 `null`입니다."
              },
              "status": {
                "type": "string",
                "enum": [
                  "not_required",
                  "pending",
                  "given",
                  "declined"
                ],
                "description": "`not_required`; `pending`(필수이나 제공되지 않음: 개인이 아직 응답하지 않았거나 `reason`에 수집되지 않은 이유가 표시됨); `given`; `declined`(거부가 기록되어 세션이 `Declined`로 종료됨. 현재 Didit 화면에서는 거부 옵션을 제공하지 않음)."
              },
              "given_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "동의가 이루어진 시점입니다. `customer_collected`의 경우 전송한 `given_at`입니다."
              },
              "declined_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "거부가 기록된 시점입니다."
              },
              "text_version": {
                "type": "string",
                "nullable": true,
                "description": "사용자가 응답한 동의 텍스트의 버전 ID 또는 귀하가 보낸 동의 텍스트의 버전 ID입니다."
              },
              "text_hash": {
                "type": "string",
                "nullable": true,
                "description": "표시된 언어 그대로의 정확한 동의 텍스트에 대한 SHA-256(16진수)입니다."
              },
              "locale": {
                "type": "string",
                "nullable": true,
                "description": "동의 문구가 표시된 언어입니다."
              },
              "policy_url": {
                "type": "string",
                "format": "uri",
                "nullable": true,
                "description": "동의 단계에서 연결된 생체 인식 데이터 정책입니다."
              },
              "step": {
                "type": "string",
                "nullable": true,
                "description": "해당 사용자가 응답했을 때 세션이 머물러 있던 워크플로 단계입니다(예: `LIVENESS`)."
              },
              "node_id": {
                "type": "string",
                "nullable": true,
                "description": "해당 사용자가 응답했을 때 세션이 머물러 있던 워크플로 그래프 노드입니다."
              },
              "ip_address": {
                "type": "string",
                "nullable": true,
                "description": "응답이 온 주소입니다."
              },
              "ip_country_code": {
                "type": "string",
                "nullable": true,
                "description": "응답 IP 주소의 ISO 3166-1 alpha-2 국가 코드입니다."
              },
              "ip_state": {
                "type": "string",
                "nullable": true,
                "description": "답변 IP의 ISO 3166-2 행정 구역(예: `US-IL`)입니다."
              },
              "ip_city": {
                "type": "string",
                "nullable": true,
                "description": "답변 IP의 도시입니다."
              },
              "user_agent": {
                "type": "string",
                "nullable": true,
                "description": "답변 요청의 사용자 에이전트입니다."
              },
              "detected_ip_address": {
                "type": "string",
                "nullable": true,
                "description": "해당 요구 사항이 마지막으로 평가된 인물의 IP 주소입니다. 해당 인물이 다른 기기에서 응답한 경우 `ip_address`와 다를 수 있습니다."
              },
              "detected_country_code": {
                "type": "string",
                "nullable": true,
                "description": "감지된 IP 주소의 ISO 3166-1 alpha-2 국가 코드입니다."
              },
              "detected_state": {
                "type": "string",
                "nullable": true,
                "description": "감지된 IP의 ISO 3166-2 행정 구역입니다."
              },
              "detected_city": {
                "type": "string",
                "nullable": true,
                "description": "감지된 IP의 도시입니다."
              },
              "declared_state": {
                "type": "string",
                "nullable": true,
                "description": "귀하가 선언한 ISO 3166-2 행정 구역: `user_state` 또는 `expected_details` 내 미국 주소의 주입니다."
              },
              "document_state": {
                "type": "string",
                "nullable": true,
                "description": "신분증 캡처 시 판독된 신분증 발급 ISO 3166-2 행정 구역입니다."
              },
              "jurisdictions": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "해당 개인에게 생체 인식 법률이 적용되는 미국 주(USPS 코드, 예: `IL`)입니다. 증거상 해당 개인이 미국에 위치하지만 주를 알 수 없는 경우 `US`입니다. 적용되는 항목이 없으면 비어 있습니다."
              },
              "retention_months": {
                "type": "integer",
                "nullable": true,
                "description": "`jurisdictions` 중 가장 짧은 생체 인식 보존 한도(월 단위)입니다. 적용되는 한도가 없는 경우 `null`입니다."
              },
              "reason": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "BIOMETRIC_CONSENT_UNSUPPORTED_SDK",
                  "BIOMETRIC_CONSENT_DECLINED"
                ],
                "description": "`BIOMETRIC_CONSENT_UNSUPPORTED_SDK`: 동의가 필요했으나 4.10.0 미만의 네이티브 SDK 또는 버전을 보고하지 않은 SDK가 동의 단계 없이 얼굴을 캡처함. `status`는 `pending`으로 유지되거나, 해당 사용자가 이후 호스팅 플로우에서 동의한 경우 `given`이 됨. `BIOMETRIC_CONSENT_DECLINED`: 거부가 기록됨(SDK 사유를 대체함). 그 외에는 `null`이며, 세션에 동의가 필요하지 않은 경우 항상 `null`임."
              },
              "decline_reason": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "BIOMETRIC_CONSENT_DECLINED"
                ],
                "description": "기록된 거부로 인해 세션이 종료된 경우 `BIOMETRIC_CONSENT_DECLINED`, 그렇지 않은 경우 `null`."
              },
              "face_data_deleted_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "거부로 인해 세션의 얼굴 이미지, 동영상 및 얼굴 템플릿이 삭제된 시점입니다. 거부가 기록되지 않은 경우 `null`입니다."
              }
            }
          },
          "investigator": {
            "$ref": "#/components/schemas/InvestigatorBlock"
          },
          "biometric_retention": {
            "$ref": "#/components/schemas/BiometricRetention"
          },
          "fraud_check": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Fraud Check API 호출 결과입니다. 다른 모든 세션의 경우 `null`입니다."
          },
          "full_session_video": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "전체 세션 녹화본의 만료되는 URL입니다. 조직에서 전체 세션 동영상을 녹화하는 경우에만 반환됩니다."
          },
          "full_session_video_recorded_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "전체 세션 녹화가 생성된 시점입니다. 조직에서 전체 세션 동영상을 녹화하는 경우에만 반환됩니다."
          }
        }
      },
      "WorkflowDetail": {
        "type": "object",
        "description": "아래 필드는 타입이 지정되어 있습니다. 또한 이 객체는 워크플로 설정의 다른 모든 열(기능 토글, 임계값, 경고 작업, 허용된 문서, 콜백)을 추가 속성으로 전달합니다. `workflow_type`에 적용되지 않는 필드는 `null`입니다.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "버전별 식별자(`settings_uuid`)입니다. 워크플로의 모든 버전에는 고유한 식별자가 있습니다."
          },
          "workflow_id": {
            "type": "string",
            "format": "uuid",
            "description": "워크플로의 모든 버전에서 공유되는 안정적인 식별자입니다. 이 식별자로 생성된 세션은 게시된 최신 버전을 사용합니다."
          },
          "workflow_label": {
            "type": "string",
            "description": "워크플로의 표시 이름입니다."
          },
          "workflow_type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "kyc",
              "kyb",
              "adaptive_age_verification",
              "biometric_authentication",
              "address_verification",
              "questionnaire_verification",
              "email_verification",
              "phone_verification",
              null
            ],
            "description": "워크플로 템플릿입니다. 템플릿 없이 생성된 그래프 워크플로의 경우 `null`입니다."
          },
          "is_default": {
            "type": "boolean",
            "description": "이 워크플로가 애플리케이션의 기본 워크플로인지 여부입니다."
          },
          "is_archived": {
            "type": "boolean",
            "description": "보관된 워크플로는 새 세션을 시작할 수 없습니다."
          },
          "version": {
            "type": "integer",
            "description": "워크플로 내의 버전 번호입니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ],
            "description": "초안 버전은 편집할 수 있으며, 게시된 버전은 변경할 수 없고 새 세션에 사용됩니다."
          },
          "published_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "이 버전이 게시된 시점입니다. 초안의 경우 `null`입니다."
          },
          "is_simple_workflow": {
            "type": "boolean",
            "description": "워크플로에 사용자 지정 `workflow_graph`가 없는 경우 `true`입니다."
          },
          "is_editable": {
            "type": "boolean",
            "description": "`draft` 버전인 경우에만 `true`입니다."
          },
          "workflow_url": {
            "type": "string",
            "format": "uri",
            "description": "이 워크플로로 세션을 시작하는 공개 URL입니다."
          },
          "workflow_graph": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "워크플로의 그래프 구조(노드 및 에지)입니다. 단순 워크플로의 경우 `null`입니다."
          },
          "features": {
            "type": "string",
            "description": "`\" + \"`로 연결된 활성화된 기능입니다(예: `\"OCR + LIVENESS\"`)."
          },
          "total_price": {
            "type": "number",
            "nullable": true,
            "description": "세션당 가격입니다. 그래프 워크플로의 경우 가장 비싼 경로의 가격입니다."
          },
          "min_price": {
            "type": "number",
            "nullable": true,
            "description": "워크플로에서 가장 저렴한 경로의 가격입니다."
          },
          "max_price": {
            "type": "number",
            "nullable": true,
            "description": "워크플로에서 가장 비싼 경로의 가격입니다."
          },
          "special_add_on_prices": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "조직별 부가 기능 가격이며, 설정되지 않은 경우 `null`입니다."
          },
          "max_retry_attempts": {
            "type": "integer",
            "description": "거부된 인증 후 허용되는 재시도 횟수입니다."
          },
          "retry_window_days": {
            "type": "integer",
            "nullable": true,
            "description": "재시도가 허용되는 일수."
          },
          "session_expiration_time": {
            "type": "integer",
            "description": "완료되지 않은 세션이 만료되기까지 남은 시간(초)."
          },
          "questionnaire": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "워크플로에 연결된 설문지 또는 `null`입니다."
          },
          "kyb_role_settings": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "KYB 주요 인물에 대한 역할별 인증 설정입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "signature_availability": {
            "type": "object",
            "description": "현재 서명 가능한 전자 서명 등급입니다. `signature_level`을 설정하기 전에 확인하십시오. `kyc`, `kyb` 및 그래프 워크플로에서 반환됩니다.",
            "properties": {
              "simple": {
                "type": "boolean",
                "description": "Simple은 항상 사용할 수 있습니다."
              },
              "aes": {
                "type": "boolean",
                "description": "고급 전자 서명(AES)으로 지금 서명할 수 있는지 여부입니다. `false`인 동안 `signature_level: \"aes\"`로 새 단계를 저장하면 `aes_not_available` 오류와 함께 거부됩니다."
              },
              "qes": {
                "type": "boolean",
                "description": "적격 전자 서명(QES)으로 지금 서명할 수 있는지 여부입니다. 적격 제공업체가 연결될 때까지 `false`입니다."
              }
            }
          },
          "is_bank_verification_enabled": {
            "type": "boolean",
            "description": "단순 KYC 또는 KYB 워크플로가 은행 확인을 실행하는지 여부입니다. 연락처 단계(및 위치 확인) 이후, 데이터베이스 검증, AML 및 IP 분석 이전에 실행됩니다. 은행 확인은 아직 일반에 공개되지 않았으며, 활성화되지 않은 환경에서 켜려고 하면 거부됩니다."
          },
          "bank_verification_config": {
            "type": "object",
            "additionalProperties": true,
            "description": "`BANK_VERIFICATION` 노드가 사용하는 것과 동일한 키(예: `bank_countries` 및 `bank_method_order`)를 사용하는 단순 워크플로의 은행 인증 설정입니다. 알 수 없는 키는 삭제됩니다. 모든 키는 선택 사항이며 누락된 키는 기본값을 유지하므로 `{}`는 모든 기본값을 의미합니다. [은행 인증 설정](/ko/management-api/workflows/feature-configs#은행-인증)을 참조하십시오.",
            "example": {}
          },
          "is_geolocation_enabled": {
            "type": "boolean",
            "description": "단순 KYC 워크플로가 위치 확인을 실행하는지 여부입니다. 연락처 단계 이후, 은행 확인 및 데이터베이스 검증 이전에 실행됩니다. 기업(KYB) 워크플로에서는 실행할 수 없습니다."
          },
          "geolocation_config": {
            "type": "object",
            "additionalProperties": true,
            "description": "간단한 워크플로의 위치 확인 설정으로, `GEOLOCATION` 노드가 사용하는 것과 동일한 키(예: `is_geolocation_geofencing_enabled` 및 `geolocation_max_attempts`)를 갖습니다. 알 수 없는 키는 삭제됩니다. 모든 키는 선택 사항이며 누락된 키는 기본값을 유지하므로 `{}`는 모든 기본값을 의미합니다.",
            "example": {}
          }
        },
        "additionalProperties": true
      },
      "UserSessionListItem": {
        "title": "KYC session row (session_kind: user)",
        "type": "object",
        "description": "사용자 인증(KYC) 세션의 요약 행입니다. 신원 필드(`full_name`, `country`, `document_type`, `portrait_image`, 연락처 필드)는 사용자가 인증 단계를 완료함에 따라 점진적으로 채워지며, 관련 단계가 완료될 때까지 `null`입니다. 워크플로의 응답 속성 설정에 의해 제한된 필드도 `null`로 반환됩니다.",
        "required": [
          "session_id",
          "session_kind",
          "session_number",
          "session_url",
          "portrait_image",
          "document_type",
          "full_name",
          "country",
          "status",
          "vendor_data",
          "didit_internal_id",
          "created_at",
          "features",
          "phone_number",
          "email_address",
          "additional_details"
        ],
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "인증 세션의 고유 식별자입니다. 전체 결정 payload를 가져오려면 `GET /v3/session/{sessionId}/decision/`과 함께 사용합니다.",
            "example": "5b3720ed-d429-42ef-b67f-37ea805f48ee"
          },
          "session_kind": {
            "type": "string",
            "enum": [
              "user"
            ],
            "description": "행 판별자. KYC 행의 경우 항상 `\"user\"`입니다. 기업 확인(KYB) 행은 `\"business\"` 값을 가지며 형태가 다릅니다.",
            "example": "user"
          },
          "session_number": {
            "type": "integer",
            "description": "애플리케이션 내 세션의 사람이 읽기 쉬운 순차 번호입니다. `search` 파라미터와도 일치합니다.",
            "example": 720
          },
          "session_url": {
            "type": "string",
            "nullable": true,
            "description": "최종 사용자가 플로우를 완료하기 위해 여는 호스팅 인증 URL입니다. 세션에 호스팅 URL이 없으면 `null`입니다.",
            "example": "https://verify.didit.me/session/CuXoBYCYVO5Y"
          },
          "portrait_image": {
            "type": "string",
            "nullable": true,
            "description": "이용 가능한 최상의 인물 사진에 대한 만료되는(사전 서명된) URL입니다. NFC 칩 사진이 있는 경우 이를 우선하며, 그렇지 않은 경우 신분증 문서 인물 사진, 그 외의 경우 라이브니스 참조 이미지가 사용됩니다. 이 중 하나가 존재하기 전까지는 `null`입니다. 링크가 만료되므로 즉시 다운로드하십시오.",
            "example": "https://<media-host>/portraits/5b3720ed.jpg?X-Amz-Expires=3600&X-Amz-Signature=..."
          },
          "document_type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Passport",
              "Identity Card",
              "Driver's License",
              "Residence Permit",
              "Health Insurance Card",
              "Tax Card"
            ],
            "description": "인증된 신분증 문서의 사람이 읽을 수 있는 유형입니다. 문서 검증이 완료되기 전에는 `null`이며, 완료 후에도 인증된 코드에 표시 매핑이 없는 경우(`SSC`, `WP`, `VISA`, `PSC`, `BC`, `OTHER`) `null`입니다. 참고: `document_type` 쿼리 파라미터는 이러한 표시 값이 아닌 짧은 코드(`P`, `ID`, `DL`, `RP` 등)로 필터링합니다.",
            "example": "Passport"
          },
          "full_name": {
            "type": "string",
            "nullable": true,
            "description": "세션에 대해 사용 가능한 가장 적합한 성명입니다. 신분증 문서 OCR, AML 스크리닝 데이터, 데이터베이스 검증 스크리닝 데이터, 주소 증명 문서, 세션 생성 시 제공된 예상 세부 정보 순으로 확인됩니다. 아직 사용 가능한 정보가 없는 경우 `null`입니다.",
            "example": "Jane Marie Doe"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "세션과 연계된 ISO 3166-1 alpha-3 국가이며, 신분증 문서 발급 국가, 데이터베이스 검증 발급 국가, 주소 증명 발급 국가, 예상 세부 정보, 인증된 전화번호 국가 순으로 결정됩니다. 국적과 다를 수 있습니다.",
            "example": "ESP"
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User"
            ],
            "description": "전체 세션 상태입니다. 라이프사이클은 [인증 상태](/ko/integration/verification-statuses) 페이지를 참조하십시오.",
            "example": "Approved"
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "최종 사용자에 대한 귀하 고유의 식별자이며, 세션 생성 시 전송된 그대로 다시 반환됩니다.",
            "example": "your-user-id-123"
          },
          "didit_internal_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "이 세션의 기반이 되는 인증된 사용자 프로필에 대한 Didit 내부 식별자입니다. 동일한 사용자의 여러 세션에 걸쳐 일정하게 유지되며, `didit_internal_id` 쿼리 파라미터를 통해 필터링할 수 있습니다.",
            "example": "d9e78474-6c8d-4f2a-bb90-6f5c2f3a1147"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "세션이 생성된 UTC 타임스탬프입니다.",
            "example": "2026-06-09T12:26:54.328364Z"
          },
          "features": {
            "type": "array",
            "description": "세션의 워크플로에 구성된 모든 인증 단계에 대한 기능별 상태(워크플로 순서)입니다.",
            "items": {
              "type": "object",
              "required": [
                "feature",
                "status"
              ],
              "properties": {
                "feature": {
                  "type": "string",
                  "enum": [
                    "ID_VERIFICATION",
                    "NFC",
                    "LIVENESS",
                    "FACE_MATCH",
                    "POA",
                    "QUESTIONNAIRE",
                    "EMAIL_VERIFICATION",
                    "PHONE",
                    "AML",
                    "IP_ANALYSIS",
                    "AGE_ESTIMATION",
                    "DATABASE_VALIDATION",
                    "GEOLOCATION"
                  ],
                  "description": "인증 기능 식별자입니다.",
                  "example": "ID_VERIFICATION"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ],
                  "description": "이 기능의 상태입니다. 단계가 완료될 때까지 `Not Finished`입니다.",
                  "example": "Approved"
                }
              }
            }
          },
          "phone_number": {
            "type": "object",
            "nullable": true,
            "description": "세션과 연결된 전화번호: 전화번호 인증이 실행된 경우 인증된 전화번호, 그렇지 않으면 세션 생성 시 제공된 연락처 전화번호입니다. 둘 다 없으면 `null`입니다.",
            "required": [
              "number",
              "is_verified"
            ],
            "properties": {
              "number": {
                "type": "string",
                "description": "E.164 형식의 전화번호입니다.",
                "example": "+14155552671"
              },
              "is_verified": {
                "type": "boolean",
                "description": "전화번호 인증 기능이 이 번호를 승인한 경우에만 `true`입니다.",
                "example": true
              }
            }
          },
          "email_address": {
            "type": "object",
            "nullable": true,
            "description": "세션과 연결된 이메일: 이메일 인증이 실행된 경우 인증된 이메일이며, 그렇지 않은 경우 세션 생성 시 제공된 연락처 이메일입니다. 둘 다 없으면 `null`입니다.",
            "required": [
              "email",
              "is_verified"
            ],
            "properties": {
              "email": {
                "type": "string",
                "format": "email",
                "example": "jane@example.com"
              },
              "is_verified": {
                "type": "boolean",
                "description": "이메일 인증 기능이 이 주소를 승인한 경우에만 `true`입니다.",
                "example": true
              }
            }
          },
          "additional_details": {
            "type": "object",
            "nullable": true,
            "description": "기능별 추가 정보의 간소화된 데이터입니다. 데이터를 생성한 기능만 키로 표시되며, 추가 정보를 생성한 기능이 없으면 `null`이 됩니다. 워크플로의 응답 속성 설정에 의해 제외된 필드는 생략됩니다.",
            "properties": {
              "aml": {
                "type": "object",
                "description": "AML 스크리닝이 실행되었을 때 표시됩니다.",
                "properties": {
                  "total_hits": {
                    "type": "integer",
                    "description": "AML 스크리닝 적발 건수입니다.",
                    "example": 0
                  },
                  "entity_type": {
                    "type": "string",
                    "description": "스크리닝된 엔티티 유형입니다.",
                    "example": "person"
                  },
                  "is_adverse_media_fetched": {
                    "type": "boolean",
                    "example": false
                  },
                  "screened_data": {
                    "type": "object",
                    "description": "스크리닝된 데이터의 하위 집합입니다. 비어 있지 않은 키만 포함됩니다.",
                    "properties": {
                      "nationality": {
                        "type": "string",
                        "example": "ESP"
                      },
                      "document_number": {
                        "type": "string",
                        "example": "XX1234567"
                      },
                      "date_of_birth": {
                        "type": "string",
                        "example": "1990-05-21"
                      }
                    }
                  }
                }
              },
              "database_validation": {
                "type": "object",
                "description": "데이터베이스 검증이 실행되었을 때 표시됩니다.",
                "properties": {
                  "validation_type": {
                    "type": "string",
                    "example": "DOCUMENT_VALIDATION"
                  },
                  "match_type": {
                    "type": "string",
                    "example": "FULL_MATCH"
                  },
                  "identification_number": {
                    "type": "string",
                    "description": "검증된 세금, 개인 또는 문서 번호(사용 가능한 첫 번째 값)입니다.",
                    "example": "12345678Z"
                  }
                }
              },
              "poa": {
                "type": "object",
                "description": "주소 증명이 실행되었을 때 표시됩니다.",
                "properties": {
                  "document_type": {
                    "type": "string",
                    "example": "UTILITY_BILL"
                  },
                  "issuer": {
                    "type": "string",
                    "example": "Energy Co"
                  },
                  "address": {
                    "type": "string",
                    "example": "Calle Mayor 1, 28013 Madrid"
                  },
                  "name_on_document": {
                    "type": "string",
                    "example": "Jane Marie Doe"
                  }
                }
              },
              "liveness": {
                "type": "object",
                "description": "라이브니스 검사가 실행되었을 때 표시됩니다.",
                "properties": {
                  "method": {
                    "type": "string",
                    "example": "PASSIVE"
                  },
                  "score": {
                    "type": "number",
                    "description": "라이브니스 신뢰도 점수(소수점 둘째 자리로 반올림됨).",
                    "example": 0.98
                  }
                }
              },
              "face_match": {
                "type": "object",
                "description": "얼굴 대조가 실행되었을 때 표시됩니다.",
                "properties": {
                  "score": {
                    "type": "number",
                    "description": "소수점 둘째 자리로 반올림된 얼굴 대조 유사도 점수입니다.",
                    "example": 0.95
                  },
                  "source_image": {
                    "type": "string",
                    "description": "소스 얼굴 이미지의 만료되는(사전 서명된) URL입니다.",
                    "example": "https://<media-host>/faces/source.jpg?X-Amz-Expires=3600&..."
                  },
                  "target_image": {
                    "type": "string",
                    "description": "타깃 얼굴 이미지의 만료되는(사전 서명된) URL입니다.",
                    "example": "https://<media-host>/faces/target.jpg?X-Amz-Expires=3600&..."
                  }
                }
              },
              "phone_verification": {
                "type": "object",
                "description": "전화번호 인증이 실행되었을 때 표시됩니다.",
                "properties": {
                  "country_code": {
                    "type": "string",
                    "description": "전화번호의 ISO 3166-1 alpha-2 국가 코드입니다.",
                    "example": "US"
                  },
                  "is_temporary": {
                    "type": "boolean",
                    "example": false
                  },
                  "is_ported": {
                    "type": "boolean",
                    "example": false
                  },
                  "is_blocked": {
                    "type": "boolean",
                    "example": false
                  }
                }
              },
              "email_verification": {
                "type": "object",
                "description": "이메일 인증이 실행되었을 때 표시됩니다.",
                "properties": {
                  "is_breached": {
                    "type": "boolean",
                    "example": false
                  },
                  "is_disposable": {
                    "type": "boolean",
                    "example": false
                  },
                  "is_undeliverable": {
                    "type": "boolean",
                    "example": false
                  },
                  "is_blocklisted": {
                    "type": "boolean",
                    "example": false
                  }
                }
              }
            }
          },
          "assignee": {
            "type": "object",
            "nullable": true,
            "description": "세션이 할당된 콘솔 검토자 또는 담당자가 없는 경우 `null`입니다.",
            "properties": {
              "email": {
                "type": "string",
                "format": "email"
              },
              "assigned_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          },
          "waiting_since": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "세션이 검토 대기를 시작한 시점입니다. 세션이 `In Review` 상태가 아닌 경우 `null`입니다."
          },
          "sla_due_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Console에서 애플리케이션에 설정된 검토 기한을 기준으로 검토가 완료되어야 하는 시점입니다. 세션이 `In Review` 상태이고 기한이 설정된 경우가 아니면 `null`입니다."
          },
          "top_warnings": {
            "type": "array",
            "description": "빠른 선별 검토를 위한 세션의 가장 중요한 몇 가지 경고입니다. 전체 목록은 결정 내에 있습니다.",
            "items": {
              "type": "object",
              "properties": {
                "risk": {
                  "type": "string",
                  "description": "경고 코드입니다(예: `FACE_MATCH_LOW_SIMILARITY`)."
                },
                "feature": {
                  "type": "string",
                  "description": "이를 발생시킨 기능입니다."
                },
                "log_type": {
                  "type": "string",
                  "nullable": true,
                  "description": "`error` 또는 `warning`, 기존 항목의 경우 `null`."
                },
                "short_description": {
                  "type": "string"
                }
              }
            }
          },
          "warnings_count": {
            "type": "integer",
            "description": "세션의 경고 수입니다."
          }
        }
      },
      "BusinessSessionListItem": {
        "title": "KYB session row (session_kind: business)",
        "type": "object",
        "description": "기업 확인(KYB) 세션의 요약 행입니다. `session_kind`가 `business` 또는 `all`인 경우에만 반환됩니다.",
        "required": [
          "session_id",
          "session_kind",
          "session_number",
          "status",
          "vendor_data",
          "created_at",
          "workflow_id",
          "workflow_type",
          "workflow_label",
          "company_name",
          "registration_number",
          "country"
        ],
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "기업 확인(KYB) 세션의 고유 식별자입니다.",
            "example": "8a1f63c2-1b9e-4f3a-9c41-2f6a1f0b7d52"
          },
          "session_kind": {
            "type": "string",
            "enum": [
              "business"
            ],
            "description": "행 판별자. KYB 행의 경우 항상 `\"business\"`입니다.",
            "example": "business"
          },
          "session_number": {
            "type": "integer",
            "description": "애플리케이션 내 기업 세션의 사람이 읽기 쉬운 순차 번호입니다. KYC 세션과는 별도로 번호가 매겨집니다.",
            "example": 42
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User"
            ],
            "description": "전체 세션 상태입니다. [인증 상태](/ko/integration/verification-statuses) 페이지를 참조하십시오.",
            "example": "Approved"
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "기업에 대한 귀하 고유의 식별자이며, 세션 생성 시 전송된 그대로 다시 반환됩니다.",
            "example": "your-company-id-77"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "세션이 생성된 UTC 타임스탬프입니다.",
            "example": "2026-06-08T09:14:02.118450Z"
          },
          "workflow_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "이 세션 생성에 사용된 워크플로의 식별자입니다.",
            "example": "9f9b1234-aaaa-bbbb-cccc-1234567890ab"
          },
          "workflow_type": {
            "type": "string",
            "nullable": true,
            "description": "워크플로 유형입니다. 기업 워크플로의 경우 `kyb`입니다.",
            "example": "kyb"
          },
          "workflow_label": {
            "type": "string",
            "nullable": true,
            "description": "워크플로의 표시 이름입니다.",
            "example": "Standard KYB"
          },
          "company_name": {
            "type": "string",
            "nullable": true,
            "description": "세션에 연결된 등기부 기업에서 가져온, 인증 중인 기업의 이름입니다. 기업이 선택될 때까지는 `null`입니다.",
            "example": "Acme Holdings S.L."
          },
          "registration_number": {
            "type": "string",
            "nullable": true,
            "description": "세션에 연결된 등기부 기업의 기업 등록번호입니다.",
            "example": "B12345678"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "세션에 연결된 등기 기업의 국가 코드입니다.",
            "example": "ES"
          }
        }
      },
      "TransactionVerificationSessionAction": {
        "title": "Verification session",
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "verification_session"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "최종 사용자에게 열어줄 호스팅 인증 URL입니다."
          },
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "인증 세션 ID입니다."
          },
          "session_token": {
            "type": "string",
            "description": "모바일 SDK에서 플로우를 네이티브로 실행하는 데 사용되는 세션 token입니다."
          },
          "status": {
            "type": "string",
            "description": "인증 세션 상태입니다."
          }
        },
        "required": [
          "type",
          "url"
        ]
      },
      "TransactionWalletOwnershipAction": {
        "title": "Wallet ownership",
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "wallet_ownership"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "호스팅 지갑 소유권 위젯 URL입니다. 실제 브라우저 환경에서 여십시오. 모바일에서는 임베디드 웹뷰를 사용하지 말고 SFSafariViewController 또는 Chrome Custom Tab을 사용하십시오."
          },
          "widget_session_id": {
            "type": "string",
            "format": "uuid",
            "description": "지갑 소유권 위젯 세션 ID입니다."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "위젯 세션이 만료되는 시점입니다."
          }
        },
        "required": [
          "type",
          "url"
        ]
      },
      "TransactionRuleActionAddScore": {
        "type": "object",
        "required": [
          "type",
          "value"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "add_score"
            ]
          },
          "value": {
            "type": "integer",
            "description": "거래의 위험 점수에 추가된 점수입니다. 음수일 수 있습니다."
          }
        },
        "description": "거래의 누적 위험 점수에 점수를 추가합니다. 총합에 따라 애플리케이션의 검토/거부 임계값을 통해 상태가 결정됩니다."
      },
      "TransactionRuleActionChangeStatus": {
        "type": "object",
        "required": [
          "type",
          "value"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "change_status"
            ]
          },
          "value": {
            "type": "string",
            "enum": [
              "APPROVED",
              "IN_REVIEW",
              "DECLINED",
              "AWAITING_USER"
            ],
            "description": "점수와 관계없이 즉시 설정할 상태입니다. 별칭 키: status."
          },
          "workflow_id": {
            "type": "string",
            "format": "uuid",
            "description": "값이 AWAITING_USER일 때 필수: 대상자가 완료하도록 요청받은 인증 워크플로입니다. 별칭 키: remediation_workflow_id. 규칙이 트리거되면 Didit은 대상자를 위한 호스팅 문제 해결 세션을 생성합니다."
          }
        },
        "description": "거래 상태를 직접 설정합니다. 일치하는 규칙들 사이에서 DECLINED가 항상 우선 적용됩니다."
      },
      "TransactionRuleActionAddTags": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "add_tags"
            ]
          },
          "tag_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "연결할 기존 애플리케이션 태그입니다."
          },
          "tag_name": {
            "type": "string",
            "description": "연결할 태그 이름입니다. 처음 사용할 때 생성됩니다(대문자로 저장됨). tag_uuid 또는 tag_name을 제공하십시오."
          },
          "tag_color": {
            "type": "string",
            "description": "tag_name으로 새 태그를 생성할 때 사용되는 16진수 색상 코드입니다(예: #007AFE)."
          }
        },
        "description": "일치하는 거래에 애플리케이션 태그를 첨부합니다."
      },
      "TransactionRuleActionAddNote": {
        "type": "object",
        "required": [
          "type",
          "note"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "add_note"
            ]
          },
          "note": {
            "type": "string",
            "description": "거래에 첨부된 메모 텍스트입니다(작성자: Rule Engine). 별칭 키: 값."
          }
        },
        "description": "일치하는 거래에 자동 분석가 메모를 첨부합니다."
      },
      "TransactionRuleActionAddToList": {
        "type": "object",
        "required": [
          "type",
          "list_id"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "add_to_list"
            ]
          },
          "list_id": {
            "type": "string",
            "format": "uuid",
            "description": "주체의 vendor_data를 추가할 목록입니다."
          }
        },
        "description": "대상자의 vendor_data를 차단 목록, 허용 목록 또는 사용자 지정 목록에 추가합니다."
      },
      "TransactionRuleActionOpenCase": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "open_case"
            ]
          },
          "blueprint": {
            "type": "string",
            "format": "uuid",
            "description": "케이스 블루프린트 UUID. 기본값은 애플리케이션의 기본 블루프린트입니다."
          },
          "grouping": {
            "type": "string",
            "enum": [
              "by_applicant",
              "by_rule_and_applicant"
            ],
            "description": "반복 일치 항목이 신청자당 하나의 케이스로 통합되는지, 아니면 규칙+신청자당 하나로 통합되는지 여부입니다."
          },
          "attach_matched_transaction": {
            "type": "boolean",
            "description": "일치하는 거래를 케이스에 첨부합니다."
          }
        },
        "description": "조사 케이스를 열거나 기존 케이스에 추가합니다. 규칙에서 첫 번째 open_case 작업만 적용됩니다."
      },
      "KYBRegistrySearchResults": {
        "type": "object",
        "properties": {
          "companies": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "kyb_response_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "이 후보에 대한 핸들입니다. 전체 프로필을 조회하려면 `POST /v3/kyb/select/`로 전달하십시오. 임시적이며 이 검색 범위로 제한됩니다. 장기 보관하지 말고 새로운 핸들을 얻으려면 다시 검색하십시오.",
                  "example": "69aeeb95febb0f1704042259"
                },
                "name": {
                  "type": "string",
                  "nullable": true,
                  "description": "등록 회사명입니다.",
                  "example": "Tesco PLC"
                },
                "registration_number": {
                  "type": "string",
                  "nullable": true,
                  "description": "법인 등기부 등록번호입니다.",
                  "example": "00445790"
                },
                "status": {
                  "type": "string",
                  "nullable": true,
                  "description": "기업의 정규화된 등기 상태입니다(예: `active`, `dissolved`, `inactive`, `struck off`).",
                  "example": "active"
                },
                "type": {
                  "type": "string",
                  "nullable": true,
                  "description": "등기소에서 보고된 법적 형태입니다.",
                  "example": "Public Limited Company"
                },
                "registered_address": {
                  "type": "string",
                  "nullable": true,
                  "description": "등기부에서 반환된 경우의 후보 등록 주소입니다. 등록번호와 함께 동일한 이름의 회사를 구별하는 데 사용합니다. 미국의 경우 후보 회사가 검색한 주가 아닌 회사가 운영되는 주에 등재되어 있을 수 있습니다.",
                  "example": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, AL7 1GA"
                },
                "risk_level": {
                  "type": "string",
                  "nullable": true,
                  "description": "제공되는 경우, 법인 등기부에 보고된 위험 수준입니다. 검색 시에는 일반적으로 `null`입니다."
                },
                "fetch_status": {
                  "type": "string",
                  "nullable": true,
                  "description": "검색 후보의 경우 항상 `pending`입니다. 전체 기업 프로필은 후보를 선택할 때만 조회(및 결제)됩니다.",
                  "example": "pending"
                }
              }
            },
            "description": "중복 제거된 후보 목록입니다. `search_resolved=false`(webhook 모드)이거나 일치하는 항목이 없는 경우 비어 있습니다."
          },
          "pagination": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer",
                "description": "반환된 후보 수입니다."
              },
              "page": {
                "type": "integer"
              },
              "per_page": {
                "type": "integer",
                "example": 25
              }
            }
          },
          "search_status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "pending",
              "resolved"
            ],
            "description": "법인 등기부 검색 라이프사이클 상태입니다."
          },
          "search_resolved": {
            "type": "boolean",
            "description": "후보자 목록이 확정되면 `true`입니다."
          }
        }
      },
      "KYBRegistryCandidateRequest": {
        "type": "object",
        "required": [
          "kyb_response_id"
        ],
        "properties": {
          "kyb_response_id": {
            "type": "string",
            "maxLength": 1024,
            "description": "`POST /v3/kyb/search/`의 후보 핸들(`kyb_registry.companies[].kyb_response_id`)입니다. 임시 값이므로 이를 생성한 검색 직후에 사용하십시오. 핸들은 길어질 수 있으므로 잘라내거나 길이를 가정하지 말고 반환된 값을 그대로 저장하고 전송하십시오.",
            "example": "69aeeb95febb0f1704042259"
          },
          "vendor_data": {
            "type": "string",
            "description": "해당 기업에 대한 귀하의 식별자입니다. 기업 세션에 저장되며 그대로 다시 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "description": "기업 세션과 함께 저장되고 그대로 반환되는 자유 형식 JSON입니다."
          },
          "save_api_request": {
            "type": "boolean",
            "default": true,
            "description": "`true`(기본값)여야 합니다. KYB 등기부 선택 항목은 결제 및 조회를 추적할 수 있도록 항상 유지됩니다. `false`는 `400`을 반환합니다."
          }
        }
      },
      "WebhookEventEnvelope": {
        "type": "object",
        "description": "이벤트 유형에 관계없이 Didit이 서명된 모든 webhook 전송에 추가하는 필드입니다. 수신한 payload를 확인하려면 `webhook_type`을 확인하십시오.",
        "required": [
          "event_id",
          "webhook_type",
          "timestamp",
          "created_at",
          "application_id",
          "environment"
        ],
        "properties": {
          "event_id": {
            "type": "string",
            "format": "uuid",
            "description": "이벤트의 식별자입니다. 모든 대상이 동일한 값을 수신하고 재전송 시에도 유지되므로 중복 제거에 사용하십시오."
          },
          "webhook_type": {
            "$ref": "#/components/schemas/WebhookEvent"
          },
          "timestamp": {
            "type": "integer",
            "description": "이 전송이 서명된 Unix 시간(초)입니다. `X-Timestamp` 헤더와 동일하며, 재전송 시에는 새로운 값이 전달됩니다."
          },
          "created_at": {
            "type": "integer",
            "description": "이벤트를 생성한 변경이 발생한 Unix 시간(초)입니다."
          },
          "application_id": {
            "type": "string",
            "format": "uuid",
            "description": "이벤트가 속한 애플리케이션입니다."
          },
          "environment": {
            "type": "string",
            "enum": [
              "live",
              "sandbox"
            ],
            "description": "샌드박스 세션 및 샌드박스 애플리케이션의 경우 `sandbox`, 그렇지 않은 경우 `live`입니다."
          }
        }
      },
      "SessionWebhookEventData": {
        "type": "object",
        "description": "`status.updated` 및 `data.updated`의 세션 필드입니다. 선택적 필드는 해당되지 않을 때 생략되며, 절대 `null`로 전송되지 않습니다. 기업(KYB) 세션에는 `business_session_id`, `session_kind`, `vendor_business_id`가 추가됩니다.",
        "required": [
          "session_id",
          "status",
          "sandbox_scenario"
        ],
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "인증 세션입니다."
          },
          "business_session_id": {
            "type": "string",
            "format": "uuid",
            "description": "기업 확인(KYB) 세션 전용: `session_id`와 동일한 값입니다."
          },
          "session_kind": {
            "type": "string",
            "enum": [
              "business"
            ],
            "description": "기업 확인(KYB) 세션 전용입니다. 사용자(KYC) 세션 이벤트에는 최상위 `session_kind`가 포함되지 않으므로 대신 `decision.session_kind`를 확인하십시오."
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User"
            ],
            "description": "변경 후 세션 상태입니다."
          },
          "trigger": {
            "type": "string",
            "description": "인증 워크플로 자체에서 발생하지 않은 이벤트인 경우 표시됩니다. 예: `manual_review`, `manual_step_update`, `ongoing_monitoring`, `webhook_reconciliation`(첫 번째 최종 webhook이 생성되지 않아 재전송된 `status.updated`이므로 이미 수신한 결정에 대해 두 번째 이벤트를 받을 수 있습니다. `session_id` 및 `status`로 중복을 제거하십시오), `manual_webhook_recovery`, `kyb_registry_change`, `biometric_retention`(세션의 라이브 생체 인식 데이터가 예정대로 삭제될 때 전송되는 `data.updated`) 또는 `console_registry_edit`, `console_key_people_skip`, `console_key_people_regenerate`와 같은 `console_*` 편집."
          },
          "workflow_id": {
            "type": "string",
            "format": "uuid",
            "description": "세션의 워크플로입니다. 세션에 워크플로가 없는 경우 생략됩니다."
          },
          "workflow_version": {
            "type": "integer",
            "description": "세션이 실행한 워크플로의 버전입니다. `workflow_id`와 함께 전송됩니다."
          },
          "vendor_data": {
            "type": "string",
            "description": "세션에 대한 귀하의 `vendor_data`입니다. 비어 있으면 생략됩니다."
          },
          "vendor_business_id": {
            "type": "string",
            "description": "기업 확인(KYB) 세션 전용: 세션이 속한 기업입니다. 없는 경우 생략됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "귀하의 세션 `metadata`입니다. 비어 있으면 생략됩니다."
          },
          "decision": {
            "$ref": "#/components/schemas/SessionDecision"
          },
          "resubmit_info": {
            "type": "object",
            "description": "`status`가 `Resubmitted`인 경우에만 해당합니다: 사용자가 다시 진행해야 하는 단계와 그 이유입니다.",
            "required": [
              "nodes_to_resubmit",
              "reasons"
            ],
            "properties": {
              "nodes_to_resubmit": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "node_id",
                    "feature"
                  ],
                  "properties": {
                    "node_id": {
                      "type": "string",
                      "description": "세션의 워크플로 정의에 표시되는 노드 식별자(예: `feature_ocr`, `feature_liveness`).",
                      "example": "feature_poa"
                    },
                    "feature": {
                      "type": "string",
                      "description": "노드의 기능 유형(예: `OCR`, `LIVENESS`, `PROOF_OF_ADDRESS`).",
                      "example": "PROOF_OF_ADDRESS"
                    }
                  }
                },
                "description": "사용자가 다시 진행해야 하는 워크플로 단계입니다. [Update Status](#patch-/v3/session/-sessionId-/update-status/)의 `nodes_to_resubmit`과 동일한 `{node_id, feature}` 항목입니다."
              },
              "reasons": {
                "type": "object",
                "additionalProperties": true,
                "description": "`nodes_to_resubmit`의 `node_id`별 사유입니다."
              }
            }
          },
          "sandbox_scenario": {
            "type": "string",
            "nullable": true,
            "description": "샌드박스 세션에 설정된 시뮬레이션 결과 또는 `null`입니다. 프로덕션 세션의 경우 항상 `null`입니다."
          }
        }
      },
      "SessionStatusUpdatedEvent": {
        "description": "인증 세션 상태가 변경되었습니다. `decision`은 `Approved`, `Declined`, `In Review`, `Abandoned`에 대해서만 전송됩니다. webhook 버전 3(기본값) 대상의 경우 `GET /v3/session/{sessionId}/decision/` 형태를 가지며, 버전 1 또는 2 대상의 경우 이전 축소 형태를 가집니다. 기업 세션은 항상 버전 3 기업 결정을 수신합니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "$ref": "#/components/schemas/SessionWebhookEventData"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "status.updated"
                ],
                "description": "항상 `status.updated`입니다."
              }
            },
            "required": [
              "webhook_type"
            ]
          }
        ]
      },
      "SessionDataUpdatedEvent": {
        "description": "수동 검토 수정, 단계 오버라이드 또는 지속적인 모니터링 재스크리닝 후와 같이 상태 변경 없이 인증 세션의 데이터가 변경되었습니다. `decision`은 `Approved`, `Declined`, `In Review`, `Abandoned`에 대해서만 전송됩니다. webhook 버전 3(기본값) 대상의 경우 `GET /v3/session/{sessionId}/decision/` 형태를 가지며, 버전 1 또는 2 대상의 경우 이전의 축소된 형태를 가집니다. 기업 세션은 항상 버전 3 기업 결정을 수신합니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "$ref": "#/components/schemas/SessionWebhookEventData"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "data.updated"
                ],
                "description": "항상 `data.updated`입니다."
              }
            },
            "required": [
              "webhook_type"
            ]
          }
        ]
      },
      "UserStatusUpdatedEvent": {
        "description": "사용자 상태가 변경되었습니다. 사용자가 생성될 때는 전송되지 않습니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "user.status.updated"
                ],
                "description": "항상 `user.status.updated`입니다."
              },
              "vendor_user_id": {
                "type": "string",
                "format": "uuid",
                "description": "이벤트 대상 사용자입니다."
              },
              "vendor_data": {
                "type": "string",
                "nullable": true,
                "description": "사용자에 대한 귀하의 `vendor_data` 또는 `null`입니다."
              },
              "status": {
                "type": "string",
                "enum": [
                  "ACTIVE",
                  "IN_REVIEW",
                  "FLAGGED",
                  "BLOCKED"
                ],
                "description": "변경 후 사용자 상태입니다."
              },
              "previous_status": {
                "type": "string",
                "enum": [
                  "ACTIVE",
                  "IN_REVIEW",
                  "FLAGGED",
                  "BLOCKED"
                ],
                "description": "변경 전 상태입니다."
              }
            },
            "required": [
              "webhook_type",
              "vendor_user_id",
              "vendor_data",
              "status",
              "previous_status"
            ]
          }
        ]
      },
      "UserDataUpdatedEvent": {
        "description": "사용자의 필드가 변경되었습니다. 사용자가 생성될 때는 전송되지 않습니다. 한 번의 저장으로 상태 이벤트와 데이터 이벤트가 모두 생성될 수 있습니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "user.data.updated"
                ],
                "description": "항상 `user.data.updated`입니다."
              },
              "vendor_user_id": {
                "type": "string",
                "format": "uuid",
                "description": "이벤트 대상 사용자입니다."
              },
              "vendor_data": {
                "type": "string",
                "nullable": true,
                "description": "사용자에 대한 귀하의 `vendor_data` 또는 `null`입니다."
              },
              "status": {
                "type": "string",
                "enum": [
                  "ACTIVE",
                  "IN_REVIEW",
                  "FLAGGED",
                  "BLOCKED"
                ],
                "description": "변경 후 사용자 상태입니다."
              },
              "changed_fields": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "vendor_data",
                    "display_name",
                    "full_name",
                    "date_of_birth",
                    "metadata",
                    "portrait_image",
                    "issuing_states",
                    "approved_emails",
                    "approved_phones",
                    "features",
                    "session_count",
                    "approved_count",
                    "declined_count",
                    "in_review_count",
                    "first_session_at",
                    "last_session_at"
                  ]
                },
                "description": "변경된 필드의 이름입니다."
              },
              "changes": {
                "type": "object",
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "previous": {
                      "nullable": true,
                      "description": "변경 전 값입니다. 날짜는 ISO 8601 형식의 문자열입니다."
                    },
                    "current": {
                      "nullable": true,
                      "description": "변경 후 값입니다. 날짜는 ISO 8601 형식의 문자열입니다."
                    }
                  }
                },
                "description": "변경된 각 필드의 이전 값 및 현재 값(필드 이름을 키로 사용)입니다. 값에는 개인정보(이름, 생년월일, 인물 사진 링크, 이메일, 전화번호)가 포함될 수 있으므로 이에 맞게 처리하십시오."
              }
            },
            "required": [
              "webhook_type",
              "vendor_user_id",
              "vendor_data",
              "status",
              "changed_fields",
              "changes"
            ]
          }
        ]
      },
      "BusinessStatusUpdatedEvent": {
        "description": "기업의 상태가 변경되었습니다. 기업이 생성될 때는 전송되지 않습니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "business.status.updated"
                ],
                "description": "항상 `business.status.updated`입니다."
              },
              "vendor_business_id": {
                "type": "string",
                "format": "uuid",
                "description": "이벤트의 대상이 되는 기업입니다."
              },
              "vendor_data": {
                "type": "string",
                "nullable": true,
                "description": "기업에 대한 귀하의 `vendor_data` 또는 `null`입니다."
              },
              "status": {
                "type": "string",
                "enum": [
                  "ACTIVE",
                  "IN_REVIEW",
                  "FLAGGED",
                  "BLOCKED"
                ],
                "description": "변경 후 기업 상태입니다."
              },
              "previous_status": {
                "type": "string",
                "enum": [
                  "ACTIVE",
                  "IN_REVIEW",
                  "FLAGGED",
                  "BLOCKED"
                ],
                "description": "변경 전 상태입니다."
              }
            },
            "required": [
              "webhook_type",
              "vendor_business_id",
              "vendor_data",
              "status",
              "previous_status"
            ]
          }
        ]
      },
      "BusinessDataUpdatedEvent": {
        "description": "기업의 필드가 변경되었습니다. 기업이 생성될 때는 전송되지 않습니다. 한 번의 저장으로 상태 이벤트와 데이터 이벤트가 모두 생성될 수 있습니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "business.data.updated"
                ],
                "description": "항상 `business.data.updated`입니다."
              },
              "vendor_business_id": {
                "type": "string",
                "format": "uuid",
                "description": "이벤트의 대상이 되는 기업입니다."
              },
              "vendor_data": {
                "type": "string",
                "nullable": true,
                "description": "기업에 대한 귀하의 `vendor_data` 또는 `null`입니다."
              },
              "status": {
                "type": "string",
                "enum": [
                  "ACTIVE",
                  "IN_REVIEW",
                  "FLAGGED",
                  "BLOCKED"
                ],
                "description": "변경 후 기업 상태입니다."
              },
              "changed_fields": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "vendor_data",
                    "display_name",
                    "metadata",
                    "legal_name",
                    "registration_number",
                    "country_code",
                    "session_count",
                    "approved_count",
                    "declined_count",
                    "in_review_count",
                    "features",
                    "first_session_at",
                    "last_session_at"
                  ]
                },
                "description": "변경된 필드의 이름입니다."
              },
              "changes": {
                "type": "object",
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "previous": {
                      "nullable": true,
                      "description": "변경 전 값입니다. 날짜는 ISO 8601 형식의 문자열입니다."
                    },
                    "current": {
                      "nullable": true,
                      "description": "변경 후 값입니다. 날짜는 ISO 8601 형식의 문자열입니다."
                    }
                  }
                },
                "description": "변경된 각 필드의 이전 값 및 현재 값(필드 이름을 키로 사용)."
              }
            },
            "required": [
              "webhook_type",
              "vendor_business_id",
              "vendor_data",
              "status",
              "changed_fields",
              "changes"
            ]
          }
        ]
      },
      "TransactionCreatedEvent": {
        "description": "거래가 생성되고 스크리닝되었습니다. 프로덕션 애플리케이션에 대해서만 전송됩니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "transaction.created"
                ],
                "description": "항상 `transaction.created`입니다."
              },
              "transaction_id": {
                "type": "string",
                "format": "uuid",
                "description": "해당 거래에 대한 Didit의 식별자입니다."
              },
              "txn_id": {
                "type": "string",
                "nullable": true,
                "description": "생성 시 제공한 `transaction_id` 또는 `null`입니다."
              },
              "status": {
                "type": "string",
                "enum": [
                  "APPROVED",
                  "IN_REVIEW",
                  "DECLINED",
                  "AWAITING_USER"
                ],
                "description": "변경 후 모니터링 상태입니다."
              },
              "score": {
                "type": "integer",
                "description": "규칙에 의해 누적된 위험 점수입니다."
              },
              "severity": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "UNKNOWN",
                  "LOW",
                  "MEDIUM",
                  "HIGH",
                  "CRITICAL",
                  null
                ],
                "description": "위험 심각도이거나, 규칙 또는 제공자가 설정하기 전까지는 `null`입니다."
              },
              "amount": {
                "type": "string",
                "description": "십진수 문자열 형태의 거래 금액입니다. API와 달리 정규화되지 않으므로 끝자리에 0이 포함될 수 있습니다(소수점 이하 최대 18자리)."
              },
              "currency": {
                "type": "string",
                "description": "`amount`의 통화 코드 또는 암호화폐 자산 심볼입니다."
              },
              "direction": {
                "type": "string",
                "enum": [
                  "INBOUND",
                  "OUTBOUND"
                ],
                "description": "주체 기준의 방향입니다."
              },
              "action_required": {
                "type": "object",
                "nullable": true,
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/TransactionVerificationSessionAction"
                  },
                  {
                    "$ref": "#/components/schemas/TransactionWalletOwnershipAction"
                  }
                ],
                "discriminator": {
                  "propertyName": "type",
                  "mapping": {
                    "verification_session": "#/components/schemas/TransactionVerificationSessionAction",
                    "wallet_ownership": "#/components/schemas/TransactionWalletOwnershipAction"
                  }
                },
                "description": "대기 중인 최종 사용자 작업 또는 `null`입니다. 거래의 `action_required`와 동일한 객체입니다. `session_token`은 자격 증명이므로 절대 로그에 기록하지 마세요."
              }
            },
            "required": [
              "webhook_type",
              "transaction_id",
              "txn_id",
              "status",
              "score",
              "severity",
              "amount",
              "currency",
              "direction",
              "action_required"
            ]
          }
        ]
      },
      "TransactionStatusUpdatedEvent": {
        "description": "규칙, 검토 또는 최종 사용자의 작업으로 인해 거래 상태가 변경되었습니다. 프로덕션 애플리케이션에 대해서만 전송됩니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "transaction.status.updated"
                ],
                "description": "항상 `transaction.status.updated`입니다."
              },
              "transaction_id": {
                "type": "string",
                "format": "uuid",
                "description": "해당 거래에 대한 Didit의 식별자입니다."
              },
              "txn_id": {
                "type": "string",
                "nullable": true,
                "description": "생성 시 제공한 `transaction_id` 또는 `null`입니다."
              },
              "status": {
                "type": "string",
                "enum": [
                  "APPROVED",
                  "IN_REVIEW",
                  "DECLINED",
                  "AWAITING_USER"
                ],
                "description": "변경 후 모니터링 상태입니다."
              },
              "score": {
                "type": "integer",
                "description": "규칙에 의해 누적된 위험 점수입니다."
              },
              "severity": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "UNKNOWN",
                  "LOW",
                  "MEDIUM",
                  "HIGH",
                  "CRITICAL",
                  null
                ],
                "description": "위험 심각도이거나, 규칙 또는 제공자가 설정하기 전까지는 `null`입니다."
              },
              "amount": {
                "type": "string",
                "description": "십진수 문자열 형태의 거래 금액입니다. API와 달리 정규화되지 않으므로 끝자리에 0이 포함될 수 있습니다(소수점 이하 최대 18자리)."
              },
              "currency": {
                "type": "string",
                "description": "`amount`의 통화 코드 또는 암호화폐 자산 심볼입니다."
              },
              "direction": {
                "type": "string",
                "enum": [
                  "INBOUND",
                  "OUTBOUND"
                ],
                "description": "주체 기준의 방향입니다."
              },
              "action_required": {
                "type": "object",
                "nullable": true,
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/TransactionVerificationSessionAction"
                  },
                  {
                    "$ref": "#/components/schemas/TransactionWalletOwnershipAction"
                  }
                ],
                "discriminator": {
                  "propertyName": "type",
                  "mapping": {
                    "verification_session": "#/components/schemas/TransactionVerificationSessionAction",
                    "wallet_ownership": "#/components/schemas/TransactionWalletOwnershipAction"
                  }
                },
                "description": "대기 중인 최종 사용자 작업 또는 `null`입니다. 거래의 `action_required`와 동일한 객체입니다. `session_token`은 자격 증명이므로 절대 로그에 기록하지 마세요."
              }
            },
            "required": [
              "webhook_type",
              "transaction_id",
              "txn_id",
              "status",
              "score",
              "severity",
              "amount",
              "currency",
              "direction",
              "action_required"
            ]
          }
        ]
      },
      "TravelRuleStatusUpdatedEvent": {
        "description": "Travel Rule 교환 상태가 변경되었습니다. `FINISHED`, `CANCELLED` 또는 `EXPIRED`를 포함한 모든 전환 시 전송되며, 그 이후에는 전송되지 않습니다. 프로덕션 애플리케이션에 대해 전송되며, Travel Rule 교환의 경우 샌드박스 애플리케이션(`environment: sandbox`)에 대해서도 전송됩니다. 최상위 `status`는 없습니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "travel_rule.status.updated"
                ],
                "description": "항상 `travel_rule.status.updated`입니다."
              },
              "transaction_id": {
                "type": "string",
                "format": "uuid",
                "description": "교환이 속한 거래입니다."
              },
              "txn_id": {
                "type": "string",
                "nullable": true,
                "description": "생성 시 제공한 `transaction_id` 또는 `null`입니다."
              },
              "travel_rule_status": {
                "type": "string",
                "enum": [
                  "AWAITING_COUNTERPARTY",
                  "ON_HOLD",
                  "COMPLETED",
                  "FINISHED",
                  "CANCELLED",
                  "EXPIRED",
                  "COUNTERPARTY_MISMATCHED_DATA",
                  "COUNTERPARTY_VASP_NOT_FOUND",
                  "COUNTERPARTY_VASP_NOT_REACHABLE",
                  "UNCONFIRMED_OWNERSHIP",
                  "COUNTERPARTY_VASP_GENERAL_DECLINE",
                  "NOT_ENOUGH_COUNTERPARTY_DATA",
                  "NOT_APPLICABLE"
                ],
                "description": "변경 후의 교환 상태입니다."
              },
              "rail": {
                "type": "string",
                "enum": [
                  "",
                  "INTERNAL",
                  "TRP",
                  "GTR",
                  "TRUST",
                  "VERIFYVASP",
                  "SYGNA",
                  "EMAIL",
                  "TEST_VASP"
                ],
                "description": "거래소가 사용하는 네트워크이며, 확인할 수 없는 경우 빈 문자열입니다. `TEST_VASP`는 Didit Test VASP가 응답한 샌드박스 전송입니다."
              },
              "test_vasp": {
                "type": "boolean",
                "description": "Didit Test VASP가 응답한 샌드박스 전송에만 존재하며 `true`입니다."
              },
              "test_vasp_scenario": {
                "type": "string",
                "description": "`test_vasp`와 함께만 표시됩니다. 결과를 결정한 샌드박스 시나리오 또는 빈 문자열입니다."
              },
              "direction": {
                "type": "string",
                "enum": [
                  "INBOUND",
                  "OUTBOUND"
                ],
                "description": "이체의 방향입니다."
              }
            },
            "required": [
              "webhook_type",
              "transaction_id",
              "txn_id",
              "travel_rule_status",
              "rail",
              "direction"
            ]
          }
        ]
      },
      "WorkflowComplianceChangedEvent": {
        "description": "재평가 후 게시된 워크플로의 컴플라이언스 상태가 변경되었습니다. 워크플로당 하나의 이벤트가 발생합니다. 최상위 `status`는 없습니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "workflow.compliance_changed"
                ],
                "description": "항상 `workflow.compliance_changed`입니다."
              },
              "workflow_id": {
                "type": "string",
                "format": "uuid",
                "description": "변경된 워크플로입니다."
              },
              "workflow_version": {
                "type": "integer",
                "description": "평가된 버전입니다."
              },
              "workflow_label": {
                "type": "string",
                "nullable": true,
                "description": "워크플로의 표시 이름입니다."
              },
              "transition": {
                "type": "object",
                "required": [
                  "from",
                  "to"
                ],
                "properties": {
                  "from": {
                    "type": "string",
                    "enum": [
                      "compliant",
                      "gaps_detected",
                      "pending_change",
                      "unknown_coverage",
                      "not_evaluated"
                    ],
                    "description": "재평가 전 상태입니다."
                  },
                  "to": {
                    "type": "string",
                    "enum": [
                      "compliant",
                      "gaps_detected",
                      "pending_change",
                      "unknown_coverage",
                      "not_evaluated"
                    ],
                    "description": "재평가 후 상태입니다."
                  }
                }
              },
              "severity": {
                "type": "string",
                "enum": [
                  "actionable",
                  "indicative",
                  "informative"
                ],
                "description": "격차가 감지된 경우 `actionable`, 보류 중인 변경 사항의 경우 `indicative`, 격차가 해결된 경우 `informative`입니다."
              },
              "kb_version": {
                "type": "string",
                "description": "사용된 규제 지식 베이스의 버전입니다."
              }
            },
            "required": [
              "webhook_type",
              "workflow_id",
              "workflow_version",
              "workflow_label",
              "transition",
              "severity",
              "kb_version"
            ]
          }
        ]
      },
      "WebhookEventPayload": {
        "description": "`webhook_type`으로 구분되는 서명된 webhook 전송의 본문입니다. `activity.created`는 구독할 수 있지만 현재는 전송되지 않습니다. 다른 모든 `webhook_type`은 새로운 이벤트 유형으로 처리하고 원시 본문을 유지하십시오.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/SessionStatusUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/SessionDataUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/UserStatusUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/UserDataUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/BusinessStatusUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/BusinessDataUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/TransactionCreatedEvent"
          },
          {
            "$ref": "#/components/schemas/TransactionStatusUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/TravelRuleStatusUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/WorkflowComplianceChangedEvent"
          },
          {
            "$ref": "#/components/schemas/TransactionRuleSuggestionsCreatedEvent"
          }
        ],
        "discriminator": {
          "propertyName": "webhook_type",
          "mapping": {
            "status.updated": "#/components/schemas/SessionStatusUpdatedEvent",
            "data.updated": "#/components/schemas/SessionDataUpdatedEvent",
            "user.status.updated": "#/components/schemas/UserStatusUpdatedEvent",
            "user.data.updated": "#/components/schemas/UserDataUpdatedEvent",
            "business.status.updated": "#/components/schemas/BusinessStatusUpdatedEvent",
            "business.data.updated": "#/components/schemas/BusinessDataUpdatedEvent",
            "transaction.created": "#/components/schemas/TransactionCreatedEvent",
            "transaction.status.updated": "#/components/schemas/TransactionStatusUpdatedEvent",
            "travel_rule.status.updated": "#/components/schemas/TravelRuleStatusUpdatedEvent",
            "workflow.compliance_changed": "#/components/schemas/WorkflowComplianceChangedEvent",
            "transaction_rule_suggestions.created": "#/components/schemas/TransactionRuleSuggestionsCreatedEvent"
          }
        }
      },
      "KYBRegistrySearchResolvedCallback": {
        "type": "object",
        "description": "등기부 검색이 완료되면 `POST /v3/kyb/search/`의 `webhook_url`로 전송되는 콜백의 본문입니다. 서명되지 않습니다. 요청에 `X-Didit-Unsigned-Callback: true`가 포함되고 서명 헤더는 포함되지 않으므로, 시작한 검색의 `request_id`와 대조하여 확인하십시오. `webhook_type`이 아닌 `event_type`을 사용합니다.",
        "required": [
          "event_id",
          "event_type",
          "request_id",
          "vendor_data",
          "metadata",
          "search_status",
          "search_resolved",
          "kyb_registry",
          "timestamp",
          "created_at"
        ],
        "properties": {
          "event_id": {
            "type": "string",
            "format": "uuid",
            "description": "콜백의 식별자입니다."
          },
          "event_type": {
            "type": "string",
            "enum": [
              "kyb.registry_search.resolved"
            ],
            "description": "항상 `kyb.registry_search.resolved`입니다."
          },
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "`POST /v3/kyb/search/`에서 반환된 `request_id`입니다."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "전송한 `vendor_data`의 에코 값입니다."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "전송한 `metadata`의 에코 값입니다."
          },
          "search_status": {
            "type": "string",
            "description": "현재는 항상 `resolved`입니다."
          },
          "search_resolved": {
            "type": "boolean",
            "description": "`search_status`가 `resolved`인 경우 `true`입니다."
          },
          "kyb_registry": {
            "$ref": "#/components/schemas/KYBRegistrySearchResults"
          },
          "timestamp": {
            "type": "integer",
            "description": "콜백이 대기열에 추가된 Unix 시간(초)입니다."
          },
          "created_at": {
            "type": "integer",
            "description": "콜백이 대기열에 추가된 Unix 시간(초)입니다."
          }
        }
      },
      "AMLScreening": {
        "type": "object",
        "properties": {
          "node_id": {
            "type": "string",
            "description": "워크플로 그래프 내 이 AML 단계의 고유 식별자입니다."
          },
          "status": {
            "type": "string",
            "description": "이 AML 스크리닝의 기능 수준 상태입니다. 최상위 세션 `status`와는 독립적입니다. 개별 기능이 `In Review` 상태로 유지되는 동안에도 세션이 전체 결정에 도달할 수 있습니다.",
            "enum": [
              "Not Finished",
              "Approved",
              "Declined",
              "In Review",
              "Resub Requested"
            ]
          },
          "total_hits": {
            "type": "integer",
            "description": "발견된 총 일치 항목 수"
          },
          "entity_type": {
            "type": "string",
            "description": "스크리닝 대상 엔티티 유형: 개인 또는 기업"
          },
          "hits": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "해당 적발 항목에 대한 Didit의 고유 식별자: `hit_` 뒤에 24자리의 16진수 문자가 붙습니다. 대상을 다시 스크리닝할 때 동일하게 일치된 엔터티는 동일한 `id`를 유지합니다. AML 적발 항목 검토 endpoint에 `hit_id`로 전달합니다."
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "description": "일치 항목의 출처 URL"
                },
                "match": {
                  "type": "boolean",
                  "description": "확인된 일치 항목인지 여부"
                },
                "score": {
                  "type": "number",
                  "format": "float",
                  "nullable": true,
                  "minimum": 0,
                  "maximum": 1,
                  "description": "0-1 범위(예: `0.73`)의 지원 중단된 가중 일치 점수입니다. 대신 `match_score`(0-100)를 사용하십시오.",
                  "deprecated": true
                },
                "target": {
                  "type": "boolean",
                  "nullable": true,
                  "description": "일치하는 엔티티가 등재의 직접적인 대상인지(관련 당사자가 아닌지) 여부입니다. 소스에서 이를 지정하지 않은 경우 `null`입니다."
                },
                "caption": {
                  "type": "string",
                  "description": "일치 항목의 캡션 또는 제목"
                },
                "datasets": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "PEP",
                      "PEP Level 1",
                      "PEP Level 2",
                      "PEP Level 3",
                      "PEP Level 4",
                      "Sanctions",
                      "Adverse Media",
                      "Warnings and Regulatory Enforcement",
                      "Fitness and Probity",
                      "SIP",
                      "SIE",
                      "Insolvency",
                      "Other Lists"
                    ]
                  },
                  "description": "일치 항목이 발견된 데이터 세트 카테고리 목록입니다. 해당 엔티티가 정치적 주요 인물(PEP) 목록(등급 포함), 제재 데이터베이스, 부정적 언론 보도, 경고/규제 집행 또는 기타 컴플라이언스 데이터 세트에 나타났는지 여부를 나타냅니다. 엔티티 소스에 이러한 카테고리가 명시되지 않은 경우 `Other Lists`가 됩니다."
                },
                "features": {
                  "type": "object",
                  "nullable": true,
                  "description": "일치 항목의 추가 특징"
                },
                "rca_name": {
                  "type": "string",
                  "description": "해당되는 경우 RCA 이름"
                },
                "last_seen": {
                  "type": "string",
                  "format": "date-time",
                  "description": "일치가 마지막으로 발견된 날짜"
                },
                "risk_view": {
                  "type": "object",
                  "properties": {
                    "crimes": {
                      "type": "object",
                      "properties": {
                        "score": {
                          "type": "integer"
                        },
                        "weightage": {
                          "type": "integer"
                        },
                        "risk_level": {
                          "type": "string"
                        },
                        "risk_scores": {
                          "type": "object"
                        }
                      }
                    },
                    "countries": {
                      "type": "object",
                      "properties": {
                        "score": {
                          "type": "integer"
                        },
                        "weightage": {
                          "type": "integer"
                        },
                        "risk_level": {
                          "type": "string"
                        },
                        "risk_scores": {
                          "type": "object"
                        }
                      }
                    },
                    "categories": {
                      "type": "object",
                      "properties": {
                        "score": {
                          "type": "integer"
                        },
                        "weightage": {
                          "type": "integer"
                        },
                        "risk_level": {
                          "type": "string"
                        },
                        "risk_scores": {
                          "type": "object"
                        }
                      }
                    },
                    "custom_list": {
                      "type": "object"
                    }
                  }
                },
                "first_seen": {
                  "type": "string",
                  "format": "date-time",
                  "description": "일치가 처음 발견된 날짜"
                },
                "properties": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "alias": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "title": {
                      "type": "string",
                      "nullable": true
                    },
                    "gender": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "height": {
                      "type": "string",
                      "nullable": true
                    },
                    "topics": {
                      "type": "string",
                      "nullable": true
                    },
                    "weight": {
                      "type": "string",
                      "nullable": true
                    },
                    "address": {
                      "type": "string",
                      "nullable": true
                    },
                    "country": {
                      "type": "string",
                      "nullable": true
                    },
                    "website": {
                      "type": "string",
                      "nullable": true
                    },
                    "eyeColor": {
                      "type": "string",
                      "nullable": true
                    },
                    "keywords": {
                      "type": "string",
                      "nullable": true
                    },
                    "lastName": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "position": {
                      "type": "string",
                      "nullable": true
                    },
                    "religion": {
                      "type": "string",
                      "nullable": true
                    },
                    "birthDate": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "education": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "ethnicity": {
                      "type": "string",
                      "nullable": true
                    },
                    "firstName": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "hairColor": {
                      "type": "string",
                      "nullable": true
                    },
                    "weakAlias": {
                      "type": "string",
                      "nullable": true
                    },
                    "birthPlace": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "modifiedAt": {
                      "type": "string",
                      "nullable": true
                    },
                    "wikidataId": {
                      "type": "string",
                      "nullable": true
                    },
                    "citizenship": {
                      "type": "string",
                      "nullable": true
                    },
                    "nationality": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                },
                "match_score": {
                  "type": "number",
                  "description": "이름 유사도, 생년월일 및 국가 일치를 바탕으로 계산된 가중 신원 신뢰도 점수(0-100)입니다. 적중 결과가 오탐인지 가능한 일치 항목인지 판별하는 데 사용됩니다.",
                  "format": "float",
                  "nullable": true
                },
                "risk_score": {
                  "type": "number",
                  "description": "엔티티 위험 점수 (0-100). 오탐(False-Positive)이 아닌 적중 중 가장 높은 risk_score를 기반으로 최종 AML 상태(Approved/In Review/Declined)를 결정하는 데 사용됩니다."
                },
                "review_status": {
                  "type": "string",
                  "description": "이 일치 항목의 검토 상태입니다. 'Unreviewed', 'Confirmed Match', 'False Positive' 또는 'Inconclusive'일 수 있습니다.",
                  "enum": [
                    "Unreviewed",
                    "Confirmed Match",
                    "False Positive",
                    "Inconclusive"
                  ]
                },
                "score_breakdown": {
                  "type": "object",
                  "description": "match_score 계산 방식에 대한 상세 내역입니다.",
                  "properties": {
                    "name_score": {
                      "type": "integer",
                      "description": "원시 성명 유사도 백분율(0-100)입니다."
                    },
                    "name_weight": {
                      "type": "integer",
                      "description": "설정(config)의 성명 원래 가중치입니다(0-100)."
                    },
                    "name_weight_normalized": {
                      "type": "number",
                      "description": "누락된 데이터에 대해 가중치를 재조정한 후의 이름 정규화 가중치(0-100)입니다."
                    },
                    "name_contribution": {
                      "type": "number",
                      "description": "총점에 기여한 이름 점수입니다."
                    },
                    "dob_score": {
                      "type": "integer",
                      "description": "생년월일 일치 점수(-100~100)."
                    },
                    "dob_weight": {
                      "type": "integer",
                      "description": "config의 생년월일 원래 가중치입니다(0-100)."
                    },
                    "dob_weight_normalized": {
                      "type": "number",
                      "description": "누락된 데이터에 대해 가중치를 재조정한 후의 생년월일 정규화 가중치(0-100)입니다."
                    },
                    "dob_contribution": {
                      "type": "number",
                      "description": "총점에 기여한 생년월일 점수입니다."
                    },
                    "country_score": {
                      "type": "integer",
                      "description": "국가 일치 점수(-100~100)."
                    },
                    "country_weight": {
                      "type": "integer",
                      "description": "설정(config)의 국가 원래 가중치입니다(0-100)."
                    },
                    "country_weight_normalized": {
                      "type": "number",
                      "description": "누락된 데이터에 대해 가중치를 재조정한 후의 국가 정규화 가중치(0-100)입니다."
                    },
                    "country_contribution": {
                      "type": "number",
                      "description": "총점에 기여한 국가 점수입니다."
                    },
                    "document_number_match_type": {
                      "type": "string",
                      "description": "문서 번호 'Golden Key' 평가 결과입니다.",
                      "enum": [
                        "MATCH",
                        "NEUTRAL",
                        "HARD_MISMATCH"
                      ]
                    },
                    "document_number_effect": {
                      "type": "string",
                      "description": "문서 번호가 점수에 미치는 영향에 대한 사람이 읽기 쉬운 설명입니다."
                    },
                    "total_score": {
                      "type": "integer",
                      "description": "최종 가중 일치 점수(0-100)입니다."
                    }
                  }
                },
                "pep_matches": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "aliases": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "education": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "list_name": {
                        "type": "string"
                      },
                      "publisher": {
                        "type": "string"
                      },
                      "source_url": {
                        "type": "string",
                        "format": "uri"
                      },
                      "description": {
                        "type": "string"
                      },
                      "matched_name": {
                        "type": "string"
                      },
                      "pep_position": {
                        "type": "string"
                      },
                      "date_of_birth": {
                        "type": "string"
                      },
                      "other_sources": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "place_of_birth": {
                        "type": "string"
                      }
                    }
                  }
                },
                "linked_entities": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "active": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "status": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "details": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "relation": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "warning_matches": {
                  "type": "array",
                  "description": "경고 및 규제 집행 일치 항목 목록입니다. 다음 카테고리의 항목이 포함됩니다: Warning, SIP, Warnings and Regulatory Enforcement, Fitness and Probity, SIE, Insolvency.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "list_name": {
                        "type": "string",
                        "description": "경고 목록 게시자의 이름"
                      },
                      "matched_name": {
                        "type": "string",
                        "description": "경고 목록에서 일치한 이름"
                      },
                      "description": {
                        "type": "string",
                        "description": "경고 항목에 대한 설명"
                      },
                      "publisher": {
                        "type": "string",
                        "description": "경고의 게시자 또는 출처"
                      },
                      "source_url": {
                        "type": "string",
                        "format": "uri",
                        "description": "경고 출처의 URL"
                      },
                      "other_sources": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "추가 소스 URL"
                      },
                      "countries": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "nullable": true,
                        "description": "경고와 관련된 국가"
                      },
                      "created_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "경고 항목이 생성된 날짜"
                      },
                      "updated_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "경고 항목이 마지막으로 업데이트된 날짜"
                      },
                      "additional_data": {
                        "type": "object",
                        "description": "경고 출처의 추가 데이터입니다. `case_details` 배열이 포함된 `data` 객체를 포함할 수 있습니다.",
                        "properties": {
                          "data": {
                            "type": "object",
                            "properties": {
                              "case_details": {
                                "type": "array",
                                "description": "이 일치 항목과 관련된 경고 케이스 세부 정보",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "case_type": {
                                      "type": "string",
                                      "description": "경고 케이스 유형",
                                      "enum": [
                                        "Accusation",
                                        "Arrest",
                                        "Bribery",
                                        "Criminal",
                                        "Fraud",
                                        "Illegal Fundraising",
                                        "Non-conviction Terror",
                                        "Proclaimed Offender",
                                        "Regulatory Enforcement",
                                        "Terrorism",
                                        "Terrorism-related",
                                        "Terrorism-related listing"
                                      ]
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "sanction_matches": {
                  "type": "array",
                  "description": "이 엔티티에 대해 발견된 제재 목록 일치 항목 목록입니다.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "list_name": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "nullable": true,
                        "description": "제재 목록 이름"
                      },
                      "matched_name": {
                        "type": "string",
                        "description": "제재 목록에서 일치한 이름"
                      },
                      "description": {
                        "type": "string",
                        "description": "제재 항목에 대한 설명"
                      },
                      "reason": {
                        "type": "string",
                        "nullable": true,
                        "description": "해당 주체가 제재 대상이 된 자유 형식 사유입니다. 제재 목록의 사유 항목들을 결합한 값입니다. 예: 'Executive Order 13224 (Terrorism)', 'Support for actions undermining Ukraine's sovereignty', 'Listed due to national security concerns.'"
                      },
                      "source_url": {
                        "type": "string",
                        "format": "uri",
                        "description": "제재 출처의 URL"
                      },
                      "other_sources": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "추가 소스 URL"
                      },
                      "details": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "제재에 대한 추가 세부 정보"
                      },
                      "legal_basis": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "제재의 법적 근거"
                      },
                      "listed_on": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "nullable": true,
                        "description": "엔티티가 등재된 날짜"
                      },
                      "sanction_list": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "nullable": true,
                        "description": "제재 목록 식별자"
                      },
                      "sanction_program": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "엔티티가 등재된 제재 프로그램"
                      },
                      "sanctioning_authority": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "제재를 부과한 기관"
                      },
                      "updated_on": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "제재 항목이 마지막으로 업데이트된 날짜"
                      },
                      "additional_data": {
                        "type": "object",
                        "description": "주요 필드에 캡처되지 않은 제재 출처의 추가 데이터"
                      }
                    }
                  }
                },
                "adverse_media_details": {
                  "type": "object",
                  "properties": {
                    "sentiment": {
                      "type": "string"
                    },
                    "entity_type": {
                      "type": "string"
                    },
                    "sentiment_score": {
                      "type": "integer"
                    },
                    "adverse_keywords": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "adverse_media_matches": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "country": {
                        "type": "string"
                      },
                      "summary": {
                        "type": "string"
                      },
                      "headline": {
                        "type": "string"
                      },
                      "sentiment": {
                        "type": "string"
                      },
                      "thumbnail": {
                        "type": "string",
                        "format": "uri"
                      },
                      "source_url": {
                        "type": "string",
                        "format": "uri"
                      },
                      "author_name": {
                        "type": "string",
                        "nullable": true
                      },
                      "other_sources": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "adverse_keywords": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "sentiment_score": {
                        "type": "integer"
                      },
                      "publication_date": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "additional_information": {
                  "type": "object"
                }
              }
            }
          },
          "score": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "minimum": 0,
            "maximum": 100,
            "description": "전체 AML 스크리닝 점수 — 모든 일치 항목 중 가장 높은 위험 점수(부동 소수점, 0-100). 계산되기 전까지는 `null`입니다."
          },
          "screened_data": {
            "type": "object",
            "properties": {
              "full_name": {
                "type": "string"
              },
              "nationality": {
                "type": "string"
              },
              "date_of_birth": {
                "type": "string",
                "format": "date"
              },
              "document_number": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "is_ongoing_monitoring_enabled": {
            "type": "boolean",
            "description": "이 스크리닝에 지속적인 AML 모니터링이 활성화되어 있는지 여부입니다. `true`인 경우 엔터티는 주기적으로 재스크리닝되며 새로운 일치 항목이 보고서에 업데이트됩니다."
          },
          "next_ongoing_monitoring_bill_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "이 지속적인 모니터링 구독에 대한 다음 결제일(YYYY-MM-DD)입니다. `is_ongoing_monitoring_enabled = true`인 경우 마지막 지속적인 모니터링 결제일로부터 365일을 더한 날짜로 계산되며, 그렇지 않으면 `null`입니다. 이는 결제일이며 스크리닝 일자가 아닙니다. 스크리닝 일자는 `last_ongoing_screening_at`을 사용하십시오."
          },
          "last_ongoing_screening_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "결과 변경 여부와 관계없이 지속적인 모니터링이 이 레코드의 재스크리닝을 마지막으로 완료한 시점입니다. 레코드가 재스크리닝된 적이 없는 경우 `null`이며, 활성화 또는 결제 날짜로 소급 작성되지 않습니다."
          },
          "last_ongoing_screening_datasets_updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "해당 스크리닝 시점에 제공업체가 보고한 가장 최근의 AML 데이터 세트 업데이트 날짜입니다. 제공업체가 데이터 세트 날짜를 보고하지 않은 경우 `null`이며, 절대 추정되지 않습니다."
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "feature": {
                  "type": "string",
                  "enum": [
                    "ID_VERIFICATION",
                    "NFC",
                    "LIVENESS",
                    "FACEMATCH",
                    "PROOF_OF_ADDRESS",
                    "PHONE",
                    "EMAIL",
                    "AML",
                    "LOCATION",
                    "DATABASE_VALIDATION",
                    "QUESTIONNAIRE",
                    "DOCUMENT_AI",
                    "KYB_REGISTRY",
                    "KYB_DOCUMENTS",
                    "KYB_KEY_PEOPLE",
                    "GEOLOCATION",
                    "SIGNATURE"
                  ],
                  "description": "이 경고를 생성한 기능입니다. 이 값은 경고가 속한 기능 블록을 식별합니다. AML 스크리닝 내에서는 일반적으로 `AML`이지만, 결정 payload의 모든 기능 경고에 대해서는 위의 enum이 기준이 됩니다."
                },
                "risk": {
                  "type": "string"
                },
                "additional_data": {
                  "type": "object",
                  "nullable": true
                },
                "log_type": {
                  "type": "string"
                },
                "short_description": {
                  "type": "string"
                },
                "long_description": {
                  "type": "string"
                },
                "node_id": {
                  "type": "string",
                  "description": "이 경고를 생성한 워크플로 그래프 노드 ID"
                }
              }
            }
          }
        }
      },
      "MonitoringEvent": {
        "type": "object",
        "description": "목록 및 대상자 타임라인 endpoint에서 반환하는 저장된 모니터링 이벤트 1건입니다. 제한된 증거(payload, 기기 컨텍스트, 규칙 증거)는 `GET /v3/events/{event_uuid}/`에서만 반환됩니다.",
        "required": [
          "event_uuid",
          "event_id",
          "event_category",
          "action_type",
          "occurred_at",
          "received_at",
          "status",
          "score",
          "subject_vendor_data",
          "subject_entity_type",
          "subject_uuid",
          "counterparty_vendor_data",
          "session_id",
          "device_fingerprint",
          "ip_address",
          "ip_country",
          "amount",
          "currency",
          "game_id",
          "round_id",
          "bonus_id",
          "affiliate_code",
          "payment_reference_id",
          "retention_class",
          "rules_matched_count",
          "correlation_pending",
          "is_droppable"
        ],
        "properties": {
          "event_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "이벤트의 Didit 식별자입니다. 조회 및 삭제 호출에서 `{event_uuid}`로 사용하세요."
          },
          "event_id": {
            "type": "string",
            "maxLength": 128,
            "description": "전송하신 멱등성 키인 귀하 고유의 식별자입니다."
          },
          "event_category": {
            "type": "string",
            "enum": [
              "auth",
              "session",
              "gameplay",
              "bonus",
              "affiliate",
              "payment",
              "dispute",
              "security",
              "responsible_gambling",
              "custom"
            ],
            "description": "이벤트 카테고리입니다."
          },
          "action_type": {
            "type": "string",
            "maxLength": 128,
            "description": "전송한 카테고리 내에서 발생한 내용입니다."
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "description": "귀하 측에서 이벤트가 발생한 시점입니다."
          },
          "received_at": {
            "type": "string",
            "format": "date-time",
            "description": "Didit이 이벤트를 수락한 시점입니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "ACCEPTED",
              "APPROVED",
              "IN_REVIEW",
              "DECLINED"
            ],
            "description": "`ACCEPTED`: 저장되었으며 일치하는 규칙이 상태를 변경하지 않았습니다(대부분의 이벤트에 대한 일반적인 응답이며, 규칙이 실행되지 않는 샌드박스 애플리케이션에서는 항상 이 응답이 반환됩니다). `APPROVED`: 일치하는 규칙이 있으며 점수가 검토 임계값 미만으로 유지되었습니다. `IN_REVIEW`: 규칙에 의해 점수가 검토 임계값을 초과했거나 해당 상태로 설정되었습니다. `DECLINED`: 규칙에 의해 거부되었거나 점수가 거부 임계값을 초과했습니다."
          },
          "score": {
            "type": "integer",
            "description": "누적된 규칙 점수입니다. 0에서 시작하며, 규칙의 `add_score` 작업에 의해 변경됩니다(음수 델타 허용)."
          },
          "subject_vendor_data": {
            "type": "string",
            "maxLength": 255,
            "description": "이벤트의 `subject.vendor_data`: 사용자 또는 기업에 대한 귀하의 ID입니다."
          },
          "subject_entity_type": {
            "type": "string",
            "description": "`individual` 또는 `company`: `subject_vendor_data`가 가리키는 대상의 종류입니다.",
            "example": "individual"
          },
          "subject_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "이벤트가 확인된 사용자(개인) 또는 회사의 UUID이며, 해당 레코드가 더 이상 존재하지 않는 경우 null입니다."
          },
          "counterparty_vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "P2P 이벤트의 상대방 참여자입니다(`payload.counterparty_vendor_data`에서 승격됨).",
            "maxLength": 255
          },
          "session_id": {
            "type": "string",
            "nullable": true,
            "description": "이벤트와 함께 전송된 `session.session_id`입니다.",
            "maxLength": 255
          },
          "device_fingerprint": {
            "type": "string",
            "nullable": true,
            "description": "이벤트와 함께 전송된 `device_context.fingerprint`.",
            "maxLength": 255
          },
          "ip_address": {
            "type": "string",
            "nullable": true,
            "description": "이벤트의 주소입니다. 서버 레인에서는 전송된 `device_context.network_context.ip_address`이며, 기기 레인에서는 요청의 주소입니다.",
            "maxLength": 64
          },
          "ip_country": {
            "type": "string",
            "nullable": true,
            "description": "IP 보강을 통해 확인된 `ip_address`의 국가 코드이며, 주소가 보강되지 않은 경우(누락되었거나 사설 IP이거나 주소가 이미 알려져 있지 않은 저가치 텔레메트리인 경우) null입니다.",
            "example": "ES"
          },
          "amount": {
            "type": "string",
            "nullable": true,
            "description": "`transaction_context.amount`, `payload.amount`, `payload.stake_amount` 순서대로 가져온 소수점 이하 18자리의 십진수 문자열 금액입니다.",
            "example": "250.000000000000000000"
          },
          "currency": {
            "type": "string",
            "nullable": true,
            "description": "`transaction_context.currency` 또는 `payload.currency`의 통화입니다.",
            "maxLength": 10
          },
          "game_id": {
            "type": "string",
            "nullable": true,
            "description": "`payload.game_id`에서 승격되었습니다.",
            "maxLength": 128
          },
          "round_id": {
            "type": "string",
            "nullable": true,
            "description": "`payload.round_id`에서 승격되었습니다.",
            "maxLength": 128
          },
          "bonus_id": {
            "type": "string",
            "nullable": true,
            "description": "`payload.bonus_id`에서 승격되었습니다.",
            "maxLength": 128
          },
          "affiliate_code": {
            "type": "string",
            "nullable": true,
            "description": "`payload.affiliate_code`에서 승격되었습니다.",
            "maxLength": 128
          },
          "payment_reference_id": {
            "type": "string",
            "nullable": true,
            "description": "`transaction_context.payment_reference_id` 또는 `payload.payment_reference_id`의 결제 참조 번호입니다.",
            "maxLength": 255
          },
          "retention_class": {
            "type": "string",
            "enum": [
              "low_value",
              "standard",
              "risk_relevant",
              "monetary_or_compliance"
            ],
            "description": "보존 클래스입니다. 결제 및 분쟁 이벤트는 `monetary_or_compliance`이고, 보안 및 책임감 있는 도박 이벤트는 `risk_relevant`이며, `session.page_view`, `session.sdk_heartbeat`, `session.sdk_loaded`, `session.device_seen`, `session.bot_signal_observed`, `bonus.promotion_viewed`, `affiliate.referral_clicked`는 `low_value`이고, 그 외 모든 이벤트는 `standard`입니다. 활성 규칙과 일치한 이벤트는 `risk_relevant`로 승격됩니다(강등되지 않음)."
          },
          "rules_matched_count": {
            "type": "integer",
            "minimum": 0,
            "description": "이벤트와 일치한 규칙 수(증거를 기록하지만 작업은 적용하지 않는 `TEST` 모드의 규칙 포함)입니다."
          },
          "correlation_pending": {
            "type": "boolean",
            "description": "이 이벤트에 대해 비동기 규칙(대상 간 상관관계 분석 또는 24시간보다 긴 시퀀스)을 계속 실행해야 하는 동안 `true`입니다. 수 분 내에 해결되며 `status`, `score`, `rules_matched_count`가 그 자리에서 업데이트됩니다."
          },
          "is_droppable": {
            "type": "boolean",
            "description": "백프레셔 상태의 SDK가 이 종류의 이벤트를 삭제할 수 있는지 여부입니다. 모든 `security`, `payment`, `dispute`, `responsible_gambling` 이벤트와 `gameplay.bet_placed`, `gameplay.bet_settled`, `gameplay.p2p_settlement`의 경우 `false`입니다."
          }
        }
      },
      "MonitoringEventDetail": {
        "description": "전체 엔벨로프, 보강 정보 및 규칙 증거가 포함된 모니터링 이벤트 1개입니다. `MonitoringEvent`의 모든 필드와 아래 필드가 포함됩니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/MonitoringEvent"
          },
          {
            "type": "object",
            "required": [
              "payload",
              "custom_values",
              "device_context",
              "field_sources",
              "session_sequence",
              "table_id",
              "hand_id",
              "match_id",
              "market_id",
              "side",
              "role",
              "net_result_amount",
              "payment_fingerprint",
              "instrument_reference_hash",
              "withdrawal_address_hash",
              "dispute_id",
              "chargeback_id",
              "changed_field",
              "identity_match_ref",
              "schema_version",
              "expires_at",
              "rules_evaluated_count",
              "rule_runs",
              "ip_enrichment",
              "subject_profile",
              "tags"
            ],
            "properties": {
              "payload": {
                "type": "object",
                "additionalProperties": true,
                "description": "`payload`로 전송한 카테고리 필드입니다."
              },
              "custom_values": {
                "type": "object",
                "additionalProperties": true,
                "description": "전송한 스칼라 `custom_values`입니다. IP 보강을 통해 주소에 플래그가 지정되었으나 직접 설정하지 않은 경우 Didit에서 `vpn_or_proxy_detected: true` 또는 `is_data_center: true`를 추가합니다."
              },
              "device_context": {
                "type": "object",
                "additionalProperties": true,
                "description": "저장된 기기 컨텍스트입니다. 전송 시의 `device_context`(`fingerprint`, `persistent_device_id`, `bot_score` 포함)와 비워 둔 키에 대해 IP 보강(`ip_country`, `ip_country_code`, `ip_city`, `asn_number`, `asn_organization`, `is_vpn_or_tor`, `is_data_center`, `proxy_type`, `connection_type`)을 통해 완성된 `network_context`가 포함됩니다."
              },
              "field_sources": {
                "type": "object",
                "additionalProperties": {
                  "type": "string",
                  "enum": [
                    "customer",
                    "sdk",
                    "server"
                  ]
                },
                "description": "출처를 나타내는 필드 경로입니다. `customer`(백엔드에서 전송), `sdk`(기기 경로를 통해 전송) 또는 `server`(`received_at` 및 강화된 네트워크 필드 등 Didit에서 파생됨)입니다. 일치 항목에 대한 조치를 취하기 전에 확인하십시오."
              },
              "session_sequence": {
                "type": "integer",
                "format": "int64",
                "nullable": true,
                "description": "이벤트와 함께 전송된 `session.sequence`입니다."
              },
              "table_id": {
                "type": "string",
                "nullable": true,
                "description": "`payload.table_id`에서 승격되었습니다.",
                "maxLength": 128
              },
              "hand_id": {
                "type": "string",
                "nullable": true,
                "description": "`payload.hand_id`에서 승격되었습니다.",
                "maxLength": 128
              },
              "match_id": {
                "type": "string",
                "nullable": true,
                "description": "`payload.match_id`에서 승격되었습니다.",
                "maxLength": 128
              },
              "market_id": {
                "type": "string",
                "nullable": true,
                "description": "`payload.market_id`에서 승격되었습니다.",
                "maxLength": 128
              },
              "side": {
                "type": "string",
                "nullable": true,
                "description": "`payload.side`에서 승격되었습니다.",
                "maxLength": 64
              },
              "role": {
                "type": "string",
                "nullable": true,
                "description": "`payload.role`에서 승격되었습니다.",
                "maxLength": 64
              },
              "net_result_amount": {
                "type": "string",
                "nullable": true,
                "description": "`payload.net_result_amount`에서 승격되었으며, 소수점 이하 18자리의 십진수 문자열입니다.",
                "example": "-120.000000000000000000"
              },
              "payment_fingerprint": {
                "type": "string",
                "nullable": true,
                "description": "`payload.payment_fingerprint`에서 승격되었습니다.",
                "maxLength": 255
              },
              "instrument_reference_hash": {
                "type": "string",
                "nullable": true,
                "description": "`payload.instrument_reference_hash`에서 승격되었습니다.",
                "maxLength": 255
              },
              "withdrawal_address_hash": {
                "type": "string",
                "nullable": true,
                "description": "`payload.withdrawal_address_hash`(또는 `payload.destination_reference_hash`)에서 승격되었습니다.",
                "maxLength": 255
              },
              "dispute_id": {
                "type": "string",
                "nullable": true,
                "description": "`payload.dispute_id`에서 승격되었습니다.",
                "maxLength": 255
              },
              "chargeback_id": {
                "type": "string",
                "nullable": true,
                "description": "`payload.chargeback_id`에서 승격되었습니다.",
                "maxLength": 255
              },
              "changed_field": {
                "type": "string",
                "nullable": true,
                "description": "`payload.changed_field`에서 승격되었습니다(보안 변경 이벤트).",
                "maxLength": 128
              },
              "identity_match_ref": {
                "type": "string",
                "nullable": true,
                "description": "`payload.identity_match_ref`에서 승격되었습니다(책임감 있는 도박 레지스트리 일치).",
                "maxLength": 255
              },
              "schema_version": {
                "type": "integer",
                "description": "이벤트 엔벨로프 스키마의 버전입니다. 현재는 `1`입니다.",
                "example": 1
              },
              "expires_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "이벤트가 보존 등급에 따라 만료되어 삭제되는 시점: `occurred_at`에 등급 기간(기본값은 14, 30 또는 90일이며 애플리케이션별로 조정 가능)을 더한 값입니다. 거래 보존 기간을 따르는 `monetary_or_compliance` 이벤트의 경우 null입니다."
              },
              "rules_evaluated_count": {
                "type": "integer",
                "minimum": 0,
                "description": "이 이벤트에 대해 평가된 이벤트 규칙 수입니다."
              },
              "rule_runs": {
                "type": "array",
                "description": "이벤트와 일치한 모든 규칙(최신순)입니다.",
                "items": {
                  "$ref": "#/components/schemas/MonitoringEventRuleRun"
                }
              },
              "ip_enrichment": {
                "type": "object",
                "nullable": true,
                "description": "이벤트 IP 주소의 보강 데이터이며, 주소가 보강되지 않은 경우 null입니다. [IP 보강](https://docs.didit.me/ko/transaction-monitoring/ip-enrichment)을 참조하세요.",
                "properties": {
                  "ip_country_code": {
                    "type": "string",
                    "nullable": true,
                    "description": "주소의 국가 코드입니다."
                  },
                  "ip_city": {
                    "type": "string",
                    "nullable": true,
                    "description": "주소의 도시입니다."
                  },
                  "asn_number": {
                    "type": "integer",
                    "nullable": true,
                    "description": "자율 시스템 번호(ASN)입니다."
                  },
                  "asn_organization": {
                    "type": "string",
                    "nullable": true,
                    "description": "자율 시스템을 운영하는 조직입니다."
                  },
                  "is_vpn_or_tor": {
                    "type": "boolean",
                    "description": "주소가 알려진 VPN 또는 Tor 출구인지 여부입니다."
                  },
                  "is_data_center": {
                    "type": "boolean",
                    "description": "주소가 호스팅 또는 데이터 센터 네트워크에 속하는지 여부입니다."
                  },
                  "proxy_type": {
                    "type": "string",
                    "nullable": true,
                    "description": "주소의 프록시 분류(불투명 문자열) 또는 null입니다."
                  },
                  "last_enriched_at": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "description": "주소가 마지막으로 보강된 시점입니다."
                  }
                },
                "required": [
                  "ip_country_code",
                  "ip_city",
                  "asn_number",
                  "asn_organization",
                  "is_vpn_or_tor",
                  "is_data_center",
                  "proxy_type",
                  "last_enriched_at"
                ]
              },
              "subject_profile": {
                "type": "object",
                "nullable": true,
                "description": "대상자의 캐시된 이메일 및 전화번호 위험 신호이며, 대상자의 프로필이 없는 경우 null입니다.",
                "properties": {
                  "email_risk_score": {
                    "type": "integer",
                    "nullable": true,
                    "description": "이메일 위험 점수입니다."
                  },
                  "email_deliverability": {
                    "type": "string",
                    "nullable": true,
                    "description": "이메일 전송 가능 여부 판정 결과입니다."
                  },
                  "email_is_disposable": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "이메일 주소가 일회용인지 여부입니다."
                  },
                  "email_is_breached": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "이메일 주소가 알려진 데이터 유출에 나타나는지 여부입니다."
                  },
                  "email_social_count": {
                    "type": "integer",
                    "nullable": true,
                    "description": "이메일 주소에 연결된 온라인 계정 수입니다."
                  },
                  "email_social_providers": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "해당 이메일 주소와 연결된 계정이 발견된 온라인 서비스의 이름입니다."
                  },
                  "phone_risk_score": {
                    "type": "integer",
                    "nullable": true,
                    "description": "전화번호 위험 점수입니다."
                  },
                  "phone_line_type": {
                    "type": "string",
                    "nullable": true,
                    "description": "전화 회선 유형입니다."
                  },
                  "phone_carrier": {
                    "type": "string",
                    "nullable": true,
                    "description": "통신사 이름입니다."
                  },
                  "phone_social_count": {
                    "type": "integer",
                    "nullable": true,
                    "description": "전화번호에 연결된 온라인 계정 수입니다."
                  },
                  "phone_social_providers": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "해당 전화번호와 연결된 계정이 발견된 온라인 서비스의 이름입니다."
                  },
                  "source_provider": {
                    "type": "string",
                    "nullable": true,
                    "description": "프로필 소스의 불투명 식별자입니다."
                  },
                  "last_enriched_at": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "description": "프로필이 마지막으로 새로고침된 시점입니다."
                  }
                },
                "required": [
                  "email_risk_score",
                  "email_deliverability",
                  "email_is_disposable",
                  "email_is_breached",
                  "email_social_count",
                  "email_social_providers",
                  "phone_risk_score",
                  "phone_line_type",
                  "phone_carrier",
                  "phone_social_count",
                  "phone_social_providers",
                  "source_provider",
                  "last_enriched_at"
                ]
              },
              "tags": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "이벤트에 연결된 태그의 이름입니다(규칙의 `add_tags` 작업)."
              }
            }
          }
        ]
      },
      "MonitoringEventRuleRun": {
        "type": "object",
        "properties": {
          "rule_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "거래 모니터링 규칙의 UUID입니다."
          },
          "rule_title": {
            "type": "string",
            "description": "규칙의 제목입니다."
          },
          "library_key": {
            "type": "string",
            "nullable": true,
            "description": "규칙 라이브러리에서 설치된 규칙인 경우의 라이브러리 키이며, 그렇지 않은 경우 null입니다."
          },
          "matched": {
            "type": "boolean",
            "description": "항상 `true`입니다. 일치하는 실행만 기록됩니다."
          },
          "mode": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "TEST"
            ],
            "description": "규칙이 실행되었을 때의 모드입니다. `TEST` 실행은 증거를 기록하지만 어떠한 작업도 적용하지 않았습니다."
          },
          "is_async": {
            "type": "boolean",
            "description": "실행이 수집 요청 대신 비동기 상관관계 분석 패스에서 비롯된 경우 `true`입니다."
          },
          "severity": {
            "type": "string",
            "nullable": true,
            "enum": [
              "UNKNOWN",
              "LOW",
              "MEDIUM",
              "HIGH",
              "CRITICAL",
              null
            ],
            "description": "규칙의 심각도입니다. `TEST` 실행 및 심각도가 없는 규칙의 경우 Null입니다."
          },
          "score_delta": {
            "type": "integer",
            "description": "이번 실행으로 이벤트의 점수가 변경된 정도입니다(`TEST` 실행의 경우 0)."
          },
          "action_summary": {
            "type": "string",
            "nullable": true,
            "description": "적용된 작업에 대한 짧은 요약입니다(예: `score +40; add_tag:VPN_LOGIN`). 적용된 작업이 없으면 null입니다."
          },
          "matched_payload": {
            "type": "array",
            "description": "일치한 조건 및 집계입니다. 조건 항목에는 `field`, `operator`, `expected_value`, `current_value`, `matched`, `group_index`, `group_logic`, `field_source`(`server`, `sdk` 또는 `customer`)가 포함되며, 집계 항목에는 `metric`, `field`, `operator`, `expected_value`, `computed_value`, `window`, `filters`, `matched`, `sample_references`가 포함됩니다.",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "규칙 실행이 기록된 시점입니다."
          }
        },
        "required": [
          "rule_uuid",
          "rule_title",
          "library_key",
          "matched",
          "mode",
          "is_async",
          "severity",
          "score_delta",
          "action_summary",
          "matched_payload",
          "created_at"
        ]
      },
      "MonitoringEventPage": {
        "type": "object",
        "description": "최신 `occurred_at` 순으로 정렬된 모니터링 이벤트 페이지 하나입니다.",
        "required": [
          "count",
          "next",
          "previous",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "description": "일치하는 이벤트 수이며, 최대 100개까지 정확하고 그 이상은 100개로 제한됩니다. 이를 바탕으로 페이지 수를 계산하지 마십시오. null이 될 때까지 `next`를 따르십시오."
          },
          "next": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "다음 페이지의 URL이며, 마지막 페이지에서는 null입니다."
          },
          "previous": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "이전 페이지의 URL이며, 첫 번째 페이지에서는 null입니다."
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MonitoringEvent"
            }
          }
        }
      },
      "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"
          }
        }
      },
      "MonitoringEventIngestResult": {
        "type": "object",
        "description": "단일 이벤트 수집 결과입니다. 새 이벤트와 멱등한 재생 모두에 대해 동일한 형태가 반환됩니다.",
        "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": "저장된 이벤트의 Didit 식별자입니다."
          },
          "event_id": {
            "type": "string",
            "description": "귀하의 `event_id`입니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "ACCEPTED",
              "APPROVED",
              "IN_REVIEW",
              "DECLINED"
            ],
            "description": "실시간 규칙 실행 후 상태입니다. `MonitoringEvent.status`를 참조하세요."
          },
          "score": {
            "type": "integer",
            "description": "실시간 규칙이 실행된 후의 점수입니다."
          },
          "rules_evaluated_count": {
            "type": "integer",
            "minimum": 0,
            "description": "요청에서 평가된 이벤트 규칙 수입니다. 규칙이 실행되지 않는 샌드박스 애플리케이션에서는 0입니다."
          },
          "rules_matched_count": {
            "type": "integer",
            "minimum": 0,
            "description": "`TEST` 모드 규칙을 포함하여 일치한 규칙 수입니다."
          },
          "correlation_pending": {
            "type": "boolean",
            "description": "비동기 규칙이 아직 실행되어야 하는 경우 `true`입니다. 최종 `status` 및 `score`를 확인하려면 몇 분 후에 `GET /v3/events/{event_uuid}/`를 호출하십시오."
          },
          "retention_class": {
            "type": "string",
            "enum": [
              "low_value",
              "standard",
              "risk_relevant",
              "monetary_or_compliance"
            ],
            "description": "일치한 규칙에 의해 승격된 후의 보존 클래스입니다."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "이벤트가 보존 등급에 따라 만료되어 삭제되는 시점입니다. `monetary_or_compliance`(결제 및 분쟁) 이벤트의 경우 null입니다."
          },
          "idempotent_replay": {
            "type": "boolean",
            "description": "이 `event_id` 및 동일한 내용을 가진 이벤트가 이미 저장되어 있는 경우 `true`입니다. 값은 저장된 이벤트의 값이며 규칙이 다시 실행되지 않았습니다."
          },
          "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`입니다."
                }
              }
            }
          }
        }
      },
      "ComplianceList": {
        "type": "object",
        "description": "단일 애플리케이션의 차단 목록, 허용 목록 또는 커스텀 목록입니다.",
        "required": [
          "uuid",
          "name",
          "description",
          "list_type",
          "entry_type",
          "is_system",
          "entry_count",
          "last_entry_added_at",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "목록 식별자입니다. 목록 및 항목 endpoint에서 `list_uuid`로 사용하며, `value_type: \"list\"`가 설정된 워크플로 또는 거래 규칙 조건의 값으로 사용합니다."
          },
          "name": {
            "type": "string",
            "maxLength": 255,
            "description": "목록 이름이며, 애플리케이션의 목록 간에 고유해야 합니다."
          },
          "description": {
            "type": "string",
            "description": "자유 형식 설명입니다. 설정되지 않은 경우 빈 문자열입니다."
          },
          "list_type": {
            "type": "string",
            "enum": [
              "blocklist",
              "allowlist",
              "custom"
            ],
            "description": "`blocklist`: 일치하는 항목이 있으면 세션이나 거래를 거부합니다(시스템 목록 전용, 항목 유형당 하나). `allowlist`: 일치하는 항목을 신뢰합니다(예: 얼굴 허용 목록은 중복 얼굴 작업을 건너뜀). 차단 목록 일치 항목을 재지정할 수는 없습니다. `custom`: 워크플로 및 거래 규칙 조건(`value_type: \"list\"`)에서 사용됩니다."
          },
          "entry_type": {
            "type": "string",
            "enum": [
              "face",
              "document",
              "phone",
              "email",
              "ip_address",
              "device_fingerprint",
              "wallet_address",
              "bank_account",
              "country",
              "user",
              "business",
              "key"
            ],
            "description": "목록에 포함되는 항목 유형입니다. `face`, `document`(문서 번호), `phone`, `email`, `ip_address`(IP 주소 또는 CIDR 범위), `device_fingerprint`, `wallet_address`, `bank_account`, `country`(ISO 3166-1 alpha-3), `user` 또는 `business`(귀하의 `vendor_data`), 또는 `key`(모든 문자열)입니다. 항목 값이 검증되고 일치되는 방식을 결정합니다."
          },
          "is_system": {
            "type": "boolean",
            "description": "Didit이 제공하는 목록의 경우 `true`입니다. 항목 유형당 하나의 차단 목록(`face`, `document`, `phone`, `email`, `ip_address`, `device_fingerprint`, `wallet_address`, `bank_account`, `user`, `business`), **고위험 국가** 맞춤 목록 및 시스템 허용 목록이 해당됩니다. 시스템 목록은 이름을 변경하거나 편집 또는 삭제할 수 없으며, 항목의 추가 및 삭제만 가능합니다."
          },
          "entry_count": {
            "type": "integer",
            "minimum": 0,
            "description": "현재 목록에 있는 항목 수입니다."
          },
          "last_entry_added_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "가장 최근의 현재 항목이 추가된 시점입니다. 빈 목록의 경우 `null`입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "목록이 생성된 시점입니다."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "목록이 마지막으로 업데이트된 시점입니다."
          }
        }
      },
      "ComplianceListEntry": {
        "type": "object",
        "description": "목록 내의 값 1개입니다.",
        "required": [
          "uuid",
          "value",
          "display_label",
          "comment",
          "added_by",
          "reference_session_id",
          "reference_session_number",
          "reference_session_type",
          "reference_object_uuid",
          "metadata",
          "created_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "항목 식별자. 목록 항목 삭제에서 `entry_uuid`로 사용합니다."
          },
          "value": {
            "type": "string",
            "description": "목록에 등록된 값: E.164 형식의 전화번호, 이메일 주소, 문서 번호, IP 주소 또는 CIDR 범위, 기기 지문, 지갑 주소, 은행 계좌, ISO 3166-1 alpha-3 국가 코드, `vendor_data`, `key` 목록의 모든 문자열, 또는 얼굴 목록에 저장된 얼굴의 UUID입니다. 전송하는 값은 전화번호와 국가 코드를 제외하고 소문자로 저장됩니다. 일치 여부 확인 시 대소문자를 구분하지 않습니다."
          },
          "display_label": {
            "type": "string",
            "nullable": true,
            "maxLength": 512,
            "description": "사람이 읽기 쉬운 라벨입니다. 아무것도 전송하지 않으면 Didit이 세션에서 가져온 항목(예: 소지자의 성명 및 문서 번호)으로 채웁니다."
          },
          "comment": {
            "type": "string",
            "description": "자유 형식 메모입니다. 설정되지 않은 경우 빈 문자열입니다."
          },
          "added_by": {
            "type": "string",
            "nullable": true,
            "description": "항목을 추가한 주체: `api`(API 키), 콘솔 사용자의 이메일 주소 또는 `console`, `system` 또는 `migration`(Didit이 생성한 항목), 또는 `rule`(거래 규칙 또는 모니터링 규칙의 작업)."
          },
          "reference_session_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "해당 항목을 가져온 인증 세션입니다. 항목이 값으로 직접 추가된 경우 `null`입니다."
          },
          "reference_session_number": {
            "type": "integer",
            "nullable": true,
            "description": "콘솔에 표시되는 해당 세션의 애플리케이션별 번호입니다."
          },
          "reference_session_type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "kyc",
              "kyb",
              null
            ],
            "description": "개인 인증 세션인 경우 `kyc`, 기업 확인 세션인 경우 `kyb`, 세션이 없는 경우 `null`입니다."
          },
          "reference_object_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "항목이 나타내는 레코드입니다. 세션에서 읽은 얼굴, 문서, 전화번호 또는 이메일 레코드, 목록에 얼굴 업로드를 통해 생성된 얼굴, 또는 전송한 UUID(예: 거래 UUID 또는 사용자의 `didit_internal_id`)입니다."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "추가 컨텍스트입니다. 항목 생성 시 전송한 `metadata`와 병합된 Didit이 설정한 키(여기에 나열됨)가 포함되며, 저장된 그대로 반환됩니다. 없는 경우 `null`입니다.",
            "properties": {
              "reference_image_url": {
                "type": "string",
                "description": "얼굴 항목: 호출마다 새로 발급되는 단기 서명된 URL입니다. `media: read` 권한이 없는 범위 지정 API 키의 경우 `null`입니다. 해당 항목에 이미지가 없으면 생략됩니다."
              },
              "front_image_url": {
                "type": "string",
                "description": "문서 앞면 이미지를 포함하는 문서 항목: 호출할 때마다 다시 발급되는 수명이 짧은 서명된 URL입니다. `media: read` 권한이 없는 범위가 지정된 API 키의 경우 `null`입니다."
              },
              "full_name": {
                "type": "string",
                "description": "세션에서 가져온 문서 항목: 소지자의 성명입니다."
              },
              "issuing_state": {
                "type": "string",
                "description": "세션에서 가져온 문서 항목: ISO 3166-1 alpha-3 발급 국가입니다."
              },
              "document_type": {
                "type": "string",
                "description": "세션에서 가져온 문서 항목: 문서 유형 코드(예: `P`, `ID`, `DL`)입니다."
              },
              "region": {
                "type": "string",
                "description": "세션에서 가져온 문서 항목: 지역에서 발급된 문서의 발급 주 또는 도이며, 해당하지 않는 경우 비어 있습니다. 세션 항목을 차단 목록에 추가해도 설정되지 않습니다."
              },
              "document_number": {
                "type": "string",
                "description": "세션에서 가져온 문서 항목: 문서 번호입니다."
              },
              "face_image_source": {
                "type": "string",
                "enum": [
                  "front_image_camera_front",
                  "back_image_camera_front"
                ],
                "description": "문서 캡처 셀피에서 가져온 얼굴 항목: 셀피 구분입니다. 라이브니스 얼굴인 경우 없습니다."
              },
              "reference_node_id": {
                "type": "string",
                "nullable": true,
                "description": "문서 캡처 셀피에서 가져온 얼굴 항목: 셀피가 생성된 신분증 인증 노드입니다."
              },
              "fingerprint_tier": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "persistent_id",
                  "composite_hash",
                  "legacy_fp",
                  "unknown",
                  null
                ],
                "description": "세션에서 수집된 기기 핑거프린트 항목(핑거프린트가 파생된 방식)입니다. `persistent_id`는 단일 기기를 식별하며, `composite_hash` 및 `legacy_fp`는 동일한 모델의 기기 간에 공유될 수 있습니다."
              },
              "sandbox": {
                "type": "boolean",
                "description": "샌드박스 애플리케이션에 업로드된 얼굴 항목인 경우 `true`입니다. 이러한 항목은 어떤 것과도 일치하지 않습니다."
              },
              "reference_type": {
                "type": "string",
                "enum": [
                  "transaction",
                  "vendor_user",
                  "vendor_business"
                ],
                "description": "사용자가 직접 설정: 콘솔에서 다시 연결할 수 있도록 `reference_object_uuid`가 가리키는 대상입니다."
              },
              "reference_id": {
                "type": "string",
                "description": "사용자가 직접 설정: 소스 레코드의 식별자입니다."
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "항목이 추가된 시점입니다."
          }
        }
      },
      "BlocklistedItem": {
        "type": "object",
        "description": "인증 세션에서 차단 목록에 등록된 얼굴, 신분증, 전화번호 또는 이메일 주소 1개입니다. 해당 항목의 `type`에 적용되지 않는 필드는 `null`입니다.",
        "required": [
          "type",
          "session_id",
          "session_number",
          "blocklisted_at",
          "face_image",
          "document_type",
          "document_number",
          "front_image",
          "phone_number",
          "country_code",
          "email"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "face",
              "document",
              "phone",
              "email"
            ],
            "description": "차단 목록에 추가된 항목입니다."
          },
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "해당 항목이 속한 인증 세션입니다."
          },
          "session_number": {
            "type": "integer",
            "nullable": true,
            "description": "콘솔에 표시되는 해당 세션의 애플리케이션별 번호입니다."
          },
          "blocklisted_at": {
            "type": "string",
            "format": "date-time",
            "description": "항목이 마지막으로 차단 목록에 등록된 시점입니다."
          },
          "face_image": {
            "type": "string",
            "nullable": true,
            "description": "얼굴 항목: 호출마다 새로 발급되는 단기 서명된 URL입니다. `media: read` 권한이 없는 범위 지정 API 키의 경우 `null`입니다. 참조 이미지가 저장되어 있지 않은 경우에도 `null`입니다."
          },
          "document_type": {
            "type": "string",
            "nullable": true,
            "description": "문서 항목: 문서 유형 코드입니다(예: `P`(여권), `ID`(주민등록증/신분증), `DL`(운전면허증), `RP`(거주 허가증))."
          },
          "document_number": {
            "type": "string",
            "nullable": true,
            "description": "문서 항목: 문서 번호 또는 문서에 번호가 없는 경우 개인 식별 번호입니다."
          },
          "front_image": {
            "type": "string",
            "nullable": true,
            "description": "문서 항목: 문서 앞면 이미지로, 호출할 때마다 다시 발급되는 수명이 짧은 서명된 URL입니다. `media: read` 권한이 없는 범위가 지정된 API 키의 경우 `null`입니다."
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "전화번호 항목: E.164 형식의 전화번호입니다."
          },
          "country_code": {
            "type": "string",
            "nullable": true,
            "description": "전화번호 항목: 해당 번호의 ISO 3166-1 alpha-2 국가입니다."
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "이메일 항목: 이메일 주소입니다."
          }
        }
      },
      "TransactionNote": {
        "type": "object",
        "description": "모니터링되는 거래의 검토 타임라인에 있는 메모 1개입니다.",
        "required": [
          "uuid",
          "note",
          "actor_email",
          "actor_name",
          "metadata",
          "created_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "메모 식별자입니다."
          },
          "note": {
            "type": "string",
            "description": "일반 텍스트 메모 본문입니다."
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "description": "메모를 작성하거나 상태를 변경한 Console 사용자의 이메일입니다. API 키로 생성된 메모 및 Didit이 자동으로 추가한 메모의 경우 `null`입니다."
          },
          "actor_name": {
            "type": "string",
            "nullable": true,
            "description": "콘솔 사용자의 표시 이름(이름이 없는 경우 이메일)입니다. Didit이 자동으로 추가하는 메모에는 `Rule Engine`으로 표시됩니다. API 키로 생성된 메모의 경우 `null`입니다."
          },
          "metadata": {
            "type": "object",
            "description": "메모 유형을 구분합니다. API나 콘솔을 통해 작성된 메모에는 `mentioned_emails`가 포함됩니다. 콘솔에서 변경된 상태에는 `previous_status`, `new_status`, `reason_code`, `reason_label`과 함께 `type: status_change`가 포함됩니다. Didit이 추가하는 메모에는 규칙의 `add_note` 작업에 대한 `source`: `rule_action`(`rule_uuid` 포함), 또는 사용자 작업 인증 세션을 생성하는 중 발생한 문제에 대한 `remediation_session`이 포함됩니다.",
            "properties": {
              "mentioned_emails": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "email"
                },
                "description": "멘션된 조직 멤버 목록으로, 소문자로 변환되고 중복이 제거됩니다. 아무도 멘션되지 않은 경우 비어 있습니다."
              },
              "type": {
                "type": "string",
                "enum": [
                  "status_change"
                ],
                "description": "콘솔에서 변경된 상태를 기록하는 메모에 표시됩니다."
              },
              "previous_status": {
                "type": "string",
                "enum": [
                  "APPROVED",
                  "IN_REVIEW",
                  "DECLINED",
                  "AWAITING_USER"
                ],
                "description": "변경 전 상태입니다."
              },
              "new_status": {
                "type": "string",
                "enum": [
                  "APPROVED",
                  "IN_REVIEW",
                  "DECLINED",
                  "AWAITING_USER"
                ],
                "description": "변경 후 상태입니다."
              },
              "reason_code": {
                "type": "string",
                "nullable": true,
                "description": "변경과 함께 제공된 사유 코드입니다."
              },
              "reason_label": {
                "type": "string",
                "nullable": true,
                "description": "변경과 함께 제공된 사유 라벨입니다."
              },
              "source": {
                "type": "string",
                "enum": [
                  "rule_action",
                  "remediation_session"
                ],
                "description": "Didit이 자동으로 추가하는 메모에 표시됩니다."
              },
              "rule_uuid": {
                "type": "string",
                "format": "uuid",
                "description": "`add_note` 작업을 통해 메모를 작성한 규칙(`source: rule_action` 포함)."
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "메모가 저장된 시점입니다."
          }
        }
      },
      "TransactionSummary": {
        "type": "object",
        "description": "모니터링된 거래의 요약 정보로, `GET /v3/transactions/`가 나열하는 형태입니다. 당사자, 알림 및 규칙 실행에 대한 정보를 보려면 `uuid`를 사용하여 `GET /v3/transactions/{transaction_id}/`를 호출하세요.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Didit 거래 UUID입니다. 거래 endpoint에서 `{transaction_id}`로 사용하세요."
          },
          "transaction_number": {
            "type": "integer",
            "nullable": true,
            "description": "Console에 표시되는 애플리케이션별 순차 번호입니다."
          },
          "txn_id": {
            "type": "string",
            "nullable": true,
            "description": "생성 호출 시 제공된 귀하 고유의 식별자입니다. 애플리케이션당 고유합니다."
          },
          "transaction_type": {
            "type": "string",
            "description": "저장된 카테고리: `finance`, `kyc`, `travelRule`, `userPlatformEvent`, `gamblingBet`, `gamblingLimitChange`, `gamblingBonusChange` 또는 `auditTrailEvent`."
          },
          "action_type": {
            "type": "string",
            "description": "카테고리 내 하위 유형입니다(예: `withdrawal`)."
          },
          "status": {
            "type": "string",
            "enum": [
              "APPROVED",
              "IN_REVIEW",
              "DECLINED",
              "AWAITING_USER"
            ],
            "description": "현재 모니터링 판정 결과입니다."
          },
          "source": {
            "type": "string",
            "enum": [
              "LIVE",
              "IMPORTED"
            ],
            "description": "모니터링을 위해 제출된 거래의 경우 `LIVE`, 과거 데이터 가져오기의 경우 `IMPORTED`."
          },
          "direction": {
            "type": "string",
            "enum": [
              "INBOUND",
              "OUTBOUND"
            ],
            "description": "주체 기준의 방향입니다."
          },
          "amount": {
            "type": "string",
            "description": "끝의 0이 제거된 십진수 문자열 형태의 금액입니다(최대 소수점 이하 18자리)."
          },
          "currency": {
            "type": "string",
            "description": "`amount`의 통화 코드 또는 암호화폐 자산 심볼입니다."
          },
          "currency_type": {
            "type": "string",
            "nullable": true,
            "description": "알려진 경우 `fiat` 또는 `crypto`."
          },
          "preferred_currency_amount": {
            "type": "string",
            "nullable": true,
            "description": "환율이 제공되는 경우 애플리케이션의 선호 통화로 변환된 `amount`입니다."
          },
          "preferred_currency_code": {
            "type": "string",
            "nullable": true,
            "description": "`preferred_currency_amount`의 통화입니다."
          },
          "payment_details": {
            "type": "string",
            "nullable": true,
            "description": "자유 형식 결제 참조입니다."
          },
          "txn_date": {
            "type": "string",
            "format": "date-time",
            "description": "거래가 발생한 시점입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Didit이 이를 기록한 시점입니다."
          },
          "score": {
            "type": "integer",
            "description": "위험 점수. 높을수록 위험합니다."
          },
          "severity": {
            "type": "string",
            "nullable": true,
            "enum": [
              "UNKNOWN",
              "LOW",
              "MEDIUM",
              "HIGH",
              "CRITICAL",
              null
            ],
            "description": "위험 심각도이며, 설정되기 전까지는 `null`입니다."
          },
          "decision_reason_code": {
            "type": "string",
            "nullable": true,
            "description": "현재 `status`에 대한 기계 판독 가능한 사유."
          },
          "decision_reason_label": {
            "type": "string",
            "nullable": true,
            "description": "`decision_reason_code`에 대한 사람이 읽기 쉬운 라벨입니다."
          },
          "tags": {
            "type": "array",
            "description": "거래의 태그입니다.",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": "string",
                  "description": "16진수 색상 코드입니다(예: `#F59E0B`)."
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "didit",
                    "custom"
                  ],
                  "description": "Didit 프리셋 또는 커스텀 태그입니다."
                }
              }
            }
          },
          "subject_name": {
            "type": "string",
            "nullable": true,
            "description": "`APPLICANT` 당사자의 성명입니다."
          },
          "subject_vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "신청인에 대한 귀하의 `vendor_data`입니다."
          },
          "subject_type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "user",
              "business",
              null
            ],
            "description": "신청자가 Didit 사용자 또는 기업에 연결되어 있는지 여부입니다. 둘 다 연결되어 있지 않은 경우 `null`입니다."
          },
          "subject_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "신청자가 연결된 Didit 사용자 또는 기업의 UUID입니다."
          },
          "subject_country": {
            "type": "string",
            "nullable": true,
            "description": "신청인의 국가 코드입니다."
          },
          "counterparty_name": {
            "type": "string",
            "nullable": true,
            "description": "`COUNTERPARTY` 당사자의 성명(있는 경우)입니다."
          },
          "counterparty_vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "거래 상대방에 대한 귀하의 `vendor_data`입니다."
          },
          "counterparty_country": {
            "type": "string",
            "nullable": true,
            "description": "거래 상대방의 국가 코드입니다."
          },
          "assigned_to_name": {
            "type": "string",
            "nullable": true,
            "description": "거래에 배정된 Console 검토자의 이름입니다."
          },
          "travel_rule_status": {
            "type": "string",
            "nullable": true,
            "description": "거래의 Travel Rule 전송 상태이며, 없는 경우 `null`입니다."
          },
          "application_id": {
            "type": "string",
            "format": "uuid",
            "description": "거래를 소유한 애플리케이션입니다."
          },
          "application_name": {
            "type": "string",
            "nullable": true,
            "description": "해당 애플리케이션의 이름입니다."
          },
          "organization_id": {
            "type": "string",
            "format": "uuid",
            "description": "애플리케이션을 소유한 조직입니다."
          },
          "organization_name": {
            "type": "string",
            "nullable": true,
            "description": "해당 조직의 이름입니다."
          }
        }
      },
      "ApplicationAnalyticsDataPoint": {
        "type": "object",
        "description": "생성 날짜(UTC) 기준 하루 동안의 세션 수입니다. 각 개수는 세션의 현재 상태를 반영합니다. 이전 기간의 데이터 포인트는 최소한 필수 필드를 포함합니다.",
        "required": [
          "rounded_date",
          "total",
          "approved",
          "declined",
          "canceled",
          "pending"
        ],
        "properties": {
          "rounded_date": {
            "type": "string",
            "format": "date",
            "description": "날짜, `YYYY-MM-DD`."
          },
          "total": {
            "type": "integer",
            "description": "해당 날짜에 생성된 세션입니다."
          },
          "approved": {
            "type": "integer",
            "description": "그 중 `Approved` 또는 `Kyc Expired` 상태인 세션입니다."
          },
          "declined": {
            "type": "integer",
            "description": "`Declined` 상태의 세션입니다."
          },
          "canceled": {
            "type": "integer",
            "description": "`Expired` 또는 `Abandoned` 상태의 세션입니다."
          },
          "pending": {
            "type": "integer",
            "description": "`Not Started`, `In Progress` 또는 `In Review` 상태의 세션입니다."
          },
          "in_review": {
            "type": "integer",
            "description": "`In Review` 상태의 세션입니다."
          },
          "expired": {
            "type": "integer",
            "description": "`Expired` 상태의 세션입니다."
          },
          "abandoned": {
            "type": "integer",
            "description": "`Abandoned` 상태의 세션입니다."
          },
          "in_progress": {
            "type": "integer",
            "description": "`In Progress` 상태의 세션입니다."
          },
          "not_started": {
            "type": "integer",
            "description": "`Not Started` 상태의 세션입니다."
          },
          "manually_approved": {
            "type": "integer",
            "description": "워크플로에서 다른 판정을 내린 후 검토자가 승인한 세션입니다."
          },
          "manually_declined": {
            "type": "integer",
            "description": "워크플로에서 다른 판정을 내린 후 검토자가 거부한 세션입니다."
          }
        }
      },
      "ApplicationAnalyticsRequestBreakdown": {
        "type": "object",
        "description": "해당 범위의 상태 합계입니다. 이전 기간 세부 내역에는 최소한 필수 필드가 포함됩니다.",
        "required": [
          "total_approved",
          "total_in_review",
          "total_declined",
          "total_canceled",
          "total_pending"
        ],
        "properties": {
          "total_approved": {
            "type": "integer",
            "description": "`Approved` 또는 `Kyc Expired` 상태의 세션입니다."
          },
          "total_in_review": {
            "type": "integer",
            "description": "`In Review` 상태의 세션입니다."
          },
          "total_declined": {
            "type": "integer",
            "description": "`Declined` 상태의 세션입니다."
          },
          "total_canceled": {
            "type": "integer",
            "description": "`Expired` 또는 `Abandoned` 상태의 세션입니다."
          },
          "total_pending": {
            "type": "integer",
            "description": "`Not Started`, `In Progress` 또는 `In Review` 상태의 세션입니다(`total_in_review` 포함)."
          },
          "total_expired": {
            "type": "integer",
            "description": "`Expired` 상태의 세션입니다."
          },
          "total_abandoned": {
            "type": "integer",
            "description": "`Abandoned` 상태의 세션입니다."
          },
          "total_in_progress": {
            "type": "integer",
            "description": "`In Progress` 상태의 세션입니다."
          },
          "total_not_started": {
            "type": "integer",
            "description": "`Not Started` 상태의 세션입니다."
          },
          "total_manually_approved": {
            "type": "integer",
            "description": "검토자가 승인함."
          },
          "total_manually_declined": {
            "type": "integer",
            "description": "검토자에 의해 거부됨."
          }
        }
      },
      "ApplicationAnalyticsCountryCount": {
        "type": "object",
        "properties": {
          "country": {
            "type": "string",
            "description": "국가명."
          },
          "country_code": {
            "type": "string",
            "description": "두 글자 국가 코드입니다."
          },
          "session_count": {
            "type": "integer",
            "description": "해당 국가의 세션입니다."
          }
        }
      },
      "ApplicationAnalyticsLocationStats": {
        "type": "object",
        "properties": {
          "ip_countries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsCountryCount"
            },
            "description": "사용자 IP 주소의 국가 목록이며, 세션 수가 가장 많은 순서대로 정렬됩니다."
          },
          "countries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsCountryCount"
            },
            "description": "`ip_countries`와 동일한 목록입니다."
          },
          "id_countries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsCountryCount"
            },
            "description": "인증된 신분증 문서의 발급 국가 목록이며, 세션 수가 가장 많은 순서로 정렬됩니다."
          },
          "conversion_by_country": {
            "type": "array",
            "description": "문서 발급 국가별: 완료된 세션(승인됨, 거부됨 또는 검토 중) 및 승인된 세션 수입니다. 완료 건수가 가장 많은 순으로 정렬됩니다.",
            "items": {
              "type": "object",
              "properties": {
                "country": {
                  "type": "string"
                },
                "country_code": {
                  "type": "string"
                },
                "finished": {
                  "type": "integer"
                },
                "approved": {
                  "type": "integer"
                }
              }
            }
          },
          "cities": {
            "type": "array",
            "description": "최대 100개의 IP 도시 목록이며, 세션 수가 많은 순서대로 정렬됩니다.",
            "items": {
              "type": "object",
              "properties": {
                "location": {
                  "type": "string",
                  "description": "`City, Country`."
                },
                "session_count": {
                  "type": "integer"
                },
                "latitude": {
                  "type": "number",
                  "nullable": true
                },
                "longitude": {
                  "type": "number",
                  "nullable": true
                }
              }
            }
          }
        }
      },
      "ApplicationAnalyticsDemographicStats": {
        "type": "object",
        "properties": {
          "age_distribution": {
            "type": "object",
            "description": "신분증 문서 기준 연령대별 세션입니다. 데이터가 없으면 비어 있습니다.",
            "properties": {
              "under_18": {
                "type": "integer"
              },
              "18_24": {
                "type": "integer"
              },
              "25_34": {
                "type": "integer"
              },
              "35_44": {
                "type": "integer"
              },
              "45_64": {
                "type": "integer"
              },
              "65_plus": {
                "type": "integer"
              }
            },
            "additionalProperties": {
              "type": "integer"
            }
          },
          "gender_distribution": {
            "type": "object",
            "description": "문서 성별 코드(`M`, `F` 또는 `U`(알 수 없음))별 세션입니다.",
            "additionalProperties": {
              "type": "integer"
            }
          }
        }
      },
      "ApplicationAnalyticsDeviceDetails": {
        "type": "object",
        "description": "세션 수가 가장 많은 순으로 각각 상위 5개입니다.",
        "properties": {
          "device_models": {
            "type": "array",
            "description": "기기 브랜드: `Apple`, `Android`, `LG`, 기타 나머지는 `Other`로 그룹화됩니다.",
            "items": {
              "type": "object",
              "properties": {
                "device": {
                  "type": "string"
                },
                "count": {
                  "type": "integer"
                }
              }
            }
          },
          "browsers": {
            "type": "array",
            "description": "브라우저: `Chrome`, `Safari`, `Didit App`, `Firefox`, 그 외 모든 항목은 `Other`로 그룹화됩니다.",
            "items": {
              "type": "object",
              "properties": {
                "browser": {
                  "type": "string"
                },
                "count": {
                  "type": "integer"
                }
              }
            }
          },
          "operating_systems": {
            "type": "array",
            "description": "운영체제입니다.",
            "items": {
              "type": "object",
              "properties": {
                "os": {
                  "type": "string"
                },
                "count": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "ApplicationAnalyticsWorkflowFunnel": {
        "type": "object",
        "description": "워크플로 ID별로 키가 지정됩니다. `total`은 해당 워크플로에서 시작된 세션 수이며, `steps`는 각 단계(`OCR`, `LIVENESS`, `FACE_MATCH`, `AML`, `POA`, `PHONE`, `EMAIL`, `NFC`, `DATABASE_VALIDATION`, `QUESTIONNAIRE`, `IP_ANALYSIS`, `AGE_ESTIMATION`, `KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`)에 도달한 세션 수를 집계합니다. 단계에 도달한 것이 해당 단계를 통과한 것을 의미하지는 않습니다.",
        "additionalProperties": {
          "type": "object",
          "properties": {
            "total": {
              "type": "integer"
            },
            "steps": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "reached": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        }
      },
      "ApplicationAnalyticsVerificationTimeStats": {
        "type": "object",
        "description": "유휴 시간을 제외하고 사용자가 인증에 소비한 실제 활동 시간입니다. 데이터가 없으면 빈 객체입니다.",
        "properties": {
          "overall_avg_seconds": {
            "type": "number",
            "description": "세션당 평균으로, 소수점 한 자리까지 표시됩니다."
          },
          "overall_count": {
            "type": "integer",
            "description": "측정된 세션입니다."
          },
          "per_feature": {
            "type": "object",
            "description": "기능별로 키가 지정됩니다(예: `OCR` 또는 `LIVENESS`).",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "avg_seconds": {
                  "type": "number"
                },
                "total_seconds": {
                  "type": "number"
                },
                "count": {
                  "type": "integer"
                }
              }
            }
          },
          "per_sub_step": {
            "type": "object",
            "description": "기능별로 키가 지정된 후 하위 단계별로 지정됩니다(예: `front_id_photo`).",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "avg_seconds": {
                    "type": "number"
                  },
                  "total_seconds": {
                    "type": "number"
                  },
                  "count": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        }
      },
      "ApplicationAnalyticsResubmissionStats": {
        "type": "object",
        "properties": {
          "first_pass": {
            "type": "integer",
            "description": "재제출이 없는 완료 세션입니다."
          },
          "second": {
            "type": "integer",
            "description": "1회 재제출된 완료 세션입니다."
          },
          "third_plus": {
            "type": "integer",
            "description": "2회 이상 재제출된 완료 세션입니다."
          },
          "abandoned": {
            "type": "integer",
            "description": "중단된 세션입니다."
          }
        }
      },
      "ApplicationAnalyticsOriginalStatusStats": {
        "type": "object",
        "description": "검토자가 변경하기 전 워크플로의 자동 판정 결과입니다.",
        "properties": {
          "approved": {
            "type": "integer"
          },
          "in_review": {
            "type": "integer"
          },
          "declined": {
            "type": "integer"
          }
        }
      },
      "ApplicationAnalyticsWarningStats": {
        "type": "object",
        "description": "기능별로 키가 지정됩니다(`ID_VERIFICATION`, `LIVENESS`, `FACEMATCH`, `AML`, `PROOF_OF_ADDRESS`, `PHONE`, `EMAIL`, `NFC`, `LOCATION`, `DATABASE_VALIDATION`, `QUESTIONNAIRE` 및 KYB 기능). `total`은 해당 기능에 도달한 세션 수이며, `risks`는 경고 코드 및 수준별 세션 수를 집계합니다.",
        "additionalProperties": {
          "type": "object",
          "properties": {
            "total": {
              "type": "integer"
            },
            "risks": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "error": {
                    "type": "integer"
                  },
                  "warning": {
                    "type": "integer"
                  },
                  "information": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        }
      },
      "ApplicationAnalyticsDemographicPoint": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "기간 키: `grouping_mode`에 따라 일의 경우 `YYYY-MM-DD`, 주의 경우 해당 주의 월요일, 월의 경우 `YYYY-MM`입니다."
          },
          "age_distribution": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "gender_distribution": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          }
        }
      },
      "ApplicationAnalyticsDevicePoint": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "기간 키: `grouping_mode`에 따라 일의 경우 `YYYY-MM-DD`, 주의 경우 해당 주의 월요일, 월의 경우 `YYYY-MM`입니다."
          },
          "devices": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "browsers": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "operating_systems": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          }
        }
      },
      "ApplicationAnalyticsVerificationTimePoint": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "기간 키: `grouping_mode`에 따라 일의 경우 `YYYY-MM-DD`, 주의 경우 해당 주의 월요일, 월의 경우 `YYYY-MM`입니다."
          },
          "overall_avg": {
            "type": "number",
            "description": "세션당 평균 활성 시간(초)입니다."
          },
          "per_feature": {
            "type": "object",
            "description": "기능당 평균 활성 시간(초)입니다.",
            "additionalProperties": {
              "type": "number"
            }
          }
        }
      },
      "ApplicationAnalyticsResubmissionPoint": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "기간 키: `grouping_mode`에 따라 일의 경우 `YYYY-MM-DD`, 주의 경우 해당 주의 월요일, 월의 경우 `YYYY-MM`입니다."
          },
          "first_pass": {
            "type": "integer"
          },
          "second": {
            "type": "integer"
          },
          "third_plus": {
            "type": "integer"
          },
          "abandoned": {
            "type": "integer"
          }
        }
      },
      "ApplicationAnalyticsOriginalStatusPoint": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "기간 키: `grouping_mode`에 따라 일의 경우 `YYYY-MM-DD`, 주의 경우 해당 주의 월요일, 월의 경우 `YYYY-MM`입니다."
          },
          "approved": {
            "type": "integer"
          },
          "in_review": {
            "type": "integer"
          },
          "declined": {
            "type": "integer"
          }
        }
      },
      "ApplicationAnalyticsSummary": {
        "type": "object",
        "description": "사용자 인증(KYC) 요약으로, `scope`와 `widget_keys`가 모두 전송되지 않은 경우 반환됩니다.",
        "required": [
          "data_points",
          "request_breakdown",
          "previous_data_points",
          "previous_request_breakdown",
          "conversion_rate",
          "location_stats",
          "demographic_stats",
          "device_details",
          "workflow_funnel_stats",
          "verification_time_stats",
          "resubmission_stats",
          "warning_stats",
          "original_status_stats",
          "grouping_mode",
          "demographic_time_series",
          "device_time_series",
          "verification_time_time_series",
          "resubmission_time_series",
          "original_status_time_series"
        ],
        "properties": {
          "data_points": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint"
            },
            "description": "해당 범위 내 세션이 있는 첫날부터 `end_date`까지 하루당 하나의 포인트입니다. `grouping_mode` 설정과 관계없이 항상 일별로 제공됩니다."
          },
          "request_breakdown": {
            "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown"
          },
          "previous_data_points": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint"
            },
            "description": "`start_date` 직전의 동일한 길이의 기간에 대한 일별 포인트입니다."
          },
          "previous_request_breakdown": {
            "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown"
          },
          "conversion_rate": {
            "type": "number",
            "nullable": true,
            "description": "`total_approved / (total_approved + total_declined + total_in_review) x 100`, 소수점 한 자리입니다. 완료된 항목이 없으면 `null`입니다."
          },
          "location_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsLocationStats"
          },
          "demographic_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsDemographicStats"
          },
          "device_details": {
            "$ref": "#/components/schemas/ApplicationAnalyticsDeviceDetails"
          },
          "workflow_funnel_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsWorkflowFunnel"
          },
          "verification_time_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimeStats"
          },
          "resubmission_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionStats"
          },
          "warning_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsWarningStats"
          },
          "original_status_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusStats"
          },
          "grouping_mode": {
            "type": "string",
            "enum": [
              "day",
              "week",
              "month"
            ],
            "description": "`*_time_series` 목록이 그룹화되는 방식입니다. 최대 14일까지는 `day`, 90일까지는 `week`, 그 이상은 `month`입니다. 해당 범위에서 세션이 발생한 첫날부터 측정됩니다."
          },
          "demographic_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDemographicPoint"
            }
          },
          "device_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDevicePoint"
            }
          },
          "verification_time_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimePoint"
            }
          },
          "resubmission_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionPoint"
            }
          },
          "original_status_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusPoint"
            }
          }
        }
      },
      "ApplicationAnalyticsWidget": {
        "type": "object",
        "description": "대시보드 위젯 1개입니다. 모든 위젯에는 `kind` 및 `title`이 있으며, 기타 필드는 `kind`에 따라 달라집니다. 세션 위젯은 요약 객체(`data_points`, `request_breakdown`, `workflow_funnel_stats` 등)를 재사용하고, 목록 위젯은 해당 항목을 `items`에 배치하며, 거래 지표는 `value`를 사용합니다.",
        "required": [
          "kind",
          "title"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "sessions_volume",
              "workflow_funnel",
              "average_verification_time",
              "country_distribution",
              "warning_insights",
              "conversion_rate",
              "conversion_by_country",
              "resubmission_insights",
              "original_status_distribution",
              "database_validation_coverage",
              "database_validation_latency",
              "demographics",
              "device_details",
              "horizontal_bar",
              "kyb_registry_coverage",
              "kyb_registry_data_completeness",
              "metric",
              "time_series",
              "breakdown",
              "status_time_series",
              "leaderboard",
              "histogram"
            ],
            "description": "위젯 유형입니다."
          },
          "title": {
            "type": "string",
            "description": "표시 제목입니다(예: `Verification volume`)."
          },
          "grouping_mode": {
            "type": "string",
            "enum": [
              "day",
              "week",
              "month"
            ],
            "description": "`*_time_series` 목록이 그룹화되는 방식입니다. 최대 14일까지는 `day`, 90일까지는 `week`, 그 이상은 `month`입니다. 해당 범위에서 세션이 발생한 첫날부터 측정됩니다."
          },
          "data_points": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint"
            }
          },
          "request_breakdown": {
            "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown"
          },
          "previous_data_points": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint"
            }
          },
          "previous_request_breakdown": {
            "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown"
          },
          "conversion_rate": {
            "type": "number",
            "nullable": true
          },
          "workflow_funnel_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsWorkflowFunnel"
          },
          "verification_time_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimeStats"
          },
          "verification_time_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimePoint"
            }
          },
          "warning_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsWarningStats"
          },
          "resubmission_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionStats"
          },
          "resubmission_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionPoint"
            }
          },
          "original_status_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusStats"
          },
          "original_status_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusPoint"
            }
          },
          "demographic_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsDemographicStats"
          },
          "demographic_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDemographicPoint"
            }
          },
          "device_details": {
            "$ref": "#/components/schemas/ApplicationAnalyticsDeviceDetails"
          },
          "device_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDevicePoint"
            }
          },
          "items": {
            "type": "array",
            "description": "목록 위젯의 항목. `country_distribution`(KYC): `country`, `country_code`, `session_count`. `conversion_by_country`: `country`, `country_code`, `finished`, `approved`. `time_series`: `date`, `value`. `status_time_series`: `date`, `approved`, `declined`, `flagged`. `breakdown`: `count` 및 `volume`이 포함된 `transaction_type` 또는 `action_type`, 또는 `tag_id`, `tag_name`, `count`. `leaderboard`: `rule_title`, `trigger_count` 또는 `assignee`, `handled_count`, `average_processing_seconds`(각각 `approved_percentage`, `declined_percentage`, `flagged_percentage` 포함). `histogram`: `score`, `count`.",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "previous_items": {
            "type": "array",
            "description": "`start_date` 바로 이전의 동일한 길이 기간에 대한 거래 시계열입니다.",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "value": {
            "type": "number",
            "description": "`metric` 위젯: 해당 범위의 수치입니다."
          },
          "currency": {
            "type": "string",
            "nullable": true,
            "description": "거래량 및 금액 위젯: 애플리케이션의 기본 거래 통화입니다."
          },
          "thresholds": {
            "type": "object",
            "description": "`histogram` 위젯: 애플리케이션의 검토 및 거부 점수 임계값입니다.",
            "properties": {
              "review": {
                "type": "integer"
              },
              "decline": {
                "type": "integer"
              }
            }
          },
          "search": {
            "type": "object",
            "description": "`kyb_registry_coverage` 위젯: 등기부 검색 총계입니다.",
            "properties": {
              "searches_total": {
                "type": "integer"
              },
              "searches_with_no_candidates": {
                "type": "integer"
              }
            }
          }
        }
      },
      "ApplicationAnalyticsWidgetResponse": {
        "type": "object",
        "description": "대시보드 위젯으로, `scope` 또는 `widget_keys`가 전송되었을 때 반환됩니다.",
        "required": [
          "scope",
          "available_widget_keys",
          "requested_widget_keys",
          "widgets"
        ],
        "properties": {
          "scope": {
            "type": "string",
            "enum": [
              "home",
              "kyc",
              "kyb",
              "transactions"
            ],
            "description": "대시보드 탭입니다."
          },
          "available_widget_keys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "이 범위에서 허용되는 모든 위젯 키입니다."
          },
          "requested_widget_keys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "응답된 위젯 키(순서대로): 유효한 `widget_keys` 또는 스코프의 기본값입니다."
          },
          "widgets": {
            "type": "object",
            "description": "위젯 키별로 키가 지정되며, `requested_widget_keys`의 순서를 따릅니다.",
            "additionalProperties": {
              "$ref": "#/components/schemas/ApplicationAnalyticsWidget"
            }
          }
        }
      },
      "ApplicationAnalyticsToday": {
        "type": "object",
        "description": "지난주 같은 요일 대비 현지 시간별 오늘의 인증 건수입니다.",
        "required": [
          "time_zone",
          "date",
          "current_hour",
          "previous_date",
          "hours",
          "previous_hours",
          "total",
          "previous_total_so_far",
          "outcomes"
        ],
        "properties": {
          "time_zone": {
            "type": "string",
            "description": "해당 날짜 및 시간이 속한 IANA 표준 시간대입니다.",
            "example": "Europe/Madrid"
          },
          "date": {
            "type": "string",
            "format": "date",
            "description": "해당 시간대 기준 오늘 날짜입니다.",
            "example": "2026-10-30"
          },
          "current_hour": {
            "type": "integer",
            "minimum": 0,
            "maximum": 23,
            "description": "현재 현지 시간(시)입니다.",
            "example": 14
          },
          "previous_date": {
            "type": "string",
            "format": "date",
            "description": "비교 기준일: 1주 전 같은 요일입니다.",
            "example": "2026-10-23"
          },
          "hours": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "minItems": 24,
            "maxItems": 24,
            "description": "00:00부터 현지 시간 기준 시간대별 오늘 생성된 인증 건수입니다. 앞으로 남은 시간대는 0입니다."
          },
          "previous_hours": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "minItems": 24,
            "maxItems": 24,
            "description": "00:00부터 현지 시간 기준 시간대별 비교 일자에 생성된 인증 건수입니다."
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "description": "오늘 현재까지 생성된 인증 건수입니다.",
            "example": 165
          },
          "previous_total_so_far": {
            "type": "integer",
            "minimum": 0,
            "description": "동일한 현지 시간까지 비교 일자에 생성된 인증 건수입니다.",
            "example": 151
          },
          "outcomes": {
            "type": "object",
            "description": "오늘의 인증 중 현재 승인됨, 검토 중 대기 및 거부됨 상태인 건수입니다. 나머지는 아직 완료되지 않았습니다.",
            "required": [
              "approved",
              "in_review",
              "declined"
            ],
            "properties": {
              "approved": {
                "type": "integer",
                "minimum": 0
              },
              "in_review": {
                "type": "integer",
                "minimum": 0
              },
              "declined": {
                "type": "integer",
                "minimum": 0
              }
            }
          }
        }
      },
      "WebhookConfigDestination": {
        "type": "object",
        "description": "전송 지표를 제외하고 webhook 설정에 나열된 webhook 대상입니다. `GET /v3/webhook/destinations/{destination_uuid}/`는 전송 요약을 추가합니다.",
        "required": [
          "uuid",
          "label",
          "url",
          "enabled",
          "webhook_version",
          "secret_shared_key",
          "subscribed_events",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "대상 ID입니다."
          },
          "label": {
            "type": "string",
            "maxLength": 255,
            "description": "사람이 읽을 수 있는 이름입니다."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2000,
            "description": "Didit이 이벤트를 POST하는 HTTPS endpoint입니다."
          },
          "enabled": {
            "type": "boolean",
            "description": "`false`는 이 대상으로의 전송을 일시 중지합니다."
          },
          "webhook_version": {
            "type": "string",
            "enum": [
              "v1",
              "v2",
              "v3"
            ],
            "description": "이 대상으로 전송되는 payload 버전입니다."
          },
          "secret_shared_key": {
            "type": "string",
            "description": "이 대상의 서명 비밀(43자 길이의 URL 안전 token)입니다. 각 webhook을 해당 webhook이 전송된 대상의 비밀로 검증하십시오. API 키 호출자는 항상 전체 값을 수신하며, `read:webhooks` 권한이 없는 콘솔 사용자는 빈 문자열을 수신합니다."
          },
          "subscribed_events": {
            "type": "array",
            "uniqueItems": true,
            "description": "이 대상에 전송되는 이벤트 유형입니다. 대상이 이벤트 없이 생성된 경우 비어 있으며, 이 경우 아무것도 수신하지 않습니다.",
            "items": {
              "$ref": "#/components/schemas/WebhookEvent"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookConfig": {
        "type": "object",
        "description": "모든 webhook 대상과 함께 애플리케이션 수준 webhook 설정, 데이터 보존 정책 및 디지털 ID 지갑 반환 호스트를 포함합니다.",
        "required": [
          "webhook_url",
          "webhook_version",
          "secret_shared_key",
          "capture_method",
          "data_retention_months",
          "face_retention_policy",
          "face_retention_days",
          "available_events",
          "allowed_return_hosts",
          "endpoints"
        ],
        "properties": {
          "webhook_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "애플리케이션 수준(레거시) webhook URL입니다. 애플리케이션에 활성화된 대상이 없을 때만 Didit이 이 URL로 전송하며, 이때는 `status.updated` 및 `data.updated`만 전송됩니다. 대상을 생성, 업데이트 또는 삭제할 때마다 가장 오래된 활성화된 대상의 URL로 설정되거나 활성화된 대상이 없으면 `null`로 설정됩니다."
          },
          "webhook_version": {
            "type": "string",
            "enum": [
              "v1",
              "v2",
              "v3"
            ],
            "description": "레거시 `webhook_url`의 payload 버전입니다. 각 대상은 자체 `webhook_version`을 가집니다."
          },
          "secret_shared_key": {
            "type": "string",
            "description": "애플리케이션 수준 서명 비밀(43자 URL-safe token)입니다. 레거시 `webhook_url`로의 전송에만 서명합니다. 각 대상은 자체 `secret_shared_key`로 서명합니다. API 키 호출자는 항상 전체 값을 수신합니다. `read:webhooks` 권한이 없는 Console 사용자는 빈 문자열을 수신합니다."
          },
          "capture_method": {
            "type": "string",
            "enum": [
              "MOBILE",
              "MOBILE_AND_DESKTOP"
            ],
            "description": "레거시 애플리케이션 설정입니다. 인증 흐름에서는 이를 읽지 않으며, 캡처 옵션은 워크플로별로 구성됩니다."
          },
          "data_retention_months": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 120,
            "description": "자동 삭제 기간입니다. 생성된 지 이 개월 수(1개월은 30일로 계산)를 초과한 사용자 인증 세션은 자동으로 삭제되며, 해당 삭제는 되돌릴 수 없습니다. `null`은 세션이 자동으로 삭제되지 않음을 의미합니다. [데이터 보존](https://docs.didit.me/ko/console/data-retention)을 참조하십시오."
          },
          "face_retention_policy": {
            "type": "string",
            "enum": [
              "delete_with_session",
              "retain_until_user_deleted"
            ],
            "description": "세션이 삭제될 때 세션의 얼굴 임베딩에 수행되는 작업입니다. `delete_with_session`(기본값)은 세션과 함께 삭제합니다. `retain_until_user_deleted`는 옵트인 방식의 [생체 인식 템플릿 보존](https://docs.didit.me/ko/console/data-retention#생체-인식-템플릿-보존)으로, 사용자에 연결된 이미지가 없는 생체 인식 템플릿이 보존 기간이 끝나거나 사용자가 삭제되거나 직접 영구 삭제할 때까지 별도로 관리됩니다."
          },
          "face_retention_days": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 3650,
            "description": "`retain_until_user_deleted` 적용 시 생체 인식 템플릿의 보존 기간(일)입니다. 해당 정책이 설정된 경우 필수입니다."
          },
          "biometric_consent_mode": {
            "type": "string",
            "enum": [
              "auto",
              "always",
              "never"
            ],
            "description": "호스팅 플로우 및 네이티브 SDK에서 얼굴 캡처 전 사용자에게 명시적인 생체 인식 동의를 요청하는 시점입니다. `auto`(기본값)는 선언된 주, 사용자의 IP, 또는 신분증 발급 국가/지역이 일리노이, 텍사스, 콜로라도에 해당하거나 사용자가 주 정보 없이 미국 내에 있는 것으로 보일 때와 같이 트리거가 적용되는 경우에만 요청합니다. `always`는 얼굴을 캡처하는 워크플로의 모든 사용자에게 요청합니다. `never`는 해당 단계를 절대 표시하지 않으며, 셀피 촬영 전에 직접 동의를 수집해야 합니다. 모든 변경 사항은 감사 로그에 기록됩니다. [생체 인식 동의](https://docs.didit.me/ko/getting-started/biometric-consent)를 참고하십시오."
          },
          "available_events": {
            "type": "array",
            "description": "대상이 구독할 수 있는 모든 이벤트 유형과 표시 라벨입니다.",
            "items": {
              "type": "object",
              "required": [
                "value",
                "label"
              ],
              "properties": {
                "value": {
                  "$ref": "#/components/schemas/WebhookEvent"
                },
                "label": {
                  "type": "string",
                  "description": "표시 레이블입니다(예: `Session status updated`)."
                }
              }
            }
          },
          "allowed_return_hosts": {
            "type": "array",
            "maxItems": 20,
            "description": "독립형 디지털 ID 지갑 인증이 `return_url`을 통해 사용자를 다시 보낼 수 있는 호스트 이름(정확히 일치, HTTPS 전용)입니다. 귀사의 화이트 라벨 도메인도 항상 허용됩니다. [반환 대상 등록](https://docs.didit.me/ko/standalone-apis/digital-id-wallets#반환-대상-등록)을 참조하십시오.",
            "items": {
              "type": "string",
              "maxLength": 253
            }
          },
          "endpoints": {
            "type": "array",
            "description": "서명용 비밀을 포함한 애플리케이션의 모든 webhook 대상(오래된 순)입니다. 여기서는 읽기 전용이며, `/v3/webhook/destinations/` endpoint를 통해 대상을 관리할 수 있습니다.",
            "items": {
              "$ref": "#/components/schemas/WebhookConfigDestination"
            }
          },
          "allowed_domains": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "type": "string",
              "maxLength": 300
            },
            "description": "호스팅 인증 흐름이 포함될 수 있고 세션 콜백을 통해 사용자를 다시 리디렉션할 수 있는 오리진(예: `https://app.example.com`; `http`는 `localhost`에만 해당)입니다. 서버 간 호출에는 영향을 미치지 않습니다. 빈 목록은 제한이 없음을 의미합니다. Didit은 각 오리진을 기본 포트 없이 소문자로 저장합니다. 유효하지 않은 항목이 있으면 `allowed_domains`에서 `400`으로 실패합니다.",
            "example": [
              "https://app.example.com"
            ]
          }
        }
      },
      "WebhookDestinationDelivery": {
        "type": "object",
        "description": "webhook 대상으로의 전송 시도 1회입니다. 이벤트의 최초 전송, 각 자동 재시도 및 각 재전송은 별도의 전송으로 처리됩니다.",
        "required": [
          "uuid",
          "session_id",
          "request_url",
          "response_status",
          "response_time_ms",
          "status",
          "webhook_type",
          "created_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "상세 조회 및 재전송 호출용 전송 ID입니다."
          },
          "session_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "해당 이벤트의 대상인 사용자 인증 세션입니다. 기업 세션, 사용자, 기업, 거래, Travel Rule 및 워크플로 이벤트의 경우 `null`입니다."
          },
          "request_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "전송이 전송된 대상의 URL: 이벤트가 생성되었을 때 대상의 URL입니다."
          },
          "response_status": {
            "type": "integer",
            "nullable": true,
            "description": "endpoint가 반환한 HTTP 상태입니다. 전송이 대기열에 있고 아직 시도되지 않은 동안에는 `null`입니다. HTTP 응답을 받지 못한 경우 Didit은 자체 상태를 기록합니다. endpoint가 5초 이내에 응답하지 않은 경우 `504`, 연결 실패의 경우 `503`, URL이 안전하지 않은 것으로 거부된 경우(예: 사설 또는 내부 주소) `400`, 기타 모든 요청 오류의 경우 `404`를 기록합니다. `400` 이상은 전송 실패로 간주됩니다."
          },
          "response_time_ms": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "description": "시도에 걸린 시간(밀리초 단위)입니다. 전송이 대기열에 있는 동안에는 `null`입니다."
          },
          "status": {
            "type": "string",
            "nullable": true,
            "description": "이벤트 생성 시 보고된 상태: 세션 이벤트의 경우 세션 상태(예: `Approved` 또는 `In Review`), 사용자 및 기업 이벤트의 경우 개인 또는 회사의 상태, 거래 이벤트의 경우 거래 상태입니다. 상태가 없는 이벤트의 경우 `null`입니다."
          },
          "webhook_type": {
            "$ref": "#/components/schemas/WebhookEvent"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "전송이 생성된 시점입니다."
          }
        }
      },
      "WebhookDestinationDeliveryDetail": {
        "type": "object",
        "description": "webhook 대상으로의 전송 시도 1회이며, Didit이 전송한 정확한 요청 헤더 및 본문이 포함됩니다.",
        "required": [
          "uuid",
          "session_id",
          "request_url",
          "response_status",
          "response_time_ms",
          "status",
          "webhook_type",
          "created_at",
          "request_header",
          "request_body"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "상세 조회 및 재전송 호출용 전송 ID입니다."
          },
          "session_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "해당 이벤트의 대상인 사용자 인증 세션입니다. 기업 세션, 사용자, 기업, 거래, Travel Rule 및 워크플로 이벤트의 경우 `null`입니다."
          },
          "request_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "전송이 전송된 대상의 URL: 이벤트가 생성되었을 때 대상의 URL입니다."
          },
          "response_status": {
            "type": "integer",
            "nullable": true,
            "description": "endpoint가 반환한 HTTP 상태입니다. 전송이 대기열에 있고 아직 시도되지 않은 동안에는 `null`입니다. HTTP 응답을 받지 못한 경우 Didit은 자체 상태를 기록합니다. endpoint가 5초 이내에 응답하지 않은 경우 `504`, 연결 실패의 경우 `503`, URL이 안전하지 않은 것으로 거부된 경우(예: 사설 또는 내부 주소) `400`, 기타 모든 요청 오류의 경우 `404`를 기록합니다. `400` 이상은 전송 실패로 간주됩니다."
          },
          "response_time_ms": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "description": "시도에 걸린 시간(밀리초 단위)입니다. 전송이 대기열에 있는 동안에는 `null`입니다."
          },
          "status": {
            "type": "string",
            "nullable": true,
            "description": "이벤트 생성 시 보고된 상태: 세션 이벤트의 경우 세션 상태(예: `Approved` 또는 `In Review`), 사용자 및 기업 이벤트의 경우 개인 또는 회사의 상태, 거래 이벤트의 경우 거래 상태입니다. 상태가 없는 이벤트의 경우 `null`입니다."
          },
          "webhook_type": {
            "$ref": "#/components/schemas/WebhookEvent"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "전송이 생성된 시점입니다."
          },
          "request_header": {
            "type": "string",
            "description": "Didit이 전송한 요청 헤더(`Content-Type`, `X-Signature`, `X-Signature-V2`, `X-Signature-Simple`, `X-Timestamp`, `User-Agent`)의 JSON 텍스트(문자열)입니다. JSON 파서로 파싱하십시오. 서명이 포함되어 있으며 서명용 비밀값은 절대 포함되지 않습니다."
          },
          "request_body": {
            "type": "string",
            "description": "Didit이 전송한 정확한 payload의 JSON 텍스트(문자열)로, `event_id` 및 `timestamp`를 포함하여 키가 정렬되어 있습니다. JSON 파서로 파싱하십시오. [Payload 구조](https://docs.didit.me/ko/integration/webhooks#payload-구조)를 참고하십시오. `media: read` 권한이 없는 범위 지정 키의 경우 내부 미디어 URL이 `null`이 되며, `sessions: write` 권한이 없으면 세션 token과 호스팅 인증 링크가 `null`이 됩니다. 이러한 방식으로 변경된 본문은 더 이상 해당 서명과 일치하지 않습니다. Didit은 귀하의 endpoint가 반환한 응답 본문을 기록하지 않습니다."
          }
        }
      },
      "SessionWebhookDelivery": {
        "type": "object",
        "description": "인증 세션에 대해 기록된 webhook 전송 시도 1건으로, Didit이 전송한 정확한 요청 헤더와 본문이 포함됩니다.",
        "required": [
          "uuid",
          "session_id",
          "request_url",
          "response_status",
          "status",
          "webhook_type",
          "request_header",
          "request_body",
          "created_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "전송 ID입니다. 이 전송을 조회하거나 재전송하려면 `{webhook_uuid}`로 사용하십시오."
          },
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "전송이 속한 세션입니다(경로의 세션)."
          },
          "request_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "전송이 전송된 대상의 URL입니다."
          },
          "response_status": {
            "type": "integer",
            "nullable": true,
            "description": "endpoint가 반환한 HTTP 상태입니다. 전송이 대기열에 있고 아직 시도되지 않은 동안에는 `null`입니다. HTTP 응답을 받지 못한 경우 Didit은 자체 상태를 기록합니다. endpoint가 5초 이내에 응답하지 않은 경우 `504`, 연결 실패의 경우 `503`, URL이 안전하지 않은 것으로 거부된 경우(예: 사설 또는 내부 주소) `400`, 기타 모든 요청 오류의 경우 `404`를 기록합니다. `400` 이상은 전송 실패로 간주됩니다."
          },
          "status": {
            "type": "string",
            "nullable": true,
            "description": "이벤트가 생성되었을 때의 세션 상태입니다(예: `In Progress`, `Approved` 또는 `Declined`)."
          },
          "webhook_type": {
            "$ref": "#/components/schemas/WebhookEvent"
          },
          "request_header": {
            "type": "string",
            "description": "Didit이 전송한 요청 헤더(`Content-Type`, `X-Signature`, `X-Signature-V2`, `X-Signature-Simple`, `X-Timestamp`, `User-Agent`)의 JSON 텍스트(문자열)입니다. JSON 파서로 파싱하십시오. 서명이 포함되어 있으며 서명용 비밀값은 절대 포함되지 않습니다."
          },
          "request_body": {
            "type": "string",
            "description": "Didit이 전송한 정확한 payload의 JSON 텍스트(문자열)로, `event_id` 및 `timestamp`를 포함하여 키가 정렬되어 있습니다. JSON 파서로 파싱하십시오. [Payload 구조](https://docs.didit.me/ko/integration/webhooks#payload-구조)를 참고하십시오. `media: read` 권한이 없는 범위 지정 키의 경우 내부 미디어 URL이 `null`이 되며, `sessions: write` 권한이 없으면 세션 token과 호스팅 인증 링크가 `null`이 됩니다. 이러한 방식으로 변경된 본문은 더 이상 해당 서명과 일치하지 않습니다. Didit은 귀하의 endpoint가 반환한 응답 본문을 기록하지 않습니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "전송이 생성된 시점입니다."
          }
        }
      },
      "SessionEvent": {
        "type": "object",
        "description": "인증 세션 이벤트 타임라인의 항목 1개입니다.",
        "required": [
          "uuid",
          "event_type",
          "created_at",
          "component",
          "feature_step",
          "step",
          "details",
          "ip_address",
          "user_agent",
          "device_info",
          "file_url",
          "sent_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "이벤트 식별자입니다."
          },
          "event_type": {
            "type": "string",
            "enum": [
              "SESSION_CREATED",
              "SESSION_COMPLETED",
              "SESSION_STATUS_CHANGED",
              "LINK_OPENED",
              "FORM_SUBMITTED",
              "BUTTON_CLICKED",
              "FILE_UPLOADED",
              "ATTEMPT_FAILED",
              "FEATURE_STEP_CHANGED",
              "STEP_RENDERED",
              "NOTE_ADDED",
              "MANUAL_REVIEW_STARTED",
              "WORKFLOW_BRANCH_EVALUATED",
              "WORKFLOW_STATUS_NODE_REACHED",
              "LOG"
            ],
            "description": "발생한 내용입니다. 호스팅 플로우 또는 SDK 진행 중 기기에서 보고된 내용: `LINK_OPENED`, `STEP_RENDERED`, `BUTTON_CLICKED`, `FORM_SUBMITTED`, `FILE_UPLOADED`, `ATTEMPT_FAILED`, `LOG`(디버깅용). 서버에서 기록된 내용: `SESSION_CREATED`, `SESSION_STATUS_CHANGED`(`details.old_status`, `details.current_status`), `FEATURE_STEP_CHANGED`(`details.old_feature_step`, `details.current_feature_step`), `WORKFLOW_BRANCH_EVALUATED`, `WORKFLOW_STATUS_NODE_REACHED`(워크플로 라우팅 추적). 이전 세션에서는 `SESSION_COMPLETED`, `NOTE_ADDED`, `MANUAL_REVIEW_STARTED`가 나타날 수 있습니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Didit이 이벤트를 저장한 시점입니다. 이벤트는 `sent_at` 이후 몇 초 뒤에 비동기식으로 저장됩니다."
          },
          "component": {
            "type": "string",
            "nullable": true,
            "description": "이벤트를 보고한 UI 컴포넌트입니다(기기 이벤트 전용)."
          },
          "feature_step": {
            "type": "string",
            "nullable": true,
            "enum": [
              "OCR",
              "OCR_BACK",
              "NFC",
              "AML",
              "FACE",
              "LIVENESS",
              "FACE_MATCH",
              "IP_ANALYSIS",
              "AGE_ESTIMATION",
              "PROOF_OF_ADDRESS",
              "PHONE_VERIFICATION",
              "EMAIL_VERIFICATION",
              "FACE_SEARCH",
              "DATABASE_VALIDATION",
              "QUESTIONNAIRE",
              "KYB_REGISTRY",
              "KYB_DOCUMENTS",
              "KYB_KEY_PEOPLE",
              "DOCUMENT_AI",
              "GEOLOCATION",
              null
            ],
            "description": "이벤트 발생 당시 세션이 진행 중이던 인증 기능입니다."
          },
          "step": {
            "type": "string",
            "nullable": true,
            "description": "기능 내 화면(예: `DOCUMENT_CAPTURE_FRONT` 또는 `FACE_PASSIVE_LIVENESS`)."
          },
          "details": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "이벤트 관련 데이터입니다. 키는 `event_type`에 따라 다릅니다."
          },
          "ip_address": {
            "type": "string",
            "nullable": true,
            "description": "기기가 이벤트를 보고한 주소입니다. 서버에 기록된 이벤트의 경우 `null`입니다."
          },
          "user_agent": {
            "type": "string",
            "nullable": true,
            "description": "기기의 사용자 에이전트입니다. 서버에 기록된 이벤트의 경우 `null`입니다."
          },
          "device_info": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "SDK 또는 브라우저가 보고한 기기 세부 정보입니다."
          },
          "file_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "이벤트에 첨부된 파일(예: 캡처된 이미지)로 연결되는 유효 기간이 짧은 사전 서명된 링크입니다. 파일이 없으면 `null`이며, `media: read` 권한이 없는 범위 지정 API 키의 경우 항상 `null`입니다."
          },
          "sent_at": {
            "type": "integer",
            "format": "int64",
            "description": "이벤트가 발생한 시점(밀리초 단위의 Unix 타임스탬프)입니다. 결과는 이 값을 기준으로 정렬됩니다."
          }
        }
      },
      "AMLDatasetSourceFreshness": {
        "type": "object",
        "description": "한 제품군 AML 데이터 세트의 최신성입니다.",
        "required": [
          "last_updated_at",
          "oldest_updated_at",
          "dataset_count",
          "dated_dataset_count"
        ],
        "properties": {
          "last_updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "해당 패밀리 내 모든 데이터셋의 가장 최근 업데이트."
          },
          "oldest_updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "데이터 최신성 경계: 제품군의 모든 데이터셋은 최소한 이 시점만큼 최신 상태입니다. 제품군의 하나 이상의 데이터셋에 업데이트 날짜가 보고되지 않아 경계를 알 수 없는 경우 `null`입니다."
          },
          "dataset_count": {
            "type": "integer",
            "description": "패밀리 내 데이터셋 수입니다."
          },
          "dated_dataset_count": {
            "type": "integer",
            "description": "업데이트 날짜를 보고한 해당 데이터 세트의 수입니다."
          }
        }
      },
      "AMLDatasetFreshness": {
        "type": "object",
        "description": "스크리닝이 실행되었을 때 AML 데이터 세트가 얼마나 최신 상태였는지를 나타냅니다. 날짜는 추정되지 않습니다.",
        "required": [
          "captured_at",
          "provider",
          "catalog_version",
          "sources"
        ],
        "properties": {
          "captured_at": {
            "type": "string",
            "format": "date-time",
            "description": "Didit이 이 최신성 정보의 출처인 데이터셋 카탈로그를 읽은 시점입니다."
          },
          "provider": {
            "type": "string",
            "description": "AML 데이터 소스의 불투명 식별자입니다. 불투명 문자열로 취급해야 하며, 이에 따라 분기하지 마십시오.",
            "example": "aml_data_source"
          },
          "catalog_version": {
            "type": "string",
            "nullable": true,
            "description": "소스에서 보고하는 경우, 데이터 세트 카탈로그의 버전 식별자입니다."
          },
          "sources": {
            "type": "object",
            "description": "데이터셋 패밀리별 최신성입니다. 데이터셋에 업데이트 날짜가 보고되지 않은 패밀리는 `null`로 채워지지 않고 생략됩니다.",
            "properties": {
              "sanctions": {
                "$ref": "#/components/schemas/AMLDatasetSourceFreshness"
              },
              "pep": {
                "$ref": "#/components/schemas/AMLDatasetSourceFreshness"
              },
              "warnings": {
                "$ref": "#/components/schemas/AMLDatasetSourceFreshness"
              },
              "adverse_media": {
                "$ref": "#/components/schemas/AMLDatasetSourceFreshness"
              }
            }
          }
        }
      },
      "AMLScreeningRun": {
        "type": "object",
        "description": "완료된 AML 확인의 지속적인 모니터링 재스크리닝 1건입니다.",
        "required": [
          "uuid",
          "run_id",
          "completed_at",
          "started_at",
          "outcome",
          "trigger",
          "provider",
          "status",
          "score",
          "total_hits",
          "new_hits",
          "entities_screened",
          "dataset_freshness"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "이 스크리닝 실행의 식별자입니다."
          },
          "run_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 스크리닝이 속한 모니터링 실행입니다. 동일한 실행에서 스크리닝된 모든 인증이 이를 공유합니다."
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "description": "이 대상자의 재스크리닝이 완료된 시점입니다. 결과는 이 값을 기준으로 최신순으로 정렬됩니다."
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "description": "이 재스크리닝이 속한 모니터링 배치가 시작된 시점입니다."
          },
          "outcome": {
            "type": "string",
            "enum": [
              "NO_CHANGE",
              "CHANGED",
              "FAILED"
            ],
            "description": "`NO_CHANGE`: 완료되었으며 결과가 변경되지 않음. `CHANGED`: 완료되었으며 점수, 상태, 일치 건수 또는 일치 항목이 변경됨. `FAILED`: 이 대상에 대해 사용 가능한 응답이 없어 확인이 그대로 유지됨."
          },
          "trigger": {
            "type": "string",
            "enum": [
              "ONGOING_MONITORING"
            ],
            "description": "스크리닝을 시작한 원인입니다. 현재는 항상 `ONGOING_MONITORING`입니다."
          },
          "provider": {
            "type": "string",
            "description": "응답한 AML 데이터 소스의 불투명 식별자입니다. 불투명 문자열로 취급해야 하며, 이에 따라 분기하지 마십시오.",
            "example": "aml_data_source"
          },
          "status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Not Finished",
              "Approved",
              "Declined",
              "In Review",
              "Resub Requested",
              null
            ],
            "description": "이번 실행으로 검사가 도달한 AML 검사 상태입니다."
          },
          "score": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "minimum": 0,
            "maximum": 100,
            "description": "이번 실행으로 검사가 도달한 AML 점수입니다."
          },
          "total_hits": {
            "type": "integer",
            "nullable": true,
            "description": "이 실행 후 검사에 남아 있는 적발 건수입니다."
          },
          "new_hits": {
            "type": "integer",
            "nullable": true,
            "description": "이 실행을 통해 검사에서 이전에 없었던 새로 발견된 적발 건수입니다. 새로운 항목이 발견되지 않은 경우 `0`이며, 실행이 실패했거나 이 카운트가 존재하기 전에 기록된 경우 `null`입니다."
          },
          "entities_screened": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1,
            "description": "이 실행에서 인증을 위해 스크리닝한 엔티티 수입니다. 대상이 스크리닝된 경우 `1`, 실행이 실패한 경우 `0`입니다."
          },
          "dataset_freshness": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AMLDatasetFreshness"
              }
            ],
            "nullable": true,
            "description": "이 실행에 사용된 데이터 세트 최신성 정보이거나, 날짜 정보가 없는 경우 `null`입니다."
          }
        }
      },
      "KYBKeyPeopleParty": {
        "type": "object",
        "description": "하위 인증을 포함하는 기업 확인(KYB) 세션의 주요 인물 당사자입니다. 동일한 당사자가 기업 세션 결정의 `key_people_checks[].submitted.parties[]`에 나타납니다.",
        "required": [
          "uuid",
          "entity_type",
          "source",
          "name",
          "is_active",
          "is_skipped",
          "requires_verification",
          "roles",
          "kyc_session_deleted",
          "kyb_sub_session_deleted"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "당사자 식별자입니다."
          },
          "entity_type": {
            "type": "string",
            "enum": [
              "person",
              "company"
            ],
            "description": "해당 당사자가 개인인지 기업인지 여부입니다."
          },
          "source": {
            "type": "string",
            "enum": [
              "REGISTRY",
              "USER"
            ],
            "description": "`REGISTRY`: 법인 등기부에서 가져옴. `USER`: 주요 인물 화면에서 입력함."
          },
          "name": {
            "type": "string",
            "description": "당사자의 표시 이름입니다."
          },
          "first_name": {
            "type": "string",
            "nullable": true,
            "description": "이름(개인)."
          },
          "last_name": {
            "type": "string",
            "nullable": true,
            "description": "성(개인)."
          },
          "company_name": {
            "type": "string",
            "nullable": true,
            "description": "기업명(기업 당사자)."
          },
          "registration_number": {
            "type": "string",
            "nullable": true,
            "description": "기업 등록번호(기업 당사자)."
          },
          "email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "description": "인증 링크가 전송되는 이메일입니다."
          },
          "nationality": {
            "type": "string",
            "nullable": true,
            "description": "개인의 경우 국적, 기업의 경우 법인 설립 국가입니다."
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "해당 주체에 대해 수집된 전화번호입니다."
          },
          "date_of_birth": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "생년월일(개인)입니다."
          },
          "position": {
            "type": "string",
            "nullable": true,
            "description": "자유 형식 직함입니다(개인)."
          },
          "custom_fields": {
            "type": "object",
            "additionalProperties": true,
            "description": "당사자에 대해 수집된 워크플로 정의 커스텀 필드이며, 필드 키를 키로 사용합니다."
          },
          "is_active": {
            "type": "boolean",
            "description": "해당 당사자가 활성 상태인지 여부입니다."
          },
          "is_skipped": {
            "type": "boolean",
            "description": "해당 당사자가 인증 면제 대상인지 여부입니다. 재생성하면 초기화됩니다."
          },
          "requires_verification": {
            "type": "boolean",
            "description": "역할 및 소유 구조 규칙에 따라 이 당사자에 대한 인증이 필요한지 여부입니다."
          },
          "roles": {
            "type": "array",
            "description": "해당 당사자가 회사에서 보유한 역할.",
            "items": {
              "type": "object",
              "required": [
                "role",
                "ownership_percent",
                "voting_percent"
              ],
              "properties": {
                "role": {
                  "type": "string",
                  "enum": [
                    "director",
                    "non_executive_director",
                    "secretary",
                    "chairman",
                    "ubo",
                    "shareholder",
                    "representative",
                    "founder",
                    "legal_advisor",
                    "authorized_signatory",
                    "trustee",
                    "beneficiary",
                    "settlor",
                    "protector",
                    "company_officer",
                    "investor",
                    "other"
                  ],
                  "description": "역할 코드."
                },
                "ownership_percent": {
                  "type": "number",
                  "nullable": true,
                  "description": "알려진 경우, 이 역할의 소유 비율입니다."
                },
                "voting_percent": {
                  "type": "number",
                  "nullable": true,
                  "description": "알려진 경우 이 역할에 대한 의결권 비율입니다."
                }
              }
            }
          },
          "kyc_session_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "하위 개인 KYC 세션(개인)입니다."
          },
          "kyc_session_status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User",
              null
            ],
            "description": "하위 KYC 세션의 상태입니다. 삭제된 세션은 삭제 당시의 상태를 유지합니다."
          },
          "kyc_session_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "하위 KYC 세션의 호스팅 링크입니다. 세션이 없거나 삭제된 경우, 그리고 `sessions: write` 권한이 없는 범위 지정 API 키의 경우 `null`입니다."
          },
          "kyc_session_deleted": {
            "type": "boolean",
            "description": "하위 KYC 세션이 삭제되어 완료될 수 없습니다."
          },
          "kyb_sub_session_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "하위 KYB 세션(법인 당사자)입니다."
          },
          "kyb_sub_session_status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User",
              null
            ],
            "description": "하위 KYB 세션의 상태입니다."
          },
          "kyb_sub_session_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "하위 KYB 세션의 호스팅 링크이며, `kyc_session_url`과 동일한 `null` 규칙이 적용됩니다."
          },
          "kyb_sub_session_deleted": {
            "type": "boolean",
            "description": "`kyc_session_deleted`에 대응하는 기업 당사자 이벤트입니다."
          },
          "verification_workflow_type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "kyc",
              "kyb",
              "adaptive_age_verification",
              "biometric_authentication",
              "address_verification",
              "questionnaire_verification",
              "email_verification",
              "phone_verification",
              null
            ],
            "description": "하위 세션이 실행하는 워크플로 유형입니다."
          },
          "verification_workflow_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "하위 세션이 실행하는 워크플로입니다."
          },
          "verification_workflow_label": {
            "type": "string",
            "nullable": true,
            "description": "해당 워크플로의 라벨입니다."
          },
          "verification_workflow_features": {
            "type": "array",
            "nullable": true,
            "description": "현재 상태가 포함된 하위 세션 워크플로의 기능입니다.",
            "items": {
              "type": "object",
              "required": [
                "feature",
                "status"
              ],
              "properties": {
                "feature": {
                  "type": "string",
                  "description": "기능 코드(예: `ID_VERIFICATION` 또는 `LIVENESS`)."
                },
                "status": {
                  "type": "string",
                  "description": "실행될 때까지 `Not Finished`인 기능 상태입니다."
                }
              }
            }
          },
          "didit_internal_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "인증된 인물이 확인된 경우 해당 인물에 대한 Didit의 식별자입니다."
          }
        }
      },
      "TravelRuleDelivery": {
        "type": "object",
        "description": "이체가 상대방에게 전달해야 하는 최신 메시지의 현재 상태입니다. Didit은 이체를 생성하거나 변경한 요청이 반환된 후 거래 상대방에게 연락하므로, 이 객체는 해당 메시지가 전달되었는지 여부(대기열 등록됨, 전송 중, 오류 후 재시도 대기 중, 전달됨 또는 실패함)를 나타냅니다. 네트워크가 복구될 가능성이 있는 실패(시간 내 응답 없음, 연결 실패, HTTP `408`, `429` 또는 `5xx`)는 30초, 2분, 10분, 30분, 1시간 후에 다시 시도됩니다. 네트워크가 거부했거나 6번째 시도마저 실패하여 첫 번째 메시지(`kind: SEND`)가 완전히 실패하면, 이체는 `timeline`에 `last_error`와 함께 `COUNTERPARTY_VASP_NOT_REACHABLE`로 이동합니다. 완전히 실패한 다른 모든 메시지는 `timeline`에 기록됩니다. 이체의 `status`는 교환 자체에 대한 기준(source of truth)으로 유지됩니다.",
        "required": [
          "kind",
          "status",
          "rail",
          "attempts",
          "last_error",
          "next_attempt_at",
          "delivered_at"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "SEND",
              "ANSWER",
              "TXID",
              "CANCEL",
              "POLL"
            ],
            "description": "메시지에 포함되는 내용입니다. `SEND`: 거래 상대방에게 보내는 전송의 첫 번째 메시지(아웃바운드, 전송 시 레일이 선택됨). `ANSWER`: 요청한 네트워크에 전달해야 하는 귀하의 수락 또는 거부(인바운드). `TXID`: 전송을 완료한 후의 온체인 거래 해시. `CANCEL`: 전송을 취소한 후의 취소. `POLL`: 상태 조회를 제공하는 네트워크에 대한 쿼리로, 전송이 거래 상대방을 기다리는 동안 5분마다 반복됩니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "QUEUED",
              "SENDING",
              "RETRYING",
              "DELIVERED",
              "FAILED"
            ],
            "description": "`QUEUED`: 전송 대기 중. `SENDING`: 시도가 실행 중임. `RETRYING`: 시도가 실패했으며 다음 시도가 `next_attempt_at`에 실행됨. `DELIVERED`: 상대방이 메시지를 수신함. `FAILED`: 상대방이 거부했거나 마지막 시도가 실패함."
          },
          "rail": {
            "type": "string",
            "enum": [
              "INTERNAL",
              "TRP",
              "GTR",
              "TRUST",
              "VERIFYVASP",
              "SYGNA",
              "EMAIL",
              ""
            ],
            "description": "메시지를 전송하는 레일입니다. Didit이 첫 번째 메시지에 대한 레일을 선택하기 전까지는 비어 있습니다."
          },
          "attempts": {
            "type": "integer",
            "minimum": 0,
            "description": "이 메시지에 대해 지금까지 수행된 시도 횟수입니다. 상태 폴링이 아닌 메시지는 최대 6회까지 시도됩니다."
          },
          "last_error": {
            "type": "string",
            "description": "마지막 시도에서 발생한 실패 유형입니다. 실패가 없으면 `\"\"`입니다(예: `email undeliverable`, `trp identity endpoint unreachable` 또는 `trp transfer inquiry delivery failed`). 거래 상대방 자체의 응답은 절대 포함되지 않으며, 이는 전송의 `timeline`에 유지됩니다.\nGTR이 오류로 응답하는 경우 GTR 자체의 상태 코드와 메시지가 포함됩니다. 응답 본문은 절대 포함되지 않습니다.",
            "example": "email undeliverable"
          },
          "next_attempt_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "메시지 상태가 `QUEUED` 또는 `RETRYING`인 동안 다음 시도가 실행되는 시점입니다."
          },
          "delivered_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "상대 측에서 메시지를 수신한 시점입니다."
          }
        }
      },
      "TravelRuleDiscoveryStep": {
        "type": "object",
        "description": "Didit이 아웃바운드 전송을 위해 실행한 거래 상대방 탐색 단계 하나(실행 순서대로 표시)입니다. 경로가 있는 VASP를 지정하는 첫 번째 단계에서 체인이 종료됩니다.",
        "properties": {
          "step": {
            "type": "string",
            "enum": [
              "internal_address_book",
              "wallet_attribution",
              "network_lookup",
              "customer_hint",
              "end_user"
            ],
            "description": "`internal_address_book`: 대상 지갑의 제어권을 증명한 다른 Didit 고객입니다. `wallet_attribution`: 지갑의 블록체인 분석 귀속 정보입니다. `network_lookup`: 해당 주소를 보유한 VASP를 확인할 수 있는 네트워크입니다. `customer_hint`: `beneficiary_data`에 전송한 VASP 이름, LEI 또는 관할 구역입니다. `end_user`: 최종 사용자(또는 귀하)가 선택한 거래 상대방, 또는 선택 요청입니다."
          },
          "outcome": {
            "type": "string",
            "enum": [
              "match",
              "miss",
              "skipped"
            ],
            "description": "`match`: 단계에서 거래 상대방을 지정했습니다. `miss`: 실행되었으나 찾지 못했습니다. `skipped`: 실행할 수 없었으며, `reason`에 그 이유가 표시됩니다."
          },
          "reason": {
            "type": "string",
            "description": "기계 판독 가능한 사유, 일치하는 경우 `\"\"`: `no_proven_internal_wallet`, `attribution_disabled`, `already_attributed`, `no_attributed_entity`, `directory_match_no_route`, `gtr_address_lookup_runs_on_dispatch`, `no_membership`, `network_switched_off`, `no_network_address_lookup`, `no_directory_match`, `awaiting_end_user` 또는 `picked_member_without_proven_wallet`."
          },
          "vasp": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "해당 단계에서 지정한 디렉터리 VASP입니다(지정된 경우)."
          },
          "rail": {
            "type": "string",
            "nullable": true,
            "description": "해당 단계에서 거래 상대방을 찾은 경우, 해당 거래 상대방에 도달하는 레일입니다."
          },
          "at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TravelRuleNextAction": {
        "type": "object",
        "description": "`COUNTERPARTY_VASP_NOT_FOUND` 또는 `COUNTERPARTY_VASP_NOT_REACHABLE` 상태의 전송을 진행시키는 요소 하나입니다. [전송이 중단되는 이유](/ko/transaction-monitoring/travel-rule#전송이-멈춘-이유)를 참조하십시오.",
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "select_counterparty_vasp",
              "declare_self_hosted",
              "add_vasp_hint",
              "update_compliance_email",
              "resend"
            ],
            "description": "`select_counterparty_vasp`: 최종 사용자가 지갑 소유 위젯에서 수취인 VASP를 선택하거나, 귀하가 `action=beneficiary_vasp`로 PATCH 요청을 보냅니다. `declare_self_hosted`: 최종 사용자가 위젯에서 자체 보관 지갑임을 선언합니다. `add_vasp_hint`: VASP 이름, LEI 또는 Travel Address(예: 수취 지갑의 주소록 항목에 있는 `travel_address`)를 통해 Didit에 거래 상대방 정보를 제공한 후 재전송합니다. `update_compliance_email` 및 `resend`는 `PATCH /v3/transactions/{transaction_id}/travel-rule/`의 `action` 값입니다. 거래 상대방의 컴플라이언스 이메일을 다시 입력하고 라우팅을 재실행합니다."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "전송에 위젯 세션이 열려 있는 동안 `select_counterparty_vasp` 및 `declare_self_hosted` 시 지갑 소유권 위젯 링크입니다."
          }
        },
        "required": [
          "action"
        ]
      },
      "TransactionTravelRule": {
        "type": "object",
        "description": "`GET /v3/transactions/{transaction_id}/`, `POST /v3/transactions/`의 `201`, `GET /v3/transactions/`의 각 행에서 반환하는 거래의 Travel Rule 이체입니다. `direction`, `rail`, `counterparty_vasp`, `delivery`, `discovery`, `reason`, `next_actions`는 `PATCH /v3/transactions/{transaction_id}/travel-rule/`와 형식이 동일하므로, 거래를 한 번만 조회해도 이체가 중단된 이유와 진행 방법을 확인할 수 있습니다.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string"
          },
          "protocol": {
            "type": "string",
            "nullable": true
          },
          "required": {
            "type": "boolean"
          },
          "obligations_count": {
            "type": "integer"
          },
          "originator_data": {
            "type": "object",
            "description": "송금인 당사자 정보입니다. 인바운드 전송의 경우 소유 구조가 확인될 때까지 거래 상대방의 값이 마스킹됩니다."
          },
          "beneficiary_data": {
            "type": "object",
            "description": "수취인 당사자 정보입니다. 입금 거래의 경우 소유 구조가 확인될 때까지 거래 상대방의 값이 마스킹됩니다."
          },
          "name_match": {
            "type": "object",
            "nullable": true,
            "description": "이체를 결정한 이름 비교(점수 및 엄격도)입니다. 실행되기 전까지는 null입니다. 비교된 이름은 당사자와 함께 마스킹됩니다."
          },
          "data_match": {
            "$ref": "#/components/schemas/TravelRuleDataMatch"
          },
          "mismatched_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "`data_match.mismatched_fields`의 바로가기입니다. 일치하지 않는 항목이 없으면 비어 있습니다."
          },
          "data_unmasked": {
            "$ref": "#/components/schemas/TravelRuleDataUnmasked"
          },
          "data_masked": {
            "type": "boolean",
            "description": "이 응답에서 거래 상대방의 개인 데이터가 마스킹되어 있는 동안 true입니다."
          },
          "metadata": {
            "type": "object"
          },
          "direction": {
            "type": "string",
            "enum": [
              "INBOUND",
              "OUTBOUND"
            ],
            "description": "이 전송이 거래소의 어느 쪽에 해당하는지입니다."
          },
          "rail": {
            "type": "string",
            "nullable": true,
            "description": "이체가 진행된 레일(`INTERNAL`, `TRP`, `GTR`, `TRUST`, `VERIFYVASP`, `SYGNA` 또는 `EMAIL`(Didit Test VASP가 응답한 샌드박스 애플리케이션의 경우 `TEST_VASP`)) 또는 레일이 선택될 때까지 `null`입니다."
          },
          "counterparty_vasp": {
            "type": "object",
            "nullable": true,
            "properties": {
              "name": {
                "type": "string"
              },
              "lei": {
                "type": "string"
              },
              "dd_score": {
                "type": "integer",
                "description": "0부터 100까지의 실사 점수이며, 높을수록 좋습니다. VASP 디렉터리와 동일한 척도입니다."
              },
              "dd_score_breakdown": {
                "type": "object",
                "description": "dd_score에 대한 구성 요소별 기여도로, VASP 디렉터리와 같이 구성 요소(jurisdiction, verification, protocol, lei, history, essentials, responsiveness)당 하나의 객체이며 각각 {points, max, reason, detail}을 포함합니다. 거래 상대방 평가가 완료될 때까지는 {}입니다.",
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "points": {
                      "type": "number",
                      "description": "이 컴포넌트에 부여된 점수입니다."
                    },
                    "max": {
                      "type": "integer",
                      "description": "이 컴포넌트가 부여할 수 있는 최대 점수입니다."
                    },
                    "reason": {
                      "type": "string",
                      "description": "구성 요소 판정의 기계 판독 가능한 코드."
                    },
                    "detail": {
                      "type": "string",
                      "description": "부여된 점수에 대해 사람이 읽을 수 있는 이유입니다."
                    }
                  }
                }
              },
              "dd_assessed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "실사 평가가 마지막으로 실행된 시점입니다. 거래 상대방이 평가될 때까지는 null입니다."
              }
            },
            "description": "거래 상대방의 디렉터리 항목이며, 전송이 연결되지 않은 경우 `null`입니다."
          },
          "delivery": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleDelivery"
              }
            ],
            "description": "해당 이체가 다른 당사자에게 보내야 하는 최신 메시지입니다. 예를 들어 `threshold_amount` 미만이거나 신고된 자체 보관 지갑인 경우처럼 보낼 메시지가 없었던 경우에는 `null`입니다."
          },
          "discovery": {
            "type": "array",
            "description": "Didit이 거래 상대방을 찾은 방식이며, 실행된 단계당 하나의 항목이 포함됩니다. 인바운드 전송과 같이 조회가 실행되지 않은 경우에는 비어 있습니다.",
            "items": {
              "$ref": "#/components/schemas/TravelRuleDiscoveryStep"
            }
          },
          "reason": {
            "type": "string",
            "description": "`COUNTERPARTY_VASP_NOT_FOUND` 또는 `COUNTERPARTY_VASP_NOT_REACHABLE` 전송이 지연된 이유이며, 다른 모든 상태의 경우 `\"\"`입니다. `COUNTERPARTY_VASP_NOT_REACHABLE`에서만 전송 실패가 먼저 결정됩니다: `email_undeliverable`(메일 제공업체가 컴플라이언스 이메일을 거부했고 시도할 주소가 남아있지 않음: 전송 시, 알림 시, 또는 나중에 보고된 영구 반송 시) 또는 `delivery_failed`(전송 중이던 레일이 완전히 실패함: 네트워크 레일이 메시지를 거부했거나 재시도 횟수를 모두 소진함, `TRP` 신원 호스트가 응답하지 않음, 또는 거래 상대방의 `TRP` 호스트가 조회를 수락하지 않음). 그렇지 않으면 `discovery` 추적이 이를 결정합니다: `awaiting_end_user`(Didit이 도달할 수 있는 거래 상대방을 지정한 단계가 없음), `directory_match_no_route`(경로가 없는 디렉터리 VASP를 지정한 단계임), `picked_member_without_proven_wallet`(최종 사용자가 지갑 제어권을 증명하지 않은 Didit 고객을 선택함), 또는 추적에서 다른 이유를 제공하지 않는 경우 `no_directory_match`. 재전송하면 전송이 진행되므로 이유가 초기화됩니다. [전송이 지연되는 이유](/ko/transaction-monitoring/travel-rule#전송이-멈춘-이유)를 참조하십시오."
          },
          "next_actions": {
            "type": "array",
            "description": "전송을 진행시키는 작업입니다. `COUNTERPARTY_VASP_NOT_FOUND` 또는 `COUNTERPARTY_VASP_NOT_REACHABLE` 이외의 상태에서는 `[]`입니다. `email_undeliverable`은 `update_compliance_email`, 그 다음 `resend`를 제공합니다. `delivery_failed`는 `resend`를 제공합니다. 발견 사유는 `select_counterparty_vasp`, `declare_self_hosted`, `add_vasp_hint` 및 `resend`를 제공합니다.",
            "items": {
              "$ref": "#/components/schemas/TravelRuleNextAction"
            }
          },
          "chain_details": {
            "$ref": "#/components/schemas/TravelRuleChainDetails"
          }
        }
      },
      "NetworkListCounts": {
        "type": "object",
        "description": "목록의 보기 및 필터 옵션에 대한 네트워크 수이며, 각 네트워크는 한 번씩 계산됩니다. `summary`가 `false`가 아닐 때만 반환됩니다. `scopes`는 애플케이션에 표시되는 모든 네트워크를 계산합니다. `views`는 선택한 `scope` 내에서 표시되는 네트워크를 계산합니다. `facets`는 선택한 `scope` 및 `status` 보기의 네트워크를 계산합니다(기각된 네트워크는 `status`에 포함되지 않는 한 제외됩니다). 다른 목록 필터는 이 계산에 영향을 주지 않습니다.",
        "properties": {
          "scopes": {
            "type": "object",
            "description": "제품별로 표시되는 네트워크입니다.",
            "properties": {
              "all": {
                "type": "integer"
              },
              "identity": {
                "type": "integer",
                "description": "기타 모든 네트워크입니다."
              },
              "transactions": {
                "type": "integer",
                "description": "모든 멤버가 거래 당사자인 네트워크입니다."
              }
            }
          },
          "views": {
            "type": "object",
            "description": "선택한 `scope` 내에서 상태별로 표시되는 네트워크와 두 개의 저장된 뷰입니다.",
            "properties": {
              "all": {
                "type": "integer"
              },
              "active": {
                "type": "integer"
              },
              "in_review": {
                "type": "integer"
              },
              "resolved": {
                "type": "integer"
              },
              "dismissed": {
                "type": "integer"
              },
              "mine": {
                "type": "integer",
                "description": "호출하는 콘솔 멤버에게 할당된 네트워크입니다. API 키의 경우 항상 0입니다."
              },
              "high_risk": {
                "type": "integer",
                "description": "기각되지 않은 위험 점수 80 이상의 네트워크입니다."
              }
            }
          },
          "facets": {
            "type": "object",
            "description": "선택한 `scope` 및 상태 보기 내의 각 필터 옵션별 개수입니다.",
            "properties": {
              "total": {
                "type": "integer",
                "description": "선택한 `scope` 및 상태 보기의 네트워크입니다."
              },
              "last_activity_days": {
                "type": "object",
                "description": "최근 7일, 30일, 90일 동안 활동이 있는 네트워크로, 일수별로 키가 지정됩니다.",
                "properties": {
                  "7": {
                    "type": "integer"
                  },
                  "30": {
                    "type": "integer"
                  },
                  "90": {
                    "type": "integer"
                  }
                }
              },
              "risk_min": {
                "type": "object",
                "description": "최소 50 및 최소 80의 위험 점수를 가진 네트워크로, 임계값별로 키가 지정됩니다.",
                "properties": {
                  "50": {
                    "type": "integer"
                  },
                  "80": {
                    "type": "integer"
                  }
                }
              },
              "signal_types": {
                "type": "object",
                "description": "각 유형의 시그널이 하나 이상 있는 네트워크입니다.",
                "properties": {
                  "ip_address": {
                    "type": "integer"
                  },
                  "device": {
                    "type": "integer"
                  },
                  "face": {
                    "type": "integer"
                  },
                  "document_number": {
                    "type": "integer"
                  },
                  "phone": {
                    "type": "integer"
                  },
                  "email": {
                    "type": "integer"
                  },
                  "address": {
                    "type": "integer"
                  }
                }
              },
              "priority": {
                "type": "object",
                "description": "우선순위별 네트워크입니다. `none`은 우선순위가 없는 네트워크를 계산합니다.",
                "properties": {
                  "low": {
                    "type": "integer"
                  },
                  "medium": {
                    "type": "integer"
                  },
                  "high": {
                    "type": "integer"
                  },
                  "none": {
                    "type": "integer"
                  }
                }
              },
              "assignee": {
                "type": "object",
                "description": "담당자별 네트워크입니다.",
                "properties": {
                  "me": {
                    "type": "integer",
                    "description": "호출한 콘솔 멤버에게 할당되었습니다. API 키의 경우 항상 0입니다."
                  },
                  "unassigned": {
                    "type": "integer",
                    "description": "아무에게도 할당되지 않았습니다."
                  },
                  "users": {
                    "type": "array",
                    "description": "담당자당 항목 1개(네트워크 수가 가장 많은 순서로 정렬)입니다.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "uuid": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "full_name": {
                          "type": "string",
                          "description": "담당자의 이름이며, 이름이 설정되지 않은 경우 이메일입니다."
                        },
                        "email": {
                          "type": "string"
                        },
                        "count": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              },
              "has_case": {
                "type": "integer",
                "description": "이 애플리케이션이 케이스를 생성한 네트워크입니다."
              },
              "min_size": {
                "type": "object",
                "description": "최소 10명의 멤버가 있는 네트워크로, 최소 규모별로 키가 지정됩니다.",
                "properties": {
                  "10": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        }
      },
      "NetworkTag": {
        "type": "object",
        "description": "네트워크에서 해당 애플리케이션의 태그 중 하나입니다.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "태그의 UUID로, `tag_uuid`로 전달하는 값과 동일합니다."
          },
          "name": {
            "type": "string"
          },
          "color": {
            "type": "string",
            "description": "16진수 색상 코드입니다(예: `#6366F1`)."
          },
          "source": {
            "type": "string",
            "enum": [
              "didit",
              "custom"
            ],
            "description": "Didit 사전 설정 태그의 경우 `didit`, 팀에서 생성한 태그의 경우 `custom`."
          },
          "added_by": {
            "type": "string",
            "nullable": true,
            "description": "태그를 추가한 콘솔 멤버의 이메일입니다. API 키로 추가한 경우 null입니다."
          },
          "added_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "NetworkOutcomes": {
        "type": "object",
        "description": "네트워크의 개인 및 기업의 현재 상태입니다. 조회 가능한 각 멤버는 결정에 도달한 가장 최근 인증 상태에 따라 한 번씩 카운트됩니다. 거래 당사자는 카운트되지 않습니다.",
        "properties": {
          "approved": {
            "type": "integer",
            "description": "가장 최근 결정된 인증이 승인된 멤버입니다."
          },
          "declined": {
            "type": "integer",
            "description": "가장 최근 결정된 인증이 거부된 멤버입니다."
          },
          "in_review": {
            "type": "integer",
            "description": "가장 최근 결정된 인증이 검토 중인 멤버입니다."
          },
          "total": {
            "type": "integer",
            "description": "결정 여부와 관계없이 최소 한 번 이상 인증을 진행한 멤버입니다. 모든 인증이 미결정(시작되지 않음, 진행 중, 만료됨, 중단됨) 상태인 멤버는 여기에만 집계되고 다른 키에는 집계되지 않습니다."
          }
        }
      },
      "NetworkPatternScore": {
        "type": "object",
        "description": "전체 네트워크에서 멤버들의 데이터 중 한 유형이 얼마나 유사한지 나타냅니다. 패턴은 신호가 아닙니다. 공유된 값이 멤버들을 연결하지는 않습니다.",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "background"
            ],
            "description": "`background`: 인물을 마스킹 처리한 후 멤버의 셀피 배경 쌍 간의 평균 유사도입니다. 각 인물의 최신 셀피 중 가장 최근의 최대 50개를 읽으며 연령 보증 세션은 제외합니다. 사용자 애플리케이션의 멤버뿐만 아니라 전체 네트워크를 대상으로 합니다."
          },
          "score": {
            "type": "number",
            "nullable": true,
            "minimum": 0,
            "maximum": 1,
            "description": "0부터 1까지의 값이며, 소수점 넷째 자리에서 반올림됩니다. `reason`이 설정된 경우 null입니다."
          },
          "members": {
            "type": "integer",
            "nullable": true,
            "description": "점수 산정 시 비교한 멤버 셀피 수입니다. 판독할 수 없거나 배경이 너무 적게 표시된 셀피는 비교되지 않습니다. `computing` 중에는 null이고, `not_enough_selfies`인 경우 0 또는 1입니다."
          },
          "reason": {
            "type": "string",
            "enum": [
              "computing",
              "not_enough_selfies"
            ],
            "nullable": true,
            "description": "점수가 없는 이유입니다. `computing`: 현재 멤버의 점수를 계산하는 중이므로 나중에 네트워크를 다시 조회하세요. `not_enough_selfies`: 사용 가능한 셀피를 보유한 멤버가 2명 미만입니다. 점수가 있으면 null입니다."
          },
          "computed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "점수가 산정된 시점입니다. `computing` 상태인 동안에는 null입니다."
          }
        }
      },
      "NetworkDetailResponse": {
        "description": "네트워크 세부 정보와 조직의 공유 모드, 교차 조직 신호 적용 여부, 네트워크에서의 애플리케이션 태그, 멤버 결과 및 패턴 점수입니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/NetworkDetail"
          },
          {
            "type": "object",
            "properties": {
              "sharing_mode": {
                "type": "string",
                "enum": [
                  "off",
                  "private",
                  "global"
                ],
                "description": "조직의 조직 간 공유 모드입니다. `global`만 조직 간 네트워크를 비교하며, `private` 및 `off`는 해당 조직 자체의 이력으로만 제한합니다.",
                "example": "global"
              },
              "cross_org_available": {
                "type": "boolean",
                "description": "조직 간 신호가 이 조직에 적용되는지 여부입니다. 엔터프라이즈 플랜과 `global` 공유 모드가 모두 필요합니다.",
                "example": true
              },
              "cross_org_unavailable_reason": {
                "type": "string",
                "enum": [
                  "plan",
                  "sharing_mode"
                ],
                "nullable": true,
                "description": "조직 간 신호가 적용되지 않는 이유(확인 순서 기준). `plan`: 공유 모드와 관계없이 조직의 요금제에 조직 간 사기 방지 네트워크가 포함되어 있지 않습니다(Enterprise 요금제 필요). `sharing_mode`: 요금제에는 포함되어 있으나 공유 모드가 `private` 또는 `off`입니다. `cross_org_available`이 `true`인 경우 null입니다.",
                "example": null
              },
              "tags": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NetworkTag"
                },
                "description": "네트워크상에서 귀하 애플리케이션의 태그로, 오래된 순으로 정렬됩니다. 각 애플리케이션은 자신의 태그만 볼 수 있습니다. `fraud_tags`는 별개이며 변경되지 않습니다. 이는 네트워크 멤버들이 보유한 태그입니다."
              },
              "outcomes": {
                "$ref": "#/components/schemas/NetworkOutcomes"
              },
              "patterns": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NetworkPatternScore"
                },
                "description": "전체 네트워크에 걸친 패턴 점수입니다. 현재는 `background` 항목 하나만 제공됩니다."
              }
            }
          }
        ]
      },
      "NetworkTagRequest": {
        "type": "object",
        "required": [
          "tag_uuid"
        ],
        "properties": {
          "tag_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "애플리케이션 태그 중 하나의 UUID입니다."
          }
        },
        "example": {
          "tag_uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
        }
      },
      "NetworkTimeline": {
        "title": "Default timeline (no contract)",
        "type": "object",
        "description": "`contract` 미지정 시: 네트워크 자체 이벤트가 페이지네이션 없이 오래된 순서대로 반환됩니다.",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkTimelineEvent"
            }
          }
        }
      },
      "NetworkTimelinePage": {
        "title": "Typed timeline page (contract=2)",
        "type": "object",
        "description": "`contract=2`인 경우: 타입이 지정된 이벤트 1페이지(최신순 정렬)입니다.",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkTypedTimelineEvent"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true,
            "description": "다음 페이지를 읽으려면 `cursor`로 전달하세요. 마지막 페이지에서는 null입니다."
          }
        }
      },
      "NetworkTypedTimelineEvent": {
        "type": "object",
        "description": "타입이 지정된 타임라인 이벤트 1건: 기본 필드 4개와 해당 id, Didit이 저장한 시점, 속한 멤버 계정 및 레코드, 그리고 해당 이벤트 타입의 세부 정보 블록이 포함됩니다. 다른 세부 정보 블록은 null입니다.",
        "properties": {
          "id": {
            "type": "string",
            "description": "`<source>:<uuid>`, 타임라인 내에서 고유합니다.",
            "example": "session:3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "event_type": {
            "type": "string",
            "enum": [
              "network_detected",
              "signal_observed",
              "network_active",
              "network_in_review",
              "network_resolved",
              "network_dismissed",
              "verification_attempt",
              "transaction",
              "login",
              "rule_hit",
              "case_linked",
              "note_added"
            ]
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "description": "발생한 시점입니다."
          },
          "ingested_at": {
            "type": "string",
            "format": "date-time",
            "description": "Didit이 이를 저장한 시점입니다."
          },
          "label": {
            "type": "string",
            "description": "영문 짧은 라벨(예: `Verification attempt 2 of 3`)입니다."
          },
          "metadata": {
            "type": "object",
            "description": "네트워크 자체 이벤트의 경우 기본 타임라인과 동일한 메타데이터입니다. 그 외의 경우 비어 있습니다."
          },
          "account": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineAccount"
              }
            ],
            "nullable": true,
            "description": "멤버 계정입니다. 네트워크 자체 이벤트, `case_linked` 및 `note_added`의 경우 null입니다."
          },
          "source_ref": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineSourceRef"
              }
            ],
            "nullable": true,
            "description": "소스 레코드입니다. 네트워크 자체 이벤트 및 `note_added`의 경우 null입니다."
          },
          "verification_attempt": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineAttempt"
              }
            ],
            "nullable": true,
            "description": "`verification_attempt` 이벤트에 설정됩니다."
          },
          "transaction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineTransaction"
              }
            ],
            "nullable": true,
            "description": "`transaction` 이벤트에 설정됩니다."
          },
          "login": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineLogin"
              }
            ],
            "nullable": true,
            "description": "`login` 이벤트에 설정됩니다."
          },
          "rule_hit": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineRuleHit"
              }
            ],
            "nullable": true,
            "description": "`rule_hit` 이벤트에 설정됩니다."
          },
          "case_linked": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineCaseLinked"
              }
            ],
            "nullable": true,
            "description": "`case_linked` 이벤트에 설정됩니다."
          },
          "note_added": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineNoteAdded"
              }
            ],
            "nullable": true,
            "description": "`note_added` 이벤트에 설정됩니다. API 키에는 절대 반환되지 않습니다."
          }
        }
      },
      "NetworkTimelineAccount": {
        "type": "object",
        "description": "이벤트가 속한 멤버 계정입니다.",
        "properties": {
          "node_id": {
            "type": "string",
            "description": "`<kind>:<uuid>` 형식이며, 여기서 종류(kind)는 `vendor_user`, `vendor_business`, `transaction_party` 중 하나입니다.",
            "example": "vendor_user:3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "node_type": {
            "type": "string",
            "enum": [
              "account",
              "business_account",
              "transaction_party"
            ]
          },
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "vendor_data": {
            "type": "string",
            "nullable": true
          },
          "display_name": {
            "type": "string",
            "nullable": true
          },
          "ownership": {
            "type": "string",
            "enum": [
              "owned",
              "organization"
            ],
            "description": "레코드가 호출한 애플리케이션에 속한 경우(콘솔 멤버의 경우 권한이 부여된 애플리케이션) `owned`입니다. 조직의 다른 애플리케이션에 속한 경우 `organization`입니다."
          },
          "route": {
            "$ref": "#/components/schemas/NetworkTimelineRoute"
          }
        }
      },
      "NetworkTimelineSourceRef": {
        "type": "object",
        "description": "이벤트를 읽어온 레코드입니다.",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "session",
              "business_session",
              "transaction",
              "monitoring_event",
              "case"
            ]
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "ownership": {
            "type": "string",
            "enum": [
              "owned",
              "organization"
            ],
            "description": "레코드가 호출한 애플리케이션에 속한 경우(콘솔 멤버의 경우 권한이 부여된 애플리케이션) `owned`입니다. 조직의 다른 애플리케이션에 속한 경우 `organization`입니다."
          },
          "route": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineRoute"
              }
            ],
            "description": "`monitoring_event` 및 `case`에는 없습니다."
          }
        }
      },
      "NetworkTimelineRoute": {
        "type": "object",
        "description": "레코드가 열리는 위치: 종류, UUID 및 레코드가 속한 애플리케이션.",
        "properties": {
          "kind": {
            "type": "string",
            "description": "계정의 경우 `user`, `business` 또는 `transaction_party`이며, 소스 레코드의 경우 `session`, `business_session` 또는 `transaction`입니다."
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "application_id": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "NetworkTimelineAttempt": {
        "type": "object",
        "description": "해당 계정의 인증 세션 1건입니다.",
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "세션 UUID 또는 기업의 경우 비즈니스 세션 UUID입니다."
          },
          "session_number": {
            "type": "integer",
            "nullable": true
          },
          "attempt": {
            "type": "integer",
            "description": "계정의 세션 중 생성 순서에 따른 이 세션의 위치입니다."
          },
          "attempt_count": {
            "type": "integer",
            "description": "해당 계정에 속한 세션 수입니다."
          },
          "status": {
            "type": "string",
            "description": "세션 상태입니다(예: `Approved` 또는 `Declined`)."
          },
          "status_changed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "decline_reasons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkTimelineDeclineReason"
            },
            "description": "거부된 세션에 한함: 경고 목록이며 가장 오래된 순으로 경고당 한 번씩 표시됩니다. 그 외의 경우 비어 있습니다."
          }
        }
      },
      "NetworkTimelineDeclineReason": {
        "type": "object",
        "properties": {
          "risk": {
            "type": "string",
            "description": "경고 코드입니다."
          },
          "feature": {
            "type": "string",
            "description": "경고를 발생시킨 기능입니다."
          },
          "short_description": {
            "type": "string"
          }
        }
      },
      "NetworkTimelineTransaction": {
        "type": "object",
        "description": "멤버 계정이 참여한 거래로, 거래 일자를 기준으로 기록됩니다.",
        "properties": {
          "transaction_id": {
            "type": "string",
            "format": "uuid"
          },
          "transaction_number": {
            "type": "integer",
            "nullable": true
          },
          "transaction_type": {
            "type": "string"
          },
          "action_type": {
            "type": "string"
          },
          "amount": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineAmount"
              }
            ],
            "nullable": true,
            "description": "거래에 금액이 없는 경우 null입니다."
          },
          "status": {
            "type": "string"
          },
          "decision_reason_code": {
            "type": "string",
            "nullable": true
          },
          "decision_reason_label": {
            "type": "string",
            "nullable": true
          },
          "party_role": {
            "type": "string",
            "description": "거래에서 계정의 역할: `APPLICANT`, `REMITTER`, `BENEFICIARY` 또는 `COUNTERPARTY`입니다."
          }
        }
      },
      "NetworkTimelineAmount": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string",
            "description": "문자열 형태의 십진수 금액입니다."
          },
          "currency": {
            "type": "string"
          },
          "direction": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "NetworkTimelineLogin": {
        "type": "object",
        "description": "이벤트 API를 통해 개인에 대해 게시한 로그인 이벤트입니다.",
        "properties": {
          "action": {
            "type": "string",
            "description": "`<event_category>.<action_type>`: 로그인 성공의 경우 `auth.login` 또는 `security.login_succeeded`, 실패한 경우 `auth.login_failed` 또는 `security.login_failed`입니다."
          },
          "succeeded": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "description": "이벤트의 상태입니다."
          },
          "ip": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineIP"
              }
            ],
            "nullable": true,
            "description": "이벤트에 IP 주소가 없는 경우 null입니다."
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineDevice"
              }
            ],
            "nullable": true,
            "description": "이벤트에 기기 핑거프린트 또는 컨텍스트가 없는 경우 null입니다."
          },
          "is_first_login": {
            "type": "boolean",
            "description": "기록된 계정의 최초 성공 로그인입니다."
          },
          "is_new_device": {
            "type": "boolean",
            "description": "해당 계정의 이전 성공한 로그인 기록에 존재하지 않는 기기에서의 성공한 로그인입니다. 첫 번째 로그인에서는 절대 true가 될 수 없습니다."
          }
        }
      },
      "NetworkTimelineIP": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string"
          },
          "country_code": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "connection_type": {
            "type": "string",
            "nullable": true,
            "description": "주소에 대한 연결 유형 라벨(자유 텍스트)입니다."
          },
          "is_vpn_or_tor": {
            "type": "boolean"
          },
          "is_data_center": {
            "type": "boolean"
          }
        }
      },
      "NetworkTimelineDevice": {
        "type": "object",
        "properties": {
          "fingerprint": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true,
            "description": "이벤트의 기기 컨텍스트로부터 생성된 읽기 쉬운 기기 라벨입니다."
          }
        }
      },
      "NetworkTimelineRuleHit": {
        "type": "object",
        "description": "멤버의 거래 또는 이벤트와 일치하는 활성 규칙입니다. 테스트 모드 일치 항목은 포함되지 않습니다.",
        "properties": {
          "rule_id": {
            "type": "string",
            "format": "uuid"
          },
          "rule_title": {
            "type": "string"
          },
          "rule_category": {
            "type": "string"
          },
          "rule_source": {
            "type": "string"
          },
          "severity": {
            "type": "string",
            "nullable": true
          },
          "score_delta": {
            "type": "integer"
          },
          "status_target": {
            "type": "string",
            "nullable": true
          },
          "action_summary": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "NetworkTimelineCaseLinked": {
        "type": "object",
        "description": "조직 내 네트워크를 위해 생성된 케이스입니다. `source_ref.ownership`은 호출한 애플리케이션에 속하는지 여부를 나타냅니다.",
        "properties": {
          "case_id": {
            "type": "string",
            "format": "uuid"
          },
          "case_number": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string"
          },
          "author_email": {
            "type": "string",
            "nullable": true
          },
          "author_name": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "NetworkTimelineNoteAdded": {
        "type": "object",
        "description": "네트워크에 남겨진 메모입니다. 메모 텍스트는 포함되지 않습니다.",
        "properties": {
          "note_id": {
            "type": "string",
            "format": "uuid"
          },
          "author_email": {
            "type": "string"
          }
        }
      },
      "FeatureStatusOverride": {
        "type": "object",
        "description": "`PATCH /v3/session/{sessionId}/features/{nodeId}/update-status/`로 수행된 검사(기능) 상태의 재정의 항목 하나입니다. 변경 내용, 적용 여부 또는 사용자가 플로우를 완료할 때까지 대기 중인지 여부, 요청한 주체 및 사유를 포함합니다.",
        "required": [
          "id",
          "node_id",
          "feature_type",
          "feature_model",
          "previous_status",
          "new_status",
          "state",
          "forced",
          "reason",
          "requested_by",
          "requested_at",
          "applied_at",
          "cancelled_at",
          "cancel_reason"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "재정의 식별자입니다. 취소 endpoint에 전달하십시오.",
            "example": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
          },
          "node_id": {
            "type": "string",
            "description": "요청에 지정된 워크플로 노드(노드가 없는 단계의 경우 `default`).",
            "example": "feature_ocr_1"
          },
          "feature_type": {
            "type": "string",
            "description": "요청이 전달한 `feature_type`이며, 전달하지 않은 경우 빈 문자열입니다.",
            "example": ""
          },
          "feature_model": {
            "type": "string",
            "description": "재정의된 검사 종류입니다(예: `KYC`, `Face`, `AML` 또는 `GeolocationCheck`).",
            "example": "KYC"
          },
          "previous_status": {
            "type": "string",
            "enum": [
              "Not Finished",
              "Approved",
              "Declined",
              "In Review",
              "Resub Requested"
            ],
            "description": "재정의가 요청되었을 때의 검사 상태입니다.",
            "example": "In Review"
          },
          "new_status": {
            "type": "string",
            "enum": [
              "Approved",
              "Declined",
              "In Review"
            ],
            "description": "재정의를 통해 설정된 상태입니다.",
            "example": "Approved"
          },
          "state": {
            "type": "string",
            "enum": [
              "applied",
              "pending_until_flow_finishes",
              "cancelled"
            ],
            "description": "`applied`: 검사에 새 상태가 적용되었습니다. `pending_until_flow_finishes`: 재지정 사항이 대기 상태를 유지하다가 사용자가 흐름을 완료하면 적용됩니다. `cancelled`: 대기 상태였으나 적용되지 않았습니다(`cancel_reason` 참조).",
            "example": "applied"
          },
          "forced": {
            "type": "boolean",
            "description": "사용자가 플로우에 머무르는 동안 오버라이드가 즉시 적용된 경우 `true`입니다.",
            "example": false
          },
          "reason": {
            "type": "string",
            "nullable": true,
            "description": "요청과 함께 전송된 `comment` 또는 `null`입니다.",
            "example": "Document manually verified by compliance."
          },
          "requested_by": {
            "type": "object",
            "nullable": true,
            "description": "누가 재정의를 요청했는지 나타내며, 알 수 없는 경우 `null`입니다.",
            "properties": {
              "email": {
                "type": "string",
                "format": "email",
                "nullable": true,
                "description": "콘솔 사용자의 이메일이며, API 키 및 시스템의 경우 `null`입니다.",
                "example": "reviewer@example.com"
              },
              "name": {
                "type": "string",
                "nullable": true,
                "description": "요청자의 표시 이름 또는 `null`입니다.",
                "example": "Alex Reviewer"
              },
              "type": {
                "type": "string",
                "enum": [
                  "CONSOLE_USER",
                  "API_KEY",
                  "SYSTEM"
                ],
                "description": "요청을 보낸 주체: 콘솔 사용자, API 키 또는 Didit 자체입니다.",
                "example": "CONSOLE_USER"
              }
            }
          },
          "requested_at": {
            "type": "string",
            "format": "date-time",
            "description": "재정의가 요청된 시점입니다.",
            "example": "2026-10-13T09:15:00Z"
          },
          "applied_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "검사가 새 상태로 변경된 시점이며, 대기 중이거나 취소된 후에는 `null`입니다.",
            "example": "2026-10-13T09:15:00Z"
          },
          "cancelled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "대기 중인 오버라이드가 취소된 시점 또는 `null`입니다.",
            "example": null
          },
          "cancel_reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "cancelled_by_reviewer",
              "replaced",
              "check_changed",
              "session_closed",
              null
            ],
            "description": "대기 중인 오버라이드가 적용되지 않은 이유 또는 `null`입니다. `cancelled_by_reviewer`: 취소 endpoint로 취소됨. `replaced`: 동일한 검사에 대한 최신 오버라이드로 대체됨. `check_changed`: 사용자가 흐름을 완료하기 전에 검사를 다시 수행함. `session_closed`: 사용자가 흐름을 완료하기 전에 세션을 벗어남(중단됨, 만료됨 또는 흐름 도중 결정됨).",
            "example": null
          }
        }
      },
      "SandboxSimulateRequest": {
        "type": "object",
        "description": "샌드박스 세션의 상태를 강제 설정합니다. 모든 필드는 선택 사항이지만 `new_status`, `scenario`, `risk` 중 하나 이상은 필수입니다.",
        "properties": {
          "new_status": {
            "type": "string",
            "enum": [
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned"
            ],
            "description": "설정할 상태입니다. 생략할 경우 위험 케이스의 기본 상태(`risk` 또는 시나리오의 매직 값에 포함된 첫 번째 위험)로 기본 설정되며, 그렇지 않은 경우 시나리오의 기본 상태로 설정됩니다.",
            "example": "Declined"
          },
          "comment": {
            "type": "string",
            "maxLength": 500,
            "description": "상태 변경으로 기록되는 활동 항목에 추가된 메모입니다.",
            "example": "Testing the decline path"
          },
          "scenario": {
            "type": "string",
            "maxLength": 100,
            "description": "카탈로그(`GET /v1/sandbox/scenarios/`)의 시나리오 슬러그입니다. 기본 상태를 제공하며, `risk`가 없는 경우 매직 값이 전달하는 경고를 제공합니다. 알 수 없는 슬러그는 `400`을 반환합니다.",
            "example": "decline_aml_hit"
          },
          "risk": {
            "type": "string",
            "maxLength": 128,
            "description": "카탈로그의 위험 케이스입니다. 해당 경고는 세션에 추가되며, 로그 유형은 `new_status`를 따릅니다. 알 수 없는 값은 `400`을 반환합니다.",
            "example": "POSSIBLE_MATCH_FOUND"
          },
          "node_id": {
            "type": "string",
            "maxLength": 128,
            "description": "위험 경고가 연결된 워크플로 노드입니다. 기본값은 세션의 현재 노드입니다.",
            "example": "feature_aml_1"
          },
          "send_webhooks": {
            "type": "boolean",
            "default": true,
            "description": "`true`는 실제 상태 변경 시 전송되는 것과 정확히 동일한 webhook을 샌드박스 애플리케이션의 대상으로 전송합니다. 구독 중인 대상에 대해 `status.updated` 및 해당 변경으로 인해 발생하는 `user.status.updated` / `user.data.updated`(또는 `business.status.updated` / `business.data.updated`) 이벤트가 전송됩니다. `false`는 webhook을 기록하거나 전송하지 않고 상태를 변경합니다. 누락된 webhook 복구 기능은 해당 결정을 다시 전송하지 않으며 콘솔은 계속 실시간으로 업데이트되고 세션의 다음 상태 변경 시 정상적으로 webhook이 전송됩니다.",
            "example": true
          }
        }
      },
      "SandboxSimulateResponse": {
        "type": "object",
        "required": [
          "session_id",
          "previous_status",
          "status",
          "scenario",
          "risk",
          "send_webhooks"
        ],
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "previous_status": {
            "type": "string",
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User"
            ],
            "description": "시뮬레이션 전 세션의 상태입니다.",
            "example": "In Progress"
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned"
            ],
            "description": "시뮬레이션을 통해 설정된 상태입니다.",
            "example": "Declined"
          },
          "scenario": {
            "type": "string",
            "nullable": true,
            "description": "전달한 시나리오 슬러그 또는 `null`입니다.",
            "example": "decline_aml_hit"
          },
          "risk": {
            "type": "string",
            "nullable": true,
            "description": "적용된 위험 케이스(`risk` 또는 시나리오에서 가져온 케이스)이며, 없는 경우 `null`입니다.",
            "example": "POSSIBLE_MATCH_FOUND"
          },
          "send_webhooks": {
            "type": "boolean",
            "description": "시뮬레이션에서 적용된 `send_webhooks` 값입니다.",
            "example": false
          }
        }
      },
      "CaseTeamSummary": {
        "type": "object",
        "nullable": true,
        "description": "케이스를 소유한 검토 팀이거나, 소유한 팀이 없는 경우 null입니다. 라우팅 규칙이 케이스를 해당 팀 중 하나에 배정할 때 라우팅에 의해 설정됩니다. `PATCH .../cases/{case_uuid}/`(`team`)로 변경하거나 비울 수 있습니다.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "CaseChecker": {
        "type": "object",
        "nullable": true,
        "description": "대기 중인 결정을 승인하거나 거부하도록 지정된 멤버입니다. 4인 승인 결정이 지정된 검토자를 기다리는 동안에만 설정됩니다. 대기 중인 항목이 없거나, 대기 중인 결정이 검토자 대기열에서 대기 중이거나, 증거가 변경되어 결정이 승인, 거부 또는 새로운 검토를 위해 반환된 경우에는 null입니다.",
        "properties": {
          "member_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "멤버의 사용자 uuid입니다. 케이스를 해결할 때 `checker`로 전달하는 값입니다."
          },
          "name": {
            "type": "string",
            "nullable": true,
            "description": "멤버의 성명이며, 알 수 없는 경우 null입니다."
          },
          "email": {
            "type": "string",
            "format": "email"
          }
        }
      },
      "ServiceStatusFeed": {
        "type": "object",
        "description": "공개 서비스 상태: 각 Didit 서비스의 상태, 전체 상태 및 진행 중이거나 지난 7일 동안 해결된 인시던트입니다.",
        "required": [
          "status",
          "updated_at",
          "services",
          "incidents"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "operational",
              "degraded",
              "down"
            ],
            "description": "진행 중인 인시던트만을 기준으로 판단한 현재 모든 서비스 중 가장 심각한 상태입니다.",
            "example": "degraded"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Didit이 이 응답을 생성한 시점(ISO 8601, UTC)입니다. 응답은 30초 동안 캐시되므로 최대 30초 전의 데이터일 수 있습니다.",
            "example": "2026-10-13T09:41:07.512345Z"
          },
          "services": {
            "type": "array",
            "description": "서비스당 항목 1개이며, 모든 서비스가 항상 나열됩니다.",
            "items": {
              "$ref": "#/components/schemas/ServiceStatusService"
            }
          },
          "incidents": {
            "type": "array",
            "description": "최신 `started_at` 순입니다. 진행 중인 모든 인시던트와 최근 7일 동안 해결된 인시던트(최대 50개의 해결된 인시던트)를 포함합니다. 해당 기간 동안 발생한 일이 없으면 비어 있습니다.",
            "items": {
              "$ref": "#/components/schemas/ServiceStatusIncident"
            }
          }
        }
      },
      "ServiceStatusService": {
        "type": "object",
        "required": [
          "key",
          "name",
          "status"
        ],
        "properties": {
          "key": {
            "type": "string",
            "enum": [
              "service_id_verification",
              "service_liveness_face_match",
              "service_aml_screening",
              "service_kyb_registries",
              "service_database_validation",
              "service_phone_delivery",
              "service_email_delivery",
              "service_transaction_monitoring"
            ],
            "description": "고정 서비스 키입니다. 표시 이름이 아닌 이 키와 일치시켜야 합니다. `service_id_verification`: 신분증 인증, `service_liveness_face_match`: 라이브니스 및 얼굴 대조, `service_aml_screening`: AML 스크리닝, `service_kyb_registries`: KYB 레지스트리, `service_database_validation`: 데이터베이스 검증, `service_phone_delivery`: 전화번호 인증 전송, `service_email_delivery`: 이메일 인증 전송, `service_transaction_monitoring`: 거래 모니터링.",
            "example": "service_database_validation"
          },
          "name": {
            "type": "string",
            "description": "서비스의 영어 표시 이름입니다.",
            "example": "Database validation"
          },
          "status": {
            "type": "string",
            "enum": [
              "operational",
              "degraded",
              "down"
            ],
            "description": "서비스에 진행 중인 인시던트가 없으면 `operational`이며, 그렇지 않으면 진행 중인 인시던트 중 가장 심각한 상태가 표시됩니다.",
            "example": "degraded"
          }
        }
      },
      "ServiceStatusIncident": {
        "type": "object",
        "required": [
          "id",
          "service",
          "service_name",
          "state",
          "status",
          "title",
          "body",
          "affected",
          "country_name",
          "started_at",
          "resolved_at",
          "duration_minutes"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "인시던트 ID입니다.",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "service": {
            "type": "string",
            "enum": [
              "service_id_verification",
              "service_liveness_face_match",
              "service_aml_screening",
              "service_kyb_registries",
              "service_database_validation",
              "service_phone_delivery",
              "service_email_delivery",
              "service_transaction_monitoring"
            ],
            "description": "영향을 받는 서비스의 키입니다(`services[].key` 참조).",
            "example": "service_database_validation"
          },
          "service_name": {
            "type": "string",
            "description": "영향을 받는 서비스의 영어 표시 이름입니다.",
            "example": "Database validation"
          },
          "state": {
            "type": "string",
            "enum": [
              "degraded",
              "down"
            ],
            "description": "서비스가 영향을 받는 방식입니다. 해결된 인시던트는 마지막 상태를 유지합니다.",
            "example": "degraded"
          },
          "status": {
            "type": "string",
            "enum": [
              "ongoing",
              "resolved"
            ],
            "description": "서비스가 복구될 때까지 `ongoing`이며, 복구되면 `resolved`입니다.",
            "example": "ongoing"
          },
          "title": {
            "type": "string",
            "description": "영어 헤드라인입니다. 번역하려면 `service`, `state`, `country_name`을 사용하여 자체 텍스트를 구성하세요.",
            "example": "Database validation is degraded in Brazil."
          },
          "body": {
            "type": "string",
            "description": "영어 세부 정보 문구: 검사가 지연되거나 실패할 수 있게 된 시점 또는 복구된 시점입니다.",
            "example": "Checks against Brazil (CPF) may be slow or fail since 08:55 UTC."
          },
          "affected": {
            "type": "string",
            "description": "영향을 받는 국가 또는 등기소입니다(예: `Brazil (CPF)`). 인시던트가 특정 국가 또는 등기소와 연관되지 않은 경우 비어 있습니다.",
            "example": "Brazil (CPF)"
          },
          "country_name": {
            "type": "string",
            "description": "영향을 받는 국가(영문)입니다. 인시던트가 특정 국가와 연관되지 않은 경우 비어 있습니다.",
            "example": "Brazil"
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "description": "인시던트가 시작된 시점(ISO 8601, UTC).",
            "example": "2026-10-13T08:55:00Z"
          },
          "resolved_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "서비스가 복구된 시점(ISO 8601, UTC). 인시던트가 진행 중인 동안에는 `null`입니다."
          },
          "duration_minutes": {
            "type": "integer",
            "nullable": true,
            "description": "`started_at`부터 `resolved_at`까지의 정수(분) 단위 시간입니다. 인시던트가 진행 중인 동안에는 `null`입니다."
          }
        }
      },
      "TravelRuleJoinInvitation": {
        "type": "object",
        "description": "아무것도 입력하기 전에 참여 페이지에 표시되는 내용입니다.",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "초대장이 전송된 주소입니다."
          },
          "vasp_name": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "초대의 출처입니다(예: `pickup`)."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "prefill": {
            "type": "object",
            "properties": {
              "vasp_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true
              },
              "legal_name": {
                "type": "string"
              },
              "lei": {
                "type": "string"
              },
              "jurisdiction": {
                "type": "string"
              },
              "domains": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "TravelRuleJoinRegisterRequest": {
        "type": "object",
        "required": [
          "email",
          "password"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254,
            "description": "초대가 발송된 주소여야 합니다."
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "maxLength": 128
          }
        }
      },
      "TravelRuleJoinVerifyRequest": {
        "type": "object",
        "required": [
          "email",
          "code"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          },
          "code": {
            "type": "string",
            "minLength": 6,
            "maxLength": 6,
            "description": "등록 후 이메일로 전송된 6자리 코드입니다."
          }
        }
      },
      "TravelRuleJoinCredentials": {
        "type": "object",
        "description": "새로운 무료 조직 및 해당 애플리케이션이 API를 호출할 때 사용하는 자격 증명입니다.",
        "properties": {
          "organization": {
            "type": "object",
            "properties": {
              "uuid": {
                "type": "string",
                "format": "uuid"
              }
            }
          },
          "application": {
            "type": "object",
            "properties": {
              "uuid": {
                "type": "string",
                "format": "uuid"
              }
            }
          },
          "client_id": {
            "type": "string"
          },
          "api_key": {
            "type": "string",
            "description": "워크스페이스 endpoint에서 `x-api-key` 헤더로 전송하십시오."
          }
        }
      },
      "TravelRuleWorkspaceClaimRequest": {
        "type": "object",
        "required": [
          "vasp_id"
        ],
        "properties": {
          "vasp_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 워크스페이스에 해당하는 디렉터리 항목입니다. `GET /v3/travel-rule/vasps/`에서 id 목록을 조회하세요."
          }
        }
      },
      "TravelRuleWorkspaceDomainConfirmRequest": {
        "type": "object",
        "required": [
          "code"
        ],
        "properties": {
          "code": {
            "type": "string",
            "minLength": 6,
            "maxLength": 6
          }
        }
      },
      "TravelRuleWorkspaceBillingRequest": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "default": true,
            "description": "`true`만 허용됩니다. API를 통해 아웃바운드 결제를 다시 끌 수는 없습니다."
          }
        }
      },
      "TravelRuleWorkspaceDomainCodeResponse": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "unverified",
              "code_sent",
              "verified"
            ]
          },
          "txt": {
            "$ref": "#/components/schemas/TravelRuleWorkspaceTxtRecord"
          }
        }
      },
      "TravelRuleWorkspaceTxtRecord": {
        "type": "object",
        "description": "DNS 증명을 위해 게시할 TXT 레코드입니다. 증명이 시작되기 전까지는 비어 있습니다.",
        "properties": {
          "host": {
            "type": "string",
            "example": "didit-tr-verify.example.com"
          },
          "value": {
            "type": "string"
          }
        }
      },
      "TravelRuleWorkspace": {
        "type": "object",
        "description": "무료로 가입한 애플리케이션의 무료 Travel Rule 워크스페이스입니다.",
        "properties": {
          "joined_free": {
            "type": "boolean"
          },
          "work_email": {
            "type": "string",
            "format": "email"
          },
          "joined_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "claim": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "unclaimed",
                  "pending_review",
                  "claimed",
                  "rejected"
                ]
              },
              "proved_by_domain": {
                "type": "boolean"
              },
              "claimed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "reviewed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "review_note": {
                "type": "string"
              },
              "vasp_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true
              },
              "vasp_name": {
                "type": "string"
              }
            }
          },
          "prefill": {
            "type": "object",
            "description": "디렉터리 항목에서 가져온 프로필 값: `vasp_id`, `legal_name`, `lei`, `jurisdiction`, `compliance_email`, `domains`. 클레임이 제기될 때까지 아무것도 기록되지 않습니다."
          },
          "domain": {
            "type": "object",
            "properties": {
              "domain": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "unverified",
                  "code_sent",
                  "verified"
                ]
              },
              "verified_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "txt": {
                "$ref": "#/components/schemas/TravelRuleWorkspaceTxtRecord"
              }
            }
          },
          "billing_enabled": {
            "type": "boolean",
            "description": "Travel Rule 데이터 수신은 무료입니다. 전송은 결제가 활성화된 후에만 비용이 청구됩니다."
          },
          "billing_enabled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "didit_network": {
            "type": "object",
            "description": "Didit 네트워크에 이 VASP가 등록되어 있는지 여부와 등록되지 않은 경우 여전히 충족되지 않은 각 조건입니다."
          },
          "settings": {
            "$ref": "#/components/schemas/TravelRuleSettingsDetail"
          }
        }
      },
      "InvestigatorDecision": {
        "type": "object",
        "description": "해당 항목이 Investigator 대기열을 벗어난 방식입니다. `decided_by`, `original_outcome`, `overrides`는 승인 및 재정의 endpoint와 보고서에서 반환되며, 세션 결정의 `investigator` 블록에는 기타 필드가 포함됩니다.",
        "properties": {
          "outcome": {
            "type": "string",
            "enum": [
              "accepted",
              "edited",
              "overridden",
              "decided_elsewhere",
              "automated"
            ],
            "description": "`accepted` 또는 `edited`는 권고안을 수락했음을 나타내며(`edited`는 서술 내용을 수정한 경우임), `overridden`은 다른 작업을 취했음을, `decided_elsewhere`는 보고서가 열려 있는 동안 Investigator 외부에서 결정이 내려졌음을, `automated`는 Investigator가 자체적으로 결정을 내렸음을 의미합니다."
          },
          "action": {
            "type": "string",
            "enum": [
              "approve",
              "decline",
              "escalate",
              "request"
            ]
          },
          "actor_email": {
            "type": "string",
            "nullable": true
          },
          "actor_name": {
            "type": "string",
            "nullable": true
          },
          "override_category": {
            "type": "string",
            "enum": [
              "missing_context",
              "needs_information",
              "policy_differs",
              "evidence_misread",
              "other",
              ""
            ],
            "nullable": true
          },
          "override_reason": {
            "type": "string",
            "nullable": true
          },
          "final_status": {
            "type": "string",
            "description": "결정 후 항목의 상태입니다."
          },
          "agreed": {
            "type": "boolean",
            "description": "결정이 권장 사항과 일치했는지 여부입니다.",
            "nullable": true
          },
          "decided_at": {
            "type": "string",
            "format": "date-time"
          },
          "billed": {
            "type": "boolean",
            "description": "검토 비용이 청구되었습니다."
          },
          "decided_by": {
            "type": "string",
            "enum": [
              "investigator",
              "member"
            ]
          },
          "original_outcome": {
            "type": "object",
            "description": "이후 재정의에 의해 변경되지 않은, 조사자가 자체적으로 내린 결정입니다. 팀이 내린 결정의 경우 null입니다.",
            "properties": {
              "action": {
                "type": "string"
              },
              "final_status": {
                "type": "string"
              },
              "decided_at": {
                "type": "string",
                "format": "date-time"
              }
            },
            "nullable": true
          },
          "overrides": {
            "type": "array",
            "description": "Investigator가 단독으로 내린 결정의 모든 재정의 내역(오래된 순)입니다.",
            "items": {
              "type": "object",
              "properties": {
                "action": {
                  "type": "string"
                },
                "actor_email": {
                  "type": "string",
                  "nullable": true
                },
                "actor_name": {
                  "type": "string",
                  "nullable": true
                },
                "override_category": {
                  "type": "string"
                },
                "override_reason": {
                  "type": "string"
                },
                "previous_status": {
                  "type": "string"
                },
                "final_status": {
                  "type": "string"
                },
                "agreed": {
                  "type": "boolean",
                  "nullable": true
                },
                "overridden_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          }
        }
      },
      "InvestigatorBlock": {
        "type": "object",
        "nullable": true,
        "description": "항목의 최신 조사관 검토 내역이며, 검토가 진행된 적이 없는 경우 null입니다. V3 세션 및 기업 세션 결정에 포함되어 전달됩니다(따라서 `status.updated` webhook에서도 전달됨).",
        "properties": {
          "run_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "running",
              "completed",
              "failed"
            ]
          },
          "stage": {
            "type": "string",
            "enum": [
              "shadow",
              "live"
            ]
          },
          "queue": {
            "type": "string",
            "enum": [
              "kyc",
              "kyb",
              "aml",
              "transactions",
              "cases"
            ]
          },
          "is_open": {
            "type": "boolean"
          },
          "recommendation": {
            "type": "string",
            "enum": [
              "approve",
              "decline",
              "escalate",
              "request"
            ],
            "nullable": true
          },
          "recommendation_detail": {
            "type": "string",
            "nullable": true
          },
          "confidence": {
            "type": "string",
            "enum": [
              "high",
              "moderate",
              "low"
            ],
            "nullable": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "ready_to_accept": {
            "type": "boolean"
          },
          "prepared_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "automated": {
            "type": "boolean",
            "description": "이후에 결정이 재정의되었더라도 수사관(Investigator)이 단독으로 결정했습니다."
          },
          "decided_by": {
            "type": "string",
            "enum": [
              "investigator",
              "member"
            ],
            "nullable": true
          },
          "decision": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/InvestigatorDecision"
              }
            ],
            "type": "object"
          }
        }
      },
      "InvestigatorQueueRow": {
        "type": "object",
        "properties": {
          "run_id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "enum": [
              "session",
              "business_session",
              "transaction",
              "case"
            ]
          },
          "queue": {
            "type": "string",
            "enum": [
              "kyc",
              "kyb",
              "aml",
              "transactions",
              "cases"
            ]
          },
          "stage": {
            "type": "string",
            "enum": [
              "shadow",
              "live"
            ]
          },
          "subject": {
            "type": "object",
            "description": "검토 중인 항목입니다: `id`, `number`, `status`, `name` 및 유형에 따라 `country`, `workflow`, `vendor_data`, `txn_id`, `amount`, `currency`, `direction`, `title`, `priority` 등이 포함됩니다.",
            "additionalProperties": true
          },
          "recommendation": {
            "type": "string",
            "enum": [
              "approve",
              "decline",
              "escalate",
              "request"
            ]
          },
          "recommendation_detail": {
            "type": "string"
          },
          "confidence": {
            "type": "string",
            "enum": [
              "high",
              "moderate",
              "low"
            ]
          },
          "summary": {
            "type": "string"
          },
          "sources_count": {
            "type": "integer"
          },
          "ready_to_accept": {
            "type": "boolean"
          },
          "guardrails": {
            "description": "이 항목을 포함하는 잠긴 가드레일입니다(있는 경우)."
          },
          "waiting_since": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "due_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "prepared_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "InvestigatorRunDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/InvestigatorQueueRow"
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string"
              },
              "is_open": {
                "type": "boolean"
              },
              "lookups": {
                "type": "integer",
                "description": "읽은 섹션 및 연결된 기록 수입니다."
              },
              "duration_ms": {
                "type": "integer",
                "nullable": true
              },
              "agent_version": {
                "type": "string"
              },
              "prepared_before_opened": {
                "type": "boolean",
                "nullable": true
              },
              "report": {
                "type": "object",
                "additionalProperties": true,
                "description": "보고서: 추론 내용, 판정 결과(`ok`, `risk`, `look`, `explained`, `context`) 및 인용 출처가 포함된 근거 항목, 스크리닝 일치 판정 결과(`same`, `not_same`, `unclear`), 제안된 후속 단계입니다."
              },
              "trail": {
                "description": "확인한 내용: 순서대로 읽은 개요, 섹션 및 기록입니다."
              },
              "decision": {
                "nullable": true,
                "allOf": [
                  {
                    "$ref": "#/components/schemas/InvestigatorDecision"
                  }
                ],
                "type": "object"
              },
              "autonomy": {
                "type": "object",
                "additionalProperties": true,
                "description": "자동화 엔진이 보고서를 처리한 결과(`result`, `reason`, `tier`, `policy_version`, `rule`, `agreement`, `decisions`, `threshold`, `at`)입니다. 대기열이 자동화되지 않은 경우 null입니다.",
                "nullable": true
              }
            }
          }
        ]
      },
      "InvestigatorAcceptRequest": {
        "type": "object",
        "properties": {
          "narrative": {
            "type": "string",
            "maxLength": 4000,
            "description": "재작성된 내러티브입니다. 이를 전송하면 결정이 수정 및 수락된 것으로 기록됩니다."
          },
          "send_email": {
            "type": "boolean",
            "default": false,
            "description": "해당 인물에게 결정 사항을 이메일로 알립니다."
          },
          "email_address": {
            "type": "string",
            "format": "email",
            "description": "`send_email`이 true일 때 필수입니다."
          },
          "email_language": {
            "type": "string",
            "default": "en",
            "maxLength": 16
          }
        }
      },
      "InvestigatorOverrideRequest": {
        "type": "object",
        "required": [
          "action",
          "category",
          "reason"
        ],
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "approve",
              "decline",
              "escalate",
              "request"
            ]
          },
          "category": {
            "type": "string",
            "enum": [
              "missing_context",
              "needs_information",
              "policy_differs",
              "evidence_misread",
              "other"
            ]
          },
          "reason": {
            "type": "string",
            "minLength": 10,
            "maxLength": 500
          },
          "send_email": {
            "type": "boolean",
            "default": false,
            "description": "해당 인물에게 결정 사항을 이메일로 알립니다."
          },
          "email_address": {
            "type": "string",
            "format": "email",
            "description": "`send_email`이 true일 때 필수입니다."
          },
          "email_language": {
            "type": "string",
            "default": "en",
            "maxLength": 16
          }
        }
      },
      "InvestigatorBatchAcceptRequest": {
        "type": "object",
        "required": [
          "run_ids"
        ],
        "properties": {
          "run_ids": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        }
      },
      "InvestigatorBatchAcceptResponse": {
        "type": "object",
        "properties": {
          "accepted": {
            "type": "integer"
          },
          "skipped": {
            "type": "integer"
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "run_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "result": {
                  "type": "string",
                  "enum": [
                    "accepted",
                    "skipped"
                  ]
                },
                "reason": {
                  "type": "string",
                  "enum": [
                    "not_found",
                    "forbidden",
                    "already_decided",
                    "not_ready",
                    "guardrail",
                    "invalid"
                  ]
                },
                "detail": {},
                "action": {
                  "type": "string"
                },
                "final_status": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "InvestigatorSettings": {
        "type": "object",
        "properties": {
          "stage": {
            "type": "string",
            "enum": [
              "none",
              "shadow",
              "live"
            ]
          },
          "stage_changed_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true,
            "nullable": true
          },
          "stage_changed_by": {
            "type": "string",
            "readOnly": true
          },
          "monthly_spend_limit": {
            "type": "string",
            "format": "decimal",
            "description": "결제 통화 기준 월간 한도(0.01~1,000,000)입니다. Null은 한도를 비활성화합니다.",
            "nullable": true
          },
          "spend_limit": {
            "type": "object",
            "readOnly": true,
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "limit": {
                "type": "string",
                "format": "decimal",
                "nullable": true
              },
              "spent": {
                "type": "string",
                "format": "decimal"
              },
              "reviews": {
                "type": "integer"
              },
              "reserved": {
                "type": "string",
                "format": "decimal",
                "description": "수락 시 비용이 청구되므로 보류된, 진행 중인 모든 라이브 보고서의 가격입니다."
              },
              "currency": {
                "type": "string"
              },
              "paused": {
                "type": "boolean",
                "description": "한도 도달: 새로운 검토가 시작되지 않습니다."
              }
            }
          }
        }
      },
      "TravelRuleUtxoEntry": {
        "type": "object",
        "description": "체인에 기록된 UTXO 거래의 입력 또는 출력 1개입니다.",
        "required": [
          "address"
        ],
        "properties": {
          "address": {
            "type": "string",
            "maxLength": 128
          },
          "amount": {
            "type": "string",
            "nullable": true,
            "description": "해당 코인 자체의 단위(사토시가 아닌 BTC)로 표시된 십진수 문자열입니다. 선택 사항입니다.",
            "example": "0.0125"
          },
          "txid": {
            "type": "string",
            "maxLength": 128,
            "description": "선택 사항입니다. 입력(input)이 사용하는 거래입니다."
          },
          "vout": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "description": "선택 사항입니다. 입력(input)이 사용하는 출력 인덱스(output index)입니다."
          }
        }
      },
      "TravelRuleUtxo": {
        "type": "object",
        "description": "UTXO 전송(BTC, LTC, BCH, DOGE)의 입력 및 출력입니다. 해당 체인에서만 허용되며, 다른 체인에서는 `400`이 반환됩니다. Didit은 이를 통해 송금인 지갑(신고된 지갑, 없을 경우 가장 많이 기여한 입력 주소)과 수취인 출력(신고된 출력, 없을 경우 입력 주소로 거스름돈을 반환하지 않는 유일한 출력, 그것도 없을 경우 전송 금액을 지급하는 하나의 출력)을 추론합니다. 결과는 전송의 `chain_details`에 포함됩니다.",
        "required": [
          "outputs"
        ],
        "properties": {
          "inputs": {
            "type": "array",
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/TravelRuleUtxoEntry"
            },
            "description": "선택 사항입니다. 입력(inputs)이 없으면 송금인이 추론되지 않으며 잔돈 출력(change output)도 인식되지 않습니다."
          },
          "outputs": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/TravelRuleUtxoEntry"
            }
          }
        }
      },
      "TravelRuleChainSide": {
        "type": "object",
        "description": "Didit이 체인 데이터로부터 확인한 한쪽 지갑입니다.",
        "properties": {
          "address": {
            "type": "string",
            "description": "지갑입니다. 메모 네트워크에서는 클래식 주소(XRP X-address는 클래식 주소와 태그로 분할됨), Lightning에서는 수취인 노드 ID 또는 Lightning Address입니다."
          },
          "memo": {
            "type": "string",
            "description": "지갑의 일부인 대상 태그 또는 메모입니다. 없는 경우 `\"\"`입니다."
          },
          "source": {
            "type": "string",
            "enum": [
              "declared",
              "x_address",
              "largest_input",
              "only_non_change_output",
              "amount_match",
              "invoice_payee",
              "updated"
            ],
            "description": "지갑의 출처: `declared`(요청값), `x_address`(XRP X-address에서 분리됨), `largest_input`(가장 많이 기여한 UTXO 입력 주소), `only_non_change_output`(거스름돈이 아닌 유일한 UTXO 출력), `amount_match`(이체 금액을 지급하는 하나의 UTXO 출력), `invoice_payee`(라이트닝 결제 요청에 지정된 수취인), `updated`(`action: update_originator_wallet`으로 추후 설정됨)."
          }
        }
      },
      "TravelRuleChainDetails": {
        "type": "object",
        "description": "둘 이상의 주소가 다른 주소로 지불할 때 전송 체인이 두 지갑의 이름을 지정하는 방식입니다. 두 주소가 곧 지갑인 계정 기반 체인 전송(EVM, Solana, Tron)의 경우 비어 있습니다(`{}`). 매칭, 라우팅 및 주소록은 여기에서 지갑을 먼저 읽습니다.",
        "properties": {
          "chain": {
            "type": "string",
            "description": "표준 체인입니다(예: `BTC`, `XRP`, 또는 Lightning 전송의 경우 `LIGHTNING`)."
          },
          "shape": {
            "type": "string",
            "enum": [
              "utxo",
              "memo",
              "lightning"
            ]
          },
          "originator": {
            "$ref": "#/components/schemas/TravelRuleChainSide"
          },
          "beneficiary": {
            "$ref": "#/components/schemas/TravelRuleChainSide"
          },
          "utxo": {
            "type": "object",
            "description": "UTXO 전송 시: 저장된 입력 및 출력(금액은 십진수 문자열)과 Didit이 각 출력을 무엇으로 판독했는지 나타냅니다.",
            "properties": {
              "inputs": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TravelRuleUtxoEntry"
                }
              },
              "outputs": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TravelRuleUtxoEntry"
                }
              },
              "change_output_indexes": {
                "type": "array",
                "items": {
                  "type": "integer"
                },
                "description": "입력 주소로 다시 지불하는 출력입니다."
              },
              "beneficiary_output_index": {
                "type": "integer",
                "nullable": true,
                "description": "수취인에게 지급하는 출력값입니다. 구분할 수 없는 경우 null입니다."
              }
            }
          },
          "lightning": {
            "type": "object",
            "description": "Lightning 전송의 경우: 결제 요청에 명시된 내용입니다. 항상 `kind`(`bolt11`, `bolt12_offer`, `bolt12_invoice`, `bolt12_invoice_request`, `lnurl`, `lightning_address`, `node_id` 또는 `unknown`)를 포함하며, BOLT11 인보이스는 `network`, `payee_node_id`, `payment_hash`, `amount_msat`, `created_at`, `expires_at`을 추가하고, BOLT12 문자열은 `blinded_paths` 및 `payee_node_id`를 추가하며, LNURL 또는 Lightning Address는 해당 `domain`을 추가합니다. 네트워크를 통해 확인되는 것은 없으며 요청만 디코딩됩니다.",
            "additionalProperties": true
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "declared_originator_not_an_input",
                "declared_beneficiary_not_an_output",
                "beneficiary_output_ambiguous",
                "beneficiary_output_amount_differs"
              ]
            },
            "description": "확인이 필요한 UTXO 불일치 사항: 신고된 송금인이 입력(input)에 없음, 신고된 수취인이 출력(output)에 없음, 단일 수취인 출력을 구별할 수 없음, 또는 수취인 출력이 거래에 명시된 금액과 다른 금액을 지급함."
          },
          "not_applicable_reason": {
            "type": "string",
            "enum": [
              "LIGHTNING_NO_PAYEE_IDENTIFIER",
              "LIGHTNING_BOLT12_BLINDED_PAYEE",
              "LIGHTNING_LNURL_NAMES_NO_PAYEE"
            ],
            "description": "결제 요청에 수취인이 명시되지 않은 발신 Lightning 전송의 경우: 전송이 `NOT_APPLICABLE`인 이유입니다. `LIGHTNING_NO_PAYEE_IDENTIFIER`(요청에 수취인 노드가 명시되지 않았거나 디코딩할 수 없음), `LIGHTNING_BOLT12_BLINDED_PAYEE`(오퍼가 블라인드 경로 뒤에 수취인을 숨김), `LIGHTNING_LNURL_NAMES_NO_PAYEE`(LNURL이 수취인이 아닌 서비스를 지정함). 동일한 코드가 전송의 마지막 `timeline` 항목을 엽니다."
          }
        }
      },
      "WalletAddressImportRow": {
        "type": "object",
        "description": "가져올 지갑 1개: `address`, `address_hash` 또는 둘 다로 지정합니다. `walletAddress`, `walletAddressHash`, `destinationTag`, `externalUserId`뿐만 아니라 이 필드들의 camelCase 형식도 허용됩니다.",
        "properties": {
          "address": {
            "type": "string",
            "maxLength": 128,
            "description": "지갑 주소입니다. 별칭: `walletAddress`."
          },
          "address_hash": {
            "type": "string",
            "description": "소문자로 변환된 주소의 SHA-256(64자의 16진수 또는 44자의 base64 문자)입니다. 주소를 공개하지 않고 지갑을 등록하려면 이 값만 전송하십시오. `address`와 함께 전송하는 경우 해당 주소의 해시여야 합니다. 별칭: `walletAddressHash`."
          },
          "chain": {
            "type": "string",
            "maxLength": 32
          },
          "memo": {
            "type": "string",
            "maxLength": 256,
            "description": "대상 태그 또는 메모입니다. XRP: 대상 태그로, 0부터 4294967295까지의 정수입니다(JSON 숫자 허용). XLM: 최대 28바이트의 텍스트 메모, 64비트 id 또는 32바이트 16진수 해시입니다. EOS: 최대 256바이트입니다. ATOM: 최대 256자입니다. HBAR: 최대 100바이트입니다. Bitcoin, EVM, Solana, Tron, Litecoin, Bitcoin Cash, Dogecoin 및 Lightning 지갑은 메모를 지원하지 않으며, 포함 시 `400`이 반환됩니다."
          },
          "holder_name": {
            "type": "string",
            "maxLength": 255
          },
          "holder_vendor_data": {
            "type": "string",
            "maxLength": 255,
            "description": "보유자에 대한 귀하의 내부 식별자입니다. 별칭: `externalUserId`."
          },
          "entity_type": {
            "type": "string",
            "enum": [
              "individual",
              "company"
            ],
            "default": "individual"
          },
          "label": {
            "type": "string",
            "maxLength": 255
          },
          "owner_type": {
            "type": "string",
            "enum": [
              "customer",
              "internal",
              "vasp"
            ],
            "default": "customer"
          },
          "travel_address": {
            "type": "string",
            "maxLength": 512
          },
          "self_declared": {
            "type": "boolean",
            "default": false,
            "description": "설정에서 허용하는 경우 자체 신고를 통해 이미 검증된 항목을 생성합니다."
          }
        }
      },
      "WalletAddressImportReport": {
        "type": "object",
        "description": "전송된 순서대로 가져오기의 각 행에 대해 발생한 내용입니다.",
        "properties": {
          "total": {
            "type": "integer"
          },
          "created": {
            "type": "integer"
          },
          "existing": {
            "type": "integer"
          },
          "duplicate": {
            "type": "integer"
          },
          "failed": {
            "type": "integer"
          },
          "rows": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "row": {
                  "type": "integer",
                  "description": "1부터 시작하는 행 번호입니다."
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "created",
                    "existing",
                    "duplicate",
                    "failed"
                  ],
                  "description": "`created`: 장부에 추가됨. `existing`: 지갑이 이미 장부에 존재하여 변경되지 않음. `duplicate`: 이번 가져오기의 이전 행과 중복됨. `failed`: `errors` 참조."
                },
                "entry_id": {
                  "type": "string",
                  "format": "uuid",
                  "nullable": true,
                  "description": "해당 행에서 생성하거나 찾은 주소록 항목입니다."
                },
                "errors": {
                  "type": "object",
                  "description": "`failed` 행의 필드 오류입니다. 그렇지 않은 경우 비어 있습니다."
                },
                "duplicate_of_row": {
                  "type": "integer",
                  "nullable": true,
                  "description": "`duplicate` 행인 경우, 해당 행이 반복하는 행입니다."
                }
              }
            }
          }
        }
      },
      "TravelRuleCounterpartyContact": {
        "type": "object",
        "description": "하나의 디렉터리 항목에 대해 EMAIL 레일이 발송하는 컴플라이언스 주소입니다.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "counterparty": {
            "type": "string",
            "format": "uuid",
            "description": "GET /v3/travel-rule/vasps/에 표시되는 디렉터리 항목의 `id`입니다."
          },
          "counterparty_name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "name": {
            "type": "string",
            "description": "팀 이름 등과 같은 선택적 라벨입니다."
          },
          "source": {
            "type": "string",
            "enum": [
              "staff",
              "application",
              "learned"
            ],
            "description": "staff: Didit이 관리함. learned: 응답 링크를 통해 요청에 응답한 VASP 자체 도메인 중 하나의 주소. application: 귀하의 애플리케이션에서 추가함."
          },
          "scope": {
            "type": "string",
            "enum": [
              "platform",
              "application"
            ],
            "description": "platform: Didit이 큐레이션하거나 검증된 답변에서 학습하여 모든 Didit 고객에게 사용되며 귀하에게는 읽기 전용입니다. application: 귀하의 애플리케이션 전용입니다."
          },
          "created_by": {
            "type": "string",
            "description": "플랫폼 연락처 및 API 키로 추가된 연락처의 경우 비어 있습니다."
          },
          "verified_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "이 주소가 응답 링크를 통해 요청에 마지막으로 응답한 시점입니다."
          },
          "is_invalid": {
            "type": "boolean",
            "description": "해당 주소로 반송(bounce)되었거나 불만(complaint)이 접수되면 true이며, EMAIL 레일은 이를 건너뜁니다."
          },
          "invalid_reason": {
            "type": "string",
            "enum": [
              "",
              "hard_bounce",
              "soft_bounce",
              "spam_complaint",
              "suppressed"
            ]
          },
          "invalid_detail": {
            "type": "string",
            "description": "수신 메일 서버에서 제공한 사유(있는 경우)입니다."
          },
          "invalid_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TravelRuleCounterpartyContactCreate": {
        "type": "object",
        "required": [
          "counterparty",
          "email"
        ],
        "properties": {
          "counterparty": {
            "type": "string",
            "format": "uuid",
            "description": "디렉터리 항목의 `id`입니다."
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          },
          "name": {
            "type": "string",
            "description": "선택적 라벨입니다.",
            "maxLength": 255
          }
        }
      },
      "TravelRuleNameMatch": {
        "type": "object",
        "nullable": true,
        "description": "이체를 결정한 이름 비교이거나, 실행되기 전까지는 null입니다. 당사자가 마스킹되어 있는 동안, 그리고 INTERNAL 교환의 다른 고객 사본에서는 `transfer_name`, `compared_name`, `matched_names`, `mismatched_names`가 숨겨집니다. `score`와 `matched`는 일치하지 않을 수 있습니다. `matched`는 엄격도를 따르고, `score`는 두 전체 성명의 유사도입니다.",
        "properties": {
          "score": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "두 성명 간의 유사도로, 0에서 100 사이입니다. 어느 한쪽 이름이 비어 있으면 0입니다."
          },
          "matched": {
            "type": "boolean",
            "description": "이름이 `strictness`를 충족하는지 여부입니다. 전송 결과는 모든 필드를 비교하는 `data_match`를 따르므로, 이 값이 true인 상태에서도 전송이 COUNTERPARTY_MISMATCHED_DATA가 될 수 있습니다."
          },
          "method": {
            "type": "string",
            "enum": [
              "none",
              "exact_token",
              "token_subset",
              "token_containment",
              "sequence_ratio"
            ],
            "description": "`matched`가 결정된 방식입니다. none (`NONE`), exact_token (`STRICT`), token_subset (`DEFAULT`), token_containment (`CONTAINS`) 또는 sequence_ratio (`FUZZY`)."
          },
          "strictness": {
            "type": "string",
            "enum": [
              "NONE",
              "STRICT",
              "CONTAINS",
              "DEFAULT",
              "FUZZY"
            ]
          },
          "compared_with": {
            "type": "string",
            "enum": [
              "wallet_holder",
              "counterparty_vasp"
            ],
            "description": "wallet_holder: 지갑에 기록된 소유자. counterparty_vasp: 거래 상대방이 이메일 응답 페이지에서 답변한 이름 또는 샌드박스 환경에서 Didit Test VASP의 답변입니다."
          },
          "transfer_name": {
            "type": "string",
            "description": "이체 내역상의 이름입니다."
          },
          "compared_name": {
            "type": "string",
            "description": "비교 대상이 된 이름입니다."
          },
          "matched_names": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "`compared_name`에서 발견된 `transfer_name`의 단어들입니다."
          },
          "mismatched_names": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "`compared_name`에 없는 `transfer_name`의 단어들이 먼저 나오고, 그 뒤에 `transfer_name`에 없는 `compared_name`의 단어들이 나옵니다."
          }
        }
      },
      "TravelRuleTransferRow": {
        "type": "object",
        "description": "전송 목록에 표시되는 Travel Rule 전송 건 1개입니다. VASP 이름, 지갑 및 메모만 포함되며 송금인 또는 수취인 개인 데이터는 절대 포함되지 않습니다.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "전송의 id입니다."
          },
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "description": "이체가 속한 Didit 거래입니다."
          },
          "txn_id": {
            "type": "string",
            "nullable": true,
            "description": "거래에 대한 귀하 고유의 ID입니다. Didit Test VASP 인바운드 전송과 같이 Didit이 대신 기록하는 전송에는 생성된 ID가 포함됩니다."
          },
          "txn_date": {
            "type": "string",
            "format": "date-time"
          },
          "kind": {
            "type": "string",
            "enum": [
              "withdrawal",
              "deposit",
              "message"
            ],
            "description": "withdrawal: 아웃바운드. message: 거래 상대방의 메시지(TRP 문의, INTERNAL 인바운드 구간, 또는 GTR, VerifyVASP 또는 Sygna Bridge 메시지)로부터 레일이 생성한 인바운드 이체. deposit: 기타 모든 인바운드 이체."
          },
          "direction": {
            "type": "string",
            "enum": [
              "INBOUND",
              "OUTBOUND"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "AWAITING_COUNTERPARTY",
              "ON_HOLD",
              "COMPLETED",
              "FINISHED",
              "CANCELLED",
              "EXPIRED",
              "COUNTERPARTY_MISMATCHED_DATA",
              "COUNTERPARTY_VASP_NOT_FOUND",
              "COUNTERPARTY_VASP_NOT_REACHABLE",
              "UNCONFIRMED_OWNERSHIP",
              "COUNTERPARTY_VASP_GENERAL_DECLINE",
              "NOT_ENOUGH_COUNTERPARTY_DATA",
              "NOT_APPLICABLE"
            ]
          },
          "reason": {
            "type": "string",
            "description": "`COUNTERPARTY_VASP_NOT_FOUND` 또는 `COUNTERPARTY_VASP_NOT_REACHABLE` 전송이 지연된 이유로, 전송 자체의 `reason`과 동일한 값이므로 각 전송을 열어보지 않고도 목록에서 반송된 컴플라이언스 이메일인지 경로가 없는 거래 상대방인지 확인할 수 있습니다. 다른 모든 상태의 경우 `\"\"`입니다. [전송이 지연되는 이유](/ko/transaction-monitoring/travel-rule#전송이-멈춘-이유)를 참조하십시오."
          },
          "rail": {
            "type": "string",
            "nullable": true,
            "enum": [
              "INTERNAL",
              "TRP",
              "GTR",
              "TRUST",
              "VERIFYVASP",
              "SYGNA",
              "EMAIL",
              "TEST_VASP",
              null
            ]
          },
          "asset": {
            "type": "string",
            "description": "거래의 통화입니다."
          },
          "amount": {
            "type": "string",
            "description": "일반 소수점 형식의 금액입니다(예: \"1.25\")."
          },
          "originator_vasp": {
            "type": "string",
            "description": "아웃바운드: 귀하 VASP의 법인명. 인바운드: 디렉터리 항목, Didit 네트워크 멤버, TRP 발송인, Didit Test VASP 또는 전송에 명시된 이름에서 가져온 거래 상대방의 이름. 알려진 이름이 없는 경우 비어 있습니다."
          },
          "beneficiary_vasp": {
            "type": "string",
            "description": "아웃바운드: 동일한 방식으로 확인된 거래 상대방 이름. 인바운드: 귀하 VASP의 법인명."
          },
          "originator_wallet": {
            "type": "string"
          },
          "beneficiary_wallet": {
            "type": "string"
          },
          "originator_memo": {
            "type": "string",
            "description": "메모 또는 목적지 태그이며, 없는 체인에서는 비어 있습니다."
          },
          "beneficiary_memo": {
            "type": "string"
          },
          "originator_wallet_type": {
            "type": "string",
            "enum": [
              "vasp",
              "self_hosted",
              "own"
            ],
            "description": "vasp, self_hosted(비호스팅으로 신고됨) 또는 own(귀하의 주소록에 귀하의 것으로 기록된 지갑). 귀하 측은 항상 vasp입니다."
          },
          "beneficiary_wallet_type": {
            "type": "string",
            "enum": [
              "vasp",
              "self_hosted",
              "own"
            ]
          },
          "matched_transaction_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "사전 통지된 이체에 수동으로 매칭한 입금의 상대방 측입니다."
          },
          "deadline_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "이체가 거래 상대방을 계속 대기 중인 경우 만료되는 시점입니다. 발신 또는 수신 여부와 관계없이 정보 교환이 필요한, `POST /v3/transactions/`로 생성하는 모든 이체에 설정됩니다. 임계값 미만인 경우, Travel Rule이 적용되지 않는 Lightning 결제인 경우, 그리고 거래 상대방이 도달할 때 Didit이 생성하는 수신 이체(수신 TRP 문의, 네트워크 메시지 또는 INTERNAL 수신 레그)의 경우 null입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BankAccountCheckHolder": {
        "description": "계좌 확인 대상 이름입니다. `full_name`과 `business_name` 중 정확히 하나만 전송하세요.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/BankAccountCheckPersonHolder"
          },
          {
            "$ref": "#/components/schemas/BankAccountCheckBusinessHolder"
          }
        ]
      },
      "BankAccountCheckRequest": {
        "type": "object",
        "required": [
          "country",
          "account",
          "holder"
        ],
        "properties": {
          "country": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3,
            "description": "ISO 3166-1 alpha-3 코드 형식의 계정 국가입니다(예: `NGA`). 소문자도 허용됩니다.",
            "example": "NGA"
          },
          "account": {
            "type": "object",
            "description": "해당 국가의 표기 방식에 따른 계좌입니다: `iban` 또는 해당 국가에 필요한 은행 또는 지점 코드(`sort_code`, `routing_number`, `transit_institution`, `bsb`, `ifsc`, `bank_code` 또는 `bic`)가 포함된 `account_number`입니다. 멕시코는 `clabe`, 아르헨티나는 `cbu_cvu`를 사용하며 은행을 이미 식별합니다. 기업 계좌의 경우 국가에서 요구하면 `registration_id`를 추가합니다. 공백, 대시 및 마침표는 무시됩니다. 해당 국가의 검증에 사용되지 않는 키는 무시되며, 필요한 키가 제공되지 않으면 해당 키를 명시하는 `400`이 반환됩니다.",
            "properties": {
              "iban": {
                "type": "string",
                "maxLength": 64,
                "description": "IBAN을 사용하는 국가의 IBAN입니다. `country`와 일치해야 합니다."
              },
              "account_number": {
                "type": "string",
                "maxLength": 64,
                "description": "별도의 은행 또는 지점 코드로 계좌를 표기하는 국가에서의 계좌번호입니다."
              },
              "sort_code": {
                "type": "string",
                "maxLength": 64,
                "description": "영국: 6자리 sort code입니다."
              },
              "routing_number": {
                "type": "string",
                "maxLength": 64,
                "description": "미국: 9자리 ABA 라우팅 번호입니다."
              },
              "transit_institution": {
                "type": "string",
                "maxLength": 64,
                "description": "캐나다: 8자리 지점 및 금융기관 번호입니다."
              },
              "bsb": {
                "type": "string",
                "maxLength": 64,
                "description": "호주: 6자리 BSB입니다."
              },
              "ifsc": {
                "type": "string",
                "maxLength": 64,
                "description": "인도: 11자리 IFSC."
              },
              "bank_code": {
                "type": "string",
                "maxLength": 64,
                "description": "해당 국가에서 필요한 경우 은행 코드입니다(예: 나이지리아)."
              },
              "bic": {
                "type": "string",
                "maxLength": 64,
                "description": "해당 국가의 확인에서 요구하는 경우 은행의 BIC입니다."
              },
              "clabe": {
                "type": "string",
                "maxLength": 64,
                "description": "멕시코: 18자리 CLABE입니다. 은행명이 이미 포함되어 있습니다."
              },
              "cbu_cvu": {
                "type": "string",
                "maxLength": 64,
                "description": "아르헨티나: 22자리 CBU 또는 CVU입니다. 은행을 이미 식별합니다."
              },
              "registration_id": {
                "type": "string",
                "maxLength": 64,
                "description": "해당 국가에서 요구하는 비즈니스 계정의 등록번호입니다."
              }
            },
            "additionalProperties": {
              "type": "string",
              "maxLength": 64
            },
            "example": {
              "bank_code": "000014",
              "account_number": "0123450001"
            }
          },
          "holder": {
            "$ref": "#/components/schemas/BankAccountCheckHolder"
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 검사에 대한 귀하 고유의 참조값이며, 변경 없이 반환됩니다.",
            "example": "payout_20481"
          },
          "consent": {
            "type": "boolean",
            "default": false,
            "description": "계좌 명의인이 이 검사에 명시적으로 동의한 경우 `true`로 설정합니다. 해당 동의가 필요한 계좌 검사 국가에서는 필수 항목입니다. 동의가 없으면 `field`가 `consent`이고 `reason`이 `required`인 `400` 오류와 함께 검사가 거부되며 요금이 청구되지 않습니다. 그 외 지역에서는 선택 사항이며, 전송 시 Didit이 검사 요금 청구와 함께 이를 기록합니다.",
            "example": true
          }
        }
      },
      "BankAccountCheckResponse": {
        "type": "object",
        "required": [
          "request_id",
          "result",
          "holder_name",
          "account",
          "vendor_data",
          "created_at"
        ],
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 검사의 ID입니다."
          },
          "result": {
            "type": "string",
            "enum": [
              "match",
              "close_match",
              "no_match",
              "cannot_verify"
            ],
            "description": "`match`: 은행에서 보낸 이름으로 계좌를 보유하고 있습니다. `close_match`: 유사한 이름(예: 중간 이름 누락 또는 오타)으로 보유하고 있습니다. `no_match`: 다른 이름으로 보유하고 있거나 해당 계좌가 존재하지 않습니다. `cannot_verify`: 은행이 이름을 비교하지 않고 응답했습니다(예: 차단되었거나 해지된 계좌)."
          },
          "holder_name": {
            "type": "string",
            "nullable": true,
            "description": "`close_match`인 경우 및 은행이 이를 반환한 경우에만 해당합니다: 은행에 보관된 계좌의 예금주명입니다. 그렇지 않으면 `null`입니다."
          },
          "account": {
            "type": "string",
            "description": "마지막 4자리를 제외하고 마스킹된 계좌입니다."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "전송하신 그대로의 귀하 고유 참조값입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "검사가 실행된 시점(UTC)입니다."
          }
        }
      },
      "BankAccountCheckError": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "detail": {
            "type": "string",
            "description": "오류 내용(영문)."
          },
          "code": {
            "type": "string",
            "description": "분기 처리를 위한 고정 코드입니다. `401` 및 `403`에는 제공되지 않습니다."
          },
          "field": {
            "type": "string",
            "description": "`400` 전용: 수정해야 할 본문 필드로, 점으로 구분된 경로(예: `account.sort_code`) 형식입니다."
          },
          "reason": {
            "type": "string",
            "enum": [
              "required",
              "length",
              "format",
              "checksum",
              "country_mismatch",
              "rejected"
            ],
            "description": "`400` 전용: 해당 필드가 거부된 이유입니다. `required`, `length`, `format`, `checksum`, `country_mismatch`(다른 국가의 IBAN)는 Didit 자체 검사이며, `rejected`는 은행이 전송된 계좌를 거부했음을 의미합니다."
          }
        }
      },
      "BankVerificationResult": {
        "type": "object",
        "description": "사용자 인증 및 기업 확인(KYB)을 위한 단일 은행 인증 단계의 결과입니다. `method`는 계좌가 어떻게 인증되었는지를 나타내며, `none`은 어떠한 시도도 평가되기 전에 사용자가 은행 없이 계속 진행했음을 나타냅니다. `continued_without_bank`는 평가된 시도 이후를 포함하여 사용자가 은행 없이 계속 진행했음을 나타냅니다. [은행 인증 방법](/ko/core-technology/bank-verification/verification-methods) 및 [사용자가 은행을 인증할 수 없는 경우](/ko/core-technology/bank-verification/fallbacks)를 참고하세요.",
        "properties": {
          "schema_version": {
            "type": "integer",
            "description": "이 결과 형식의 버전입니다. 현재는 `1`입니다."
          },
          "bank_verification_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 결과의 ID입니다."
          },
          "node_id": {
            "type": "string",
            "description": "이 결과가 속한 워크플로 노드입니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Finished",
              "Approved",
              "Declined",
              "In Review",
              "Expired"
            ],
            "description": "작업 및 상태 규칙이 적용된 후의 단계 판정 결과입니다."
          },
          "original_status": {
            "type": "string",
            "nullable": true,
            "description": "수동 검토와 같은 후속 변경이 발생하기 전, 해당 단계에서 도달한 최초의 판정 결과입니다."
          },
          "method": {
            "type": "string",
            "nullable": true,
            "enum": [
              "open_banking",
              "account_lookup",
              "microdeposits",
              "statement",
              "none"
            ],
            "description": "계좌가 인증된 방식입니다. `open_banking`(은행 로그인: 사용자가 해당 은행에 로그인함), `account_lookup`(계좌 확인: 사용자가 계좌 정보를 입력하고 은행이 명의를 확인함), `microdeposits` 또는 `statement`(계좌 거래 내역서 업로드). 평가된 시도가 있기 전에 사용자가 은행 없이 계속 진행하여 인증된 계좌가 없는 경우에는 `none`입니다. 평가된 시도 후에는 해당 시도의 방법으로 유지됩니다. 계좌가 평가될 때까지 및 워크플로가 반환 데이터를 축소하는 경우에는 `null`입니다. 워크플로 규칙은 `bank.method`와 동일한 값을 읽습니다."
          },
          "provider": {
            "type": "string",
            "nullable": true,
            "description": "연결을 실행한 경로의 키입니다. 계정이 어떻게 인증되었는지 확인하려면 이 키가 아닌 `method`를 읽으십시오."
          },
          "credential_source": {
            "type": "string",
            "nullable": true,
            "enum": [
              "native",
              "byok"
            ],
            "description": "`native`: Didit의 자체 경로이며 Didit 잔액으로 청구됩니다. `byok`: 자체 자격 증명으로 연결한 마켓플레이스 제공업체입니다."
          },
          "route": {
            "type": "object",
            "nullable": true,
            "description": "동의 전에 선택된 경로입니다. 이후에는 절대 변경되지 않습니다.",
            "properties": {
              "provider_key": {
                "type": "string",
                "nullable": true,
                "description": "경로의 키입니다."
              },
              "credential_source": {
                "type": "string",
                "enum": [
                  "native",
                  "byok"
                ]
              },
              "is_fallback": {
                "type": "boolean",
                "description": "연결할 수 없는 마켓플레이스 제공업체를 대신하여 Didit 자체 경로가 사용되었는지 여부입니다."
              },
              "provider_connection_id": {
                "type": "string",
                "nullable": true,
                "description": "`byok`에 사용된 마켓플레이스 연동입니다."
              },
              "requested_scopes": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "연결에서 요청한 데이터입니다(예: `ownership` 또는 `balances`)."
              }
            }
          },
          "connection": {
            "type": "object",
            "nullable": true,
            "description": "가장 최근 시도의 연결입니다. 첫 번째 시도 전에는 `null`입니다.",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "pending",
                  "connected",
                  "cancelled",
                  "timeout",
                  "failed",
                  "unsupported",
                  "revoked",
                  "expired"
                ]
              },
              "institution_id": {
                "type": "string",
                "nullable": true,
                "description": "은행 ID입니다. 은행이 선택되지 않은 계좌 확인의 경우 `null`입니다."
              },
              "institution_name": {
                "type": "string",
                "nullable": true,
                "description": "은행 이름입니다. 계좌 확인의 경우 `null`입니다."
              },
              "institution_country": {
                "type": "string",
                "nullable": true,
                "description": "계정의 국가, ISO 3166-1 alpha-3입니다."
              },
              "oauth": {
                "type": "boolean",
                "nullable": true,
                "description": "은행 로그인이 OAuth 또는 앱 간(app-to-app) 방식으로 실행되었는지 여부입니다. 계좌 확인의 경우 `null`입니다."
              },
              "connected_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "연결에 성공한 시점입니다."
              },
              "consent_expires_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "은행 로그인의 경우 은행 동의가 종료되는 시점입니다."
              },
              "last_refreshed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "금융 데이터를 마지막으로 다시 읽은 시점입니다."
              },
              "attempts": {
                "type": "integer",
                "description": "해당 사용자가 이 단계에서 시도한 횟수로, 모든 방법의 합산입니다."
              },
              "reason_code": {
                "type": "string",
                "nullable": true,
                "description": "연결이 단순히 `connected` 상태가 아닌 이유(예: `USER_CANCELLED`, `INSTITUTION_DOWN`, `ACCOUNT_NOT_FOUND`, `REFERENCE_IDENTITY_MISSING` 또는 `VERIFICATION_COMPLETED`)."
              }
            }
          },
          "account": {
            "type": "object",
            "nullable": true,
            "description": "평가된 계정입니다. 계정이 평가될 때까지 `null`입니다.",
            "properties": {
              "account_id_masked": {
                "type": "string",
                "nullable": true,
                "description": "마스킹된 계좌번호입니다."
              },
              "iban_masked": {
                "type": "string",
                "nullable": true,
                "description": "마스킹 처리된 IBAN입니다."
              },
              "sort_code": {
                "type": "string",
                "nullable": true,
                "description": "영국의 소트 코드(Sort code)입니다."
              },
              "routing_number_masked": {
                "type": "string",
                "nullable": true,
                "description": "마스킹된 라우팅 번호입니다."
              },
              "type": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "checking",
                  "current",
                  "savings",
                  "business",
                  "other"
                ]
              },
              "subtype": {
                "type": "string",
                "nullable": true,
                "description": "은행 고유의 계좌 하위 유형입니다."
              },
              "currency": {
                "type": "string",
                "nullable": true,
                "description": "계정의 ISO 4217 통화입니다."
              },
              "holder_type": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "person",
                  "business",
                  "unknown"
                ]
              },
              "holders_count": {
                "type": "integer",
                "nullable": true
              },
              "is_joint": {
                "type": "boolean",
                "nullable": true
              },
              "is_business": {
                "type": "boolean",
                "nullable": true
              }
            }
          },
          "ownership": {
            "type": "object",
            "nullable": true,
            "description": "계좌 명의인과 인증된 신원 정보를 비교한 방식입니다. 계좌가 평가될 때까지는 `null`입니다.",
            "properties": {
              "result": {
                "type": "string",
                "enum": [
                  "match",
                  "partial_match",
                  "no_match",
                  "unknown",
                  "not_verifiable"
                ],
                "description": "`partial_match`는 유사 일치입니다. `not_verifiable`: 은행에서 비교할 명의자 정보 없이 응답했습니다. `unknown`: 증빙 자료를 읽을 수 없거나 비교할 신원 정보가 없습니다."
              },
              "reference_identity_source": {
                "type": "string",
                "nullable": true,
                "description": "소지자의 신원을 대조한 대상 단계입니다: `kyc`, `database_validation`, `expected_details`, `questionnaire`, `document_ai` 또는 `kyb`."
              },
              "name_score": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "nullable": true,
                "description": "Didit의 명의자 이름 점수입니다."
              },
              "provider_name_score": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "nullable": true,
                "description": "은행에서 반환한 경우, 은행 자체의 예금주명 점수입니다."
              },
              "address_score": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "nullable": true,
                "description": "주소 일치 확인이 실행된 경우의 명의인 주소 점수입니다."
              },
              "email_score": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "nullable": true,
                "description": "이메일 일치 확인이 실행된 경우의 명의인 이메일 점수입니다."
              },
              "phone_score": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "nullable": true,
                "description": "전화번호 일치 확인이 실행된 경우의 명의인 전화번호 점수입니다."
              },
              "dob_score": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "nullable": true,
                "description": "은행에서 제공한 경우의 명의인 생년월일 점수입니다."
              },
              "close_match": {
                "type": "boolean",
                "nullable": true,
                "description": "이름이 근접 일치 범위에 속했는지 여부입니다."
              },
              "holder_confirmation": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "pending",
                  "confirmed",
                  "rejected"
                ],
                "description": "유사 이름 확인 요청을 받았을 때 해당 인물이 응답한 내용입니다. 요청받은 적이 없으면 `null`입니다."
              },
              "method": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "exact",
                  "token_set",
                  "nickname",
                  "transliteration",
                  "fuzzy",
                  "provider_only",
                  "microdeposits"
                ],
                "description": "점수를 산출한 성명 비교 방식입니다. 이는 인증 방법이 아니며, 인증 방법은 최상위 `method`를 확인하십시오."
              },
              "matched_holder_index": {
                "type": "integer",
                "nullable": true
              },
              "holders": {
                "type": "array",
                "items": {
                  "type": "object"
                },
                "description": "은행이 나열한 각 명의자와 해당 점수입니다."
              },
              "owner_identity_available": {
                "type": "boolean",
                "nullable": true
              },
              "evidence_freshness": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "live",
                  "cached",
                  "refreshed"
                ]
              },
              "evaluated_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "판정이 계산된 시점입니다."
              }
            }
          },
          "financial_data": {
            "type": "object",
            "description": "단계에서 읽은 금융 데이터입니다. 은행 로그인 시에만 읽습니다.",
            "properties": {
              "balances": {
                "type": "object",
                "nullable": true,
                "description": "`balances` 스코프 포함 시."
              },
              "transactions": {
                "type": "object",
                "nullable": true,
                "description": "`transactions` 스코프 포함 시."
              },
              "income": {
                "type": "object",
                "nullable": true,
                "description": "`income` 스코프 포함 시."
              },
              "categorization": {
                "type": "object",
                "nullable": true,
                "description": "읽어온 거래에 대한 Didit의 분류입니다. 거래가 없으면 `null`입니다."
              },
              "not_collected": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "balances",
                    "income",
                    "transactions"
                  ]
                },
                "description": "단계에서 요청했으나 계좌를 인증한 방식에서 수집하지 않는 데이터입니다. 잔액, 거래 및 수입은 은행 로그인을 통해서만 제공되므로 계좌 확인으로 인증된 계좌는 해당 항목을 여기에 나열합니다. 실패로 간주되지 않으며, 그렇지 않은 경우 비어 있습니다."
              }
            }
          },
          "billing": {
            "type": "object",
            "nullable": true,
            "properties": {
              "route": {
                "type": "string",
                "enum": [
                  "native",
                  "byok"
                ]
              },
              "billed": {
                "type": "boolean"
              },
              "marketplace_fee": {
                "type": "string",
                "nullable": true,
                "description": "`byok`에 청구된 마켓플레이스 플랫폼 수수료입니다."
              },
              "usage_type": {
                "type": "string",
                "nullable": true,
                "description": "요금이 청구된 사용 항목입니다. 은행 로그인 또는 계좌 확인의 경우 `bank_verification`, 이전에 청구된 은행 시도가 없는 명세서 업로드의 경우 `bank_statement_upload`, 자체 공급자에 대한 마켓플레이스 수수료의 경우 `bank_byok_fee`입니다. 청구된 내역이 없으면 `null`입니다."
              }
            }
          },
          "reference_identity": {
            "type": "object",
            "nullable": true,
            "description": "명의인과 비교 대상이 된 신원 및 해당 출처입니다."
          },
          "signals": {
            "type": "object",
            "nullable": true,
            "description": "단계에서 거래 내역을 읽었을 때 거래 내역에서 읽어온 계정 신호입니다."
          },
          "connection_abandoned": {
            "type": "boolean",
            "nullable": true,
            "description": "인물이 은행 단계에서 이탈한 후 일치 항목 없이 단계가 종료되었는지 여부입니다."
          },
          "not_covered": {
            "type": "boolean",
            "nullable": true,
            "description": "해당 단계에서 인물의 은행 또는 국가에 연결할 수 없었는지 여부입니다. 국가 또는 은행을 확인할 수 있는 방식이 없어 인물이 은행 없이 계속 진행한 경우에도 `true`가 됩니다."
          },
          "continued_without_bank": {
            "type": "boolean",
            "description": "해당 인물이 **Continue without your bank**를 선택하여 단계를 벗어났는지 여부입니다. 이 경우 `continuation`에 이유가 표시됩니다. 계속 진행하기 전에 평가된 시도가 없었던 경우 `method`는 `none`입니다. 명의자 불일치와 같이 평가된 시도가 있은 후에는 `method`가 해당 시도의 방식으로 유지되며 판정 및 사유 코드가 유지됩니다. 워크플로가 반환하는 데이터를 좁히는 경우에도 반환됩니다."
          },
          "continuation": {
            "type": "object",
            "nullable": true,
            "description": "사용자가 은행 없이 계속 진행한 방식입니다. 그렇지 않은 경우에는 `null`입니다. 워크플로가 반환 데이터를 축소하는 경우에도 `reason`은 계속 반환되며 다른 모든 키는 `null`입니다.",
            "properties": {
              "reason": {
                "type": "string",
                "enum": [
                  "no_route",
                  "institution_unsupported",
                  "attempts_exhausted",
                  "person_choice"
                ],
                "description": "사용자가 진행할 때 Didit이 파악한 이유입니다: `no_route`(해당 국가를 지원하는 은행 로그인 또는 계좌 확인 수단이 없음), `institution_unsupported`(선택한 은행을 이 단계에서 사용할 수 없음), `attempts_exhausted`(모든 시도를 이미 소진했으며 진행 중인 시도가 없음), 또는 `person_choice`(확인 방법이 있었으나 사용자가 진행하기로 선택함, 은행에 지금 연결할 수 없는 경우도 포함). 평가된 시도로 단계가 이미 결정되지 않은 한, `no_route` 및 `institution_unsupported`는 `bank_unsupported_action`을 따르고, `attempts_exhausted`는 `bank_attempts_exhausted_action`을 따르며, `person_choice`는 `bank_skipped_action`을 따릅니다."
              },
              "country": {
                "type": "string",
                "nullable": true,
                "description": "사용자가 인증을 진행하던 국가(ISO 3166-1 alpha-3)입니다. 국가를 선택하기 전에 계속 진행한 경우 `null`입니다."
              },
              "offered": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "statement",
                    "microdeposits"
                  ]
                },
                "nullable": true,
                "description": "사용자가 계속 진행할 때 해당 국가에서 사용자에게 제공한 다른 인증 방법 목록으로, 제공된 순서대로 `statement`(거래내역서 업로드), `microdeposits`입니다. 제공된 방법이 없으면 비어 있습니다."
              },
              "institution_id": {
                "type": "string",
                "nullable": true,
                "description": "`institution_unsupported`의 경우 사용자가 이용할 수 없었던 은행의 ID: 사용자가 선택한 은행 또는 마지막 시도가 종료된 은행입니다. Didit은 사용자의 기기가 아닌 자체 은행 목록에서 이를 가져오므로 해당 목록에 없는 은행은 `null`입니다. 다른 모든 사유의 경우 `null`입니다."
              },
              "institution_name": {
                "type": "string",
                "nullable": true,
                "description": "`institution_unsupported`의 경우 해당 은행의 이름이며, `institution_id`와 동일한 목록에서 가져옵니다. 해당 목록에 은행이 없거나 다른 모든 사유의 경우 `null`입니다."
              },
              "continued_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "사용자가 진행한 시점입니다."
              }
            }
          },
          "evidence_purged_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "`bank_evidence_retention_days`에 따라 은행 증빙이 삭제된 시점입니다. 그렇지 않은 경우 `null`입니다."
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "정보 제공 코드(예: `holder_declared`)입니다. 경고 자체만으로는 상태가 변경되지 않습니다."
          },
          "reason_codes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "판정 결과가 그렇게 나온 이유(예: `OWNER_NAME_PARTIAL`)입니다. 여러 개가 적용될 수 있습니다. `NOT_COVERED`: 해당 국가 또는 은행을 확인할 수 있는 방법이 없어 은행 없이 진행함. `SKIPPED`: 확인 방법이 있었으나 사용자가 은행 없이 진행하기로 선택함. 평가된 시도로 단계가 이미 결정된 경우에는 둘 다 추가되지 않습니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BankAccountCheckPersonHolder": {
        "type": "object",
        "description": "계정을 보유해야 하는 인물입니다.",
        "required": [
          "full_name"
        ],
        "properties": {
          "full_name": {
            "type": "string",
            "maxLength": 255,
            "description": "계정 소유자여야 하는 사람의 성명입니다.",
            "example": "Maria Oliveira"
          }
        }
      },
      "BankAccountCheckBusinessHolder": {
        "type": "object",
        "description": "계좌를 보유해야 하는 기업입니다. 기업 계좌를 확인합니다.",
        "required": [
          "business_name"
        ],
        "properties": {
          "business_name": {
            "type": "string",
            "maxLength": 255,
            "description": "계좌를 보유해야 하는 회사의 이름입니다. 기업 계좌를 확인합니다."
          }
        }
      },
      "BankVerificationPricing": {
        "type": "object",
        "description": "Public Bank Verification 정가: 거래내역서 업로드, 자체 제공자 키 수수료 및 각 국가별 방식입니다.",
        "required": [
          "currency",
          "statement_upload",
          "own_provider_fee_usd",
          "countries"
        ],
        "properties": {
          "currency": {
            "type": "string",
            "enum": [
              "USD"
            ],
            "description": "응답에 포함된 모든 가격의 통화입니다.",
            "example": "USD"
          },
          "statement_upload": {
            "$ref": "#/components/schemas/BankStatementUploadPricing"
          },
          "own_provider_fee_usd": {
            "type": "string",
            "description": "Didit 대신 자체 제공업체 계약을 사용하는 경로에서 청구 가능한 각 소유 구조 확인에 대한 수수료로, 결과에 관계없이 부과됩니다. 취소되거나 시간 초과되거나 중단된 연결에는 요금이 부과되지 않습니다. 소수점 4자리의 USD 10진수 문자열입니다.",
            "example": "0.0200"
          },
          "countries": {
            "type": "object",
            "description": "ISO 3166-1 alpha-3 코드를 키로 하는 모든 국가입니다.",
            "additionalProperties": {
              "$ref": "#/components/schemas/BankVerificationPricingCountry"
            }
          }
        }
      },
      "BankStatementUploadPricing": {
        "type": "object",
        "description": "은행 계좌 거래 내역서 업로드에 대한 가격 책정 방식입니다.",
        "required": [
          "price_usd",
          "included_after_charged_bank_attempt",
          "standalone_available"
        ],
        "properties": {
          "price_usd": {
            "type": "string",
            "description": "과금된 은행 시도 후 명세서 업로드 가격입니다. 소수점 이하 4자리의 십진수 문자열(USD)입니다.",
            "example": "0.0000"
          },
          "included_after_charged_bank_attempt": {
            "type": "boolean",
            "description": "동일한 세션에서 과금된 은행 시도 후 추가 요금 없이 업로드가 포함된 경우 `true`입니다.",
            "example": true
          },
          "standalone_available": {
            "type": "boolean",
            "description": "은행 시도 없이 명세서 업로드만 독립적으로 실행할 수 있는 경우 `true`입니다. 프로덕션 환경에서는 `false`이며, 샌드박스 세션에서는 결제 없이 테스트할 수 있습니다.",
            "example": false
          }
        }
      },
      "BankVerificationPricingCountry": {
        "type": "object",
        "description": "특정 국가의 은행 확인 방법 및 정가 목록입니다.",
        "required": [
          "name",
          "methods"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "영어 국가명.",
            "example": "United Kingdom"
          },
          "methods": {
            "$ref": "#/components/schemas/BankVerificationPricingMethods"
          }
        }
      },
      "BankVerificationPricingMethods": {
        "type": "object",
        "description": "해당 국가에서 지원되는 두 가지 은행 인증 방식입니다.",
        "required": [
          "open_banking",
          "account_lookup"
        ],
        "properties": {
          "open_banking": {
            "$ref": "#/components/schemas/BankSignInPricing"
          },
          "account_lookup": {
            "$ref": "#/components/schemas/BankAccountCheckPricing"
          }
        }
      },
      "BankSignInPricing": {
        "type": "object",
        "description": "은행 로그인: 사용자가 자신의 은행에 로그인합니다. 시장별로 가격이 책정되며, 해당 시장 내 모든 은행에 동일하게 적용됩니다.",
        "required": [
          "available",
          "market",
          "price_usd",
          "add_ons"
        ],
        "properties": {
          "available": {
            "type": "boolean",
            "description": "프로덕션 환경에서 Didit이 해당 국가의 은행 로그인을 지원하는 경우에만 `true`입니다.",
            "example": true
          },
          "market": {
            "type": "string",
            "nullable": true,
            "description": "가격이 적용되는 시장입니다. 사용할 수 없는 경우 `null`입니다.",
            "example": "UK and EEA"
          },
          "price_usd": {
            "type": "string",
            "nullable": true,
            "description": "은행 로그인 1건당 가격입니다. 이용할 수 없는 경우 `null`입니다. USD 기준 소수점 4자리의 소수 문자열입니다.",
            "example": "0.7900"
          },
          "add_ons": {
            "type": "object",
            "description": "해당 국가에서 가격이 책정된 부가 기능으로, 은행 로그인 가격에 추가되는 USD 기준 소수점 4자리 십진수 문자열입니다. 해당 국가에서 제공하는 부가 기능만 나열되며, 은행 로그인을 사용할 수 없는 경우 비어 있습니다.",
            "properties": {
              "balance": {
                "type": "string",
                "description": "계좌 잔액 추가 기능.",
                "example": "0.3500"
              },
              "transactions": {
                "type": "string",
                "description": "거래 애드온입니다.",
                "example": "1.3000"
              }
            }
          }
        }
      },
      "BankAccountCheckPricing": {
        "type": "object",
        "description": "계좌 확인: 사용자가 계좌 번호를 입력하면 Didit이 은행을 통해 확인합니다. 국가별로 가격이 책정됩니다.",
        "required": [
          "available",
          "price_usd"
        ],
        "properties": {
          "available": {
            "type": "boolean",
            "description": "프로덕션 환경에서 Didit이 해당 국가의 계좌 확인을 지원하는 경우에만 `true`입니다.",
            "example": true
          },
          "price_usd": {
            "type": "string",
            "nullable": true,
            "description": "은행이 응답한 계좌 확인 건당 가격입니다. 이용할 수 없는 경우 `null`입니다. USD 기준 소수점 4자리의 소수 문자열입니다.",
            "example": "0.4000"
          }
        }
      },
      "ImportProvider": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "enum": [
              "sumsub",
              "jumio",
              "veriff",
              "onfido",
              "persona",
              "metamap",
              "socure",
              "idnow",
              "shufti",
              "idenfy",
              "ondato",
              "trulioo",
              "au10tix",
              "complycube",
              "other"
            ]
          },
          "name": {
            "type": "string"
          },
          "mode": {
            "type": "string",
            "enum": [
              "api_list",
              "api_ids",
              "export_file"
            ],
            "description": "`api_list`: Didit이 키를 사용하여 레코드를 나열합니다. `api_ids`: 내보내기에서 레코드 ID를 업로드합니다. `export_file`: Didit 형식의 내보내기 파일을 업로드합니다."
          },
          "record_noun": {
            "type": "string"
          },
          "credential_fields": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "secret": {
                  "type": "boolean"
                }
              }
            }
          },
          "regions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "required_permissions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "docs_url": {
            "type": "string",
            "nullable": true
          },
          "status_mapping": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "enum": [
                "Approved",
                "Declined",
                "In Review",
                "Expired",
                "Not Finished",
                "Abandoned"
              ]
            }
          }
        }
      },
      "ImportJobSummary": {
        "type": "object",
        "description": "모든 유형의 가져오기 작업 1개이며 콘솔의 가져오기 작업 드로어에서 읽는 형식입니다.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "enum": [
              "sessions",
              "businesses",
              "users",
              "status_rules",
              "transactions"
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "file",
              "api",
              "provider"
            ]
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "provider_name": {
            "type": "string",
            "nullable": true
          },
          "filename": {
            "type": "string",
            "nullable": true
          },
          "state": {
            "type": "string",
            "enum": [
              "ready",
              "queued",
              "running",
              "paused",
              "completed",
              "errors",
              "failed",
              "cancelled"
            ],
            "description": "콘솔에 표시되는 작업 상태입니다. `errors`는 거부된 행이 포함된 완료된 작업입니다."
          },
          "status": {
            "type": "string"
          },
          "is_dry_run": {
            "type": "boolean"
          },
          "credential_hint": {
            "type": "string",
            "nullable": true
          },
          "resumes_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_error": {
            "type": "string",
            "nullable": true
          },
          "started_by": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "nullable": true
              },
              "email": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "progress": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer",
                "format": "int64"
              },
              "processed": {
                "type": "integer",
                "format": "int64"
              },
              "imported": {
                "type": "integer",
                "format": "int64"
              },
              "updated": {
                "type": "integer",
                "format": "int64"
              },
              "already_in_didit": {
                "type": "integer",
                "format": "int64"
              },
              "failed": {
                "type": "integer",
                "format": "int64"
              },
              "not_finished": {
                "type": "integer",
                "format": "int64"
              },
              "same_person": {
                "type": "integer",
                "format": "int64"
              }
            }
          },
          "face_templates": {
            "type": "object",
            "nullable": true,
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "built": {
                "type": "integer",
                "format": "int64"
              },
              "duplicates": {
                "type": "integer",
                "format": "int64"
              },
              "blocklisted": {
                "type": "integer",
                "format": "int64"
              }
            }
          },
          "eta_seconds": {
            "type": "integer",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "FiledRegulatoryReport": {
        "type": "object",
        "description": "요청된 삭제를 방지하는 완료된 규제 보고서입니다.",
        "required": [
          "uuid",
          "report_number",
          "report_type",
          "case_uuid"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "보고서 UUID입니다."
          },
          "report_number": {
            "type": "string",
            "description": "콘솔에 표시되는 보고서 번호(예: SAR-0001)입니다."
          },
          "report_type": {
            "type": "string",
            "enum": [
              "SAR",
              "STR",
              "CTR",
              "TTR",
              "UTR",
              "IFT",
              "CBR",
              "TFR"
            ],
            "description": "규제 보고서 유형입니다."
          },
          "case_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "보고서가 속한 케이스."
          }
        }
      },
      "FiledReportTransaction": {
        "type": "object",
        "description": "확정된 규제 보고서에 나열되어 있어 삭제할 수 없는 거래입니다.",
        "required": [
          "uuid",
          "transaction_id",
          "reports"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Didit 거래 UUID입니다."
          },
          "transaction_id": {
            "type": "string",
            "description": "거래 생성 시 제공된 거래 식별자입니다."
          },
          "reports": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FiledRegulatoryReport"
            },
            "description": "이 거래가 포함된 확정된 보고서입니다."
          }
        }
      },
      "InFiledReportError": {
        "type": "object",
        "description": "선택한 데이터가 확정된 규제 보고서에 포함되어 있어 삭제가 거부되었습니다. 아무것도 삭제되지 않았습니다. 보고서를 삭제한 후 요청을 반복하십시오.",
        "required": [
          "detail",
          "code"
        ],
        "properties": {
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "enum": [
              "in_filed_report"
            ],
            "description": "확정된 규제 보고서로 인해 삭제가 차단된 경우에 대한 안정적인 오류 코드입니다."
          },
          "reports": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FiledRegulatoryReport"
            },
            "description": "개인, 기업, 케이스 또는 세션 삭제를 차단하는 보고서 목록입니다."
          },
          "transactions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FiledReportTransaction"
            },
            "description": "거래 삭제를 차단하는 거래 및 이를 나열하는 각 보고서입니다."
          }
        }
      },
      "SubjectDeletionInProgressError": {
        "type": "object",
        "description": "다른 요청이 아직 이 개인 또는 기업을 삭제하는 중입니다. 이 요청은 아무것도 삭제하지 않았으며 해당 삭제가 완료된 후 재시도할 수 있습니다. 재시도 시 여전히 선택되어 있는 항목이 삭제됩니다.",
        "required": [
          "detail",
          "code"
        ],
        "properties": {
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "enum": [
              "subject_deletion_in_progress"
            ],
            "description": "다른 요청에서 아직 삭제 중인 개인 또는 기업에 대한 안정적인 오류 코드입니다."
          }
        }
      },
      "TravelRuleNetworkParticipantSummary": {
        "type": "object",
        "nullable": true,
        "description": "네트워크에 속한 이 애플리케이션 자체의 참여자이며, 없는 경우 null입니다.",
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "platform",
              "own"
            ],
            "description": "platform: Didit의 멤버십을 통해 지원됨; own: 애플리케이션의 자체 멤버십으로 온보딩됨."
          },
          "status": {
            "type": "string",
            "enum": [
              "not_requested",
              "questionnaire_pending",
              "submitted_to_network",
              "active",
              "suspended",
              "rejected"
            ],
            "description": "not_requested: 요청된 적이 없거나 네트워크가 첫 번째 요청을 거부함(last_error 참조); questionnaire_pending: 고객 실사 설문지 승인 대기 중; submitted_to_network: 네트워크 온보딩으로 전달됨; active: 네트워크가 이 애플리케이션에 고유 참여자 코드를 부여함; suspended / rejected: Didit이 일시 중단하거나 거부함."
          },
          "participant_code": {
            "type": "string",
            "description": "네트워크가 이 애플리케이션에 부여한 코드입니다(GTR의 경우 VASP 코드). 아웃바운드 메시지에는 Didit의 자체 코드가 아닌 이 코드가 포함됩니다."
          },
          "requested_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "activated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_error": {
            "type": "string",
            "description": "등록을 거부했을 때 네트워크의 응답이며, 그렇지 않은 경우 비어 있습니다."
          }
        }
      },
      "TravelRuleNetworkState": {
        "type": "object",
        "description": "이 애플리케이션에 대해 특정 네트워크의 Travel Rule 메시지가 전송되는 방식 및 전송할 수 없는 이유입니다. 실시간 상태 또는 전송 확인이 아닌 구성 상태입니다.",
        "properties": {
          "rail": {
            "type": "string",
            "enum": [
              "GTR",
              "TRUST",
              "VERIFYVASP",
              "SYGNA"
            ]
          },
          "mode": {
            "type": "string",
            "enum": [
              "own",
              "didit",
              "off",
              "unavailable"
            ],
            "description": "own: 애플리케이션의 연결된 멤버십이 사용됨; didit: Didit의 멤버십이 애플리케이션을 자체 활성 참여자로 지원함; off: 자체 멤버십이 없는 상태에서 disabled_networks를 통해 플랫폼 라우팅이 비활성화됨; unavailable: 아직 이 네트워크에서 전송할 수 있는 것이 없음(state 및 reason 참조)."
          },
          "state": {
            "type": "string",
            "enum": [
              "own_membership",
              "live_through_didit",
              "off",
              "didit_onboarding",
              "questionnaire_needed",
              "questionnaire_in_review",
              "request_access",
              "request_sent",
              "unavailable",
              "error"
            ],
            "description": "own_membership: 연결된 자체 멤버십으로 전송; live_through_didit: Didit 멤버십 내 고유 참여자로 전송; off: 플랫폼 라우팅을 비활성화함; didit_onboarding: 이 네트워크에 대한 Didit의 자체 멤버십이 아직 활성화되지 않아 다른 참여자를 지원할 수 없음; questionnaire_needed / questionnaire_in_review: 고객 실사 설문지를 제출해야 하거나 Didit에서 검토 중임; request_access: 설문지가 승인되었으며 네트워크에 요청 가능; request_sent: 참여자 온보딩 진행 중; unavailable: reason 참조; error: reason 참조."
          },
          "reason": {
            "type": "string",
            "enum": [
              "own_membership_connected",
              "platform_network_switched_off",
              "own_membership_only",
              "sandbox_application",
              "didit_membership_not_live",
              "participant_suspended",
              "participant_rejected",
              "questionnaire_not_submitted",
              "questionnaire_submitted",
              "questionnaire_changes_requested",
              "questionnaire_rejected",
              "participant_not_requested",
              "participant_active",
              "participant_key_missing",
              "participant_key_unresolved",
              "provisioning_failed",
              "questionnaire_pending",
              "submitted_to_network"
            ],
            "description": "상태의 기계 판독 가능한 세부 정보. own_membership_only: Didit은 이 네트워크(TRUST)에서 애플리케이션을 지원하지 않으므로 자체 멤버십을 연결해야 함; sandbox_application: 샌드박스 전송은 네트워크에 도달하지 않음; provisioning_failed: 네트워크에서 등록을 거부함, 참가자의 last_error에 원인이 명시되어 있으며 네트워크를 다시 요청하면 재시도됨."
          },
          "platform_available": {
            "type": "boolean",
            "description": "이 네트워크에 대한 Didit 자체 멤버십이 구성되어 있는지 여부입니다. 실시간 상태 확인은 아닙니다."
          },
          "connected": {
            "type": "boolean",
            "description": "연결된 고객 멤버십이 존재하는지 여부입니다. 자격 증명은 로컬에서 검증되며, 네트워크 검증은 실시간 교환 중에 수행됩니다."
          },
          "participant": {
            "$ref": "#/components/schemas/TravelRuleNetworkParticipantSummary"
          },
          "vasps_reachable": {
            "type": "integer",
            "description": "이 네트워크에서 접근 가능한 디렉터리 VASP입니다."
          },
          "routed_30d": {
            "type": "integer",
            "description": "지난 30일 동안 이 네트워크에서 진행된 이 애플리케이션의 전송 건수입니다."
          }
        }
      },
      "TravelRuleNetworkQuestionnaireAnswers": {
        "type": "object",
        "description": "Didit의 네트워크 실사 설문지입니다. 저장은 부분적으로 수행됩니다. 즉, 저장 시 명시되지 않은 모든 답변이 유지됩니다. 제출하려면 lei 및 data_protection_contact_email을 제외한 모든 필드가 필요하며 세 가지 증명 필드가 모두 true여야 합니다.",
        "properties": {
          "legal_name": {
            "type": "string",
            "maxLength": 255
          },
          "registration_number": {
            "type": "string",
            "maxLength": 255
          },
          "incorporation_country": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2,
            "description": "ISO 3166-1 alpha-2 국가 코드입니다."
          },
          "registered_address": {
            "type": "string",
            "maxLength": 1000
          },
          "website": {
            "type": "string",
            "format": "uri",
            "maxLength": 500
          },
          "lei": {
            "type": "string",
            "maxLength": 20,
            "description": "선택 사항입니다. 제공되는 경우 유효한 ISO 17442 LEI입니다."
          },
          "licences": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "required": [
                "regulator",
                "jurisdiction",
                "licence_type",
                "licence_number"
              ],
              "properties": {
                "regulator": {
                  "type": "string",
                  "maxLength": 255
                },
                "jurisdiction": {
                  "type": "string",
                  "minLength": 2,
                  "maxLength": 2,
                  "description": "ISO 3166-1 alpha-2 국가 코드입니다."
                },
                "licence_type": {
                  "type": "string",
                  "maxLength": 255
                },
                "licence_number": {
                  "type": "string",
                  "maxLength": 255
                }
              }
            },
            "description": "VASP가 보유한 모든 라이선스 또는 등록 내역입니다."
          },
          "operating_jurisdictions": {
            "type": "array",
            "minItems": 1,
            "maxItems": 250,
            "items": {
              "type": "string",
              "minLength": 2,
              "maxLength": 2,
              "description": "ISO 3166-1 alpha-2 국가 코드입니다."
            }
          },
          "compliance_officer_name": {
            "type": "string",
            "maxLength": 255
          },
          "compliance_officer_email": {
            "type": "string",
            "format": "email"
          },
          "aml_ctf_policy_attested": {
            "type": "boolean",
            "description": "제출하려면 true여야 합니다."
          },
          "sanctions_screening_attested": {
            "type": "boolean",
            "description": "제출하려면 true여야 합니다."
          },
          "data_protection_attested": {
            "type": "boolean",
            "description": "제출하려면 true여야 합니다."
          },
          "data_protection_contact_email": {
            "type": "string",
            "format": "email",
            "description": "선택 사항입니다."
          },
          "expected_monthly_transfers": {
            "type": "integer",
            "minimum": 0
          },
          "expected_monthly_volume_usd": {
            "type": "string",
            "format": "decimal",
            "description": "USD 기준 예상 월간 거래량(소수점 이하 최대 2자리)입니다. 문자열로 반환됩니다."
          },
          "assets": {
            "type": "array",
            "minItems": 1,
            "maxItems": 200,
            "items": {
              "type": "string",
              "maxLength": 32
            },
            "description": "대문자로 저장되고 정렬 및 중복 제거된 자산 티커입니다."
          }
        }
      },
      "TravelRuleNetworkQuestionnaire": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "submitted",
              "changes_requested",
              "approved",
              "rejected"
            ],
            "description": "답변은 draft 또는 changes_requested 상태일 때 저장할 수 있습니다. submitted, approved, rejected는 Didit이 변경하는 상태입니다."
          },
          "answers": {
            "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaireAnswers"
          },
          "submitted_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "reviewed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "review_note": {
            "type": "string",
            "description": "변경할 사항 등 Didit의 최근 결정에 대한 메모입니다."
          },
          "history": {
            "type": "array",
            "readOnly": true,
            "description": "모든 상태 변경 내역(오래된 순)입니다.",
            "items": {
              "type": "object",
              "properties": {
                "at": {
                  "type": "string",
                  "format": "date-time"
                },
                "from": {
                  "type": "string"
                },
                "to": {
                  "type": "string"
                },
                "note": {
                  "type": "string",
                  "description": "검토 메모 또는 네트워크 응답(있는 경우)."
                }
              }
            }
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "TravelRuleNetworkParticipant": {
        "type": "object",
        "description": "하나의 네트워크에 속한 이 애플리케이션 자체의 참여자입니다.",
        "properties": {
          "network": {
            "type": "string",
            "enum": [
              "gtr",
              "trust",
              "verifyvasp",
              "sygna"
            ]
          },
          "rail": {
            "type": "string",
            "enum": [
              "GTR",
              "TRUST",
              "VERIFYVASP",
              "SYGNA"
            ]
          },
          "mode": {
            "type": "string",
            "enum": [
              "platform",
              "own"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "not_requested",
              "questionnaire_pending",
              "submitted_to_network",
              "active",
              "suspended",
              "rejected"
            ],
            "description": "not_requested: 요청된 적이 없거나 네트워크가 첫 번째 요청을 거부함(last_error 참조); questionnaire_pending: 고객 실사 설문지 승인 대기 중; submitted_to_network: 네트워크 온보딩으로 전달됨; active: 네트워크가 이 애플리케이션에 고유 참여자 코드를 부여함; suspended / rejected: Didit이 일시 중단하거나 거부함."
          },
          "participant_code": {
            "type": "string"
          },
          "requested_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "submitted_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "activated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "suspended_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_error": {
            "type": "string",
            "description": "등록을 거부했을 때 네트워크의 응답이며, 그렇지 않은 경우 비어 있습니다."
          },
          "history": {
            "type": "array",
            "readOnly": true,
            "description": "모든 상태 변경 내역(오래된 순)입니다.",
            "items": {
              "type": "object",
              "properties": {
                "at": {
                  "type": "string",
                  "format": "date-time"
                },
                "from": {
                  "type": "string"
                },
                "to": {
                  "type": "string"
                },
                "note": {
                  "type": "string",
                  "description": "검토 메모 또는 네트워크 응답(있는 경우)."
                }
              }
            }
          }
        }
      },
      "TravelRuleNetworksOverview": {
        "type": "object",
        "properties": {
          "platform_networks_enabled": {
            "type": "boolean",
            "description": "Didit 멤버십을 통한 네트워크 접근이 열려 있는지 여부입니다. false인 동안 설문지 저장, 제출 및 네트워크 요청에 403 응답이 반환됩니다."
          },
          "questionnaire": {
            "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaire"
          },
          "participants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TravelRuleNetworkParticipant"
            }
          },
          "networks": {
            "type": "object",
            "readOnly": true,
            "description": "네트워크별로 이 애플리케이션이 전송하는 방식과 전송할 수 없는 이유를 나타냅니다. GTR을 포함한 어떤 네트워크도 기본으로 포함되지 않습니다. 네트워크는 연결된 자체 멤버십을 통해 도달하거나, 해당 네트워크에 대한 Didit의 멤버십이 활성화되고 자체 참가자가 활성 상태가 되면 Didit 멤버십을 통해 도달할 수 있습니다. 실시간 상태 또는 전송 확인 검사가 아닙니다.",
            "properties": {
              "gtr": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              },
              "trust": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              },
              "verifyvasp": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              },
              "sygna": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              }
            }
          }
        }
      },
      "AddressValidationResult": {
        "type": "object",
        "description": "단일 Address Validation 결과입니다. 주소의 존재 여부 및 정규화된 형태를 나타냅니다. 주소만 확인하며, 결코 주소를 개인과 연결하지 않습니다.",
        "required": [
          "status",
          "verification_level",
          "address",
          "formatted_address",
          "latitude",
          "longitude"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "verified",
              "partially_verified",
              "not_verified",
              "unavailable"
            ],
            "description": "`verified`: 주소가 건물(또는 호수, 사서함) 단위까지 확인되었습니다. `partially_verified`: 도로명 단위까지 또는 해당 지역에 대해 우편 참조 데이터가 보유한 가장 정밀한 수준까지만 확인되었습니다. `not_verified`: 지역 또는 도시만 일치했거나 아무것도 일치하지 않았습니다. `unavailable`: 검증을 실행할 수 없었습니다(예: 참조 서비스가 응답하지 않음). 비용이 청구되지 않으며 인증에 영향을 주지 않습니다."
          },
          "verification_level": {
            "type": "string",
            "nullable": true,
            "enum": [
              "administrative_area",
              "locality",
              "thoroughfare",
              "premise",
              "delivery_point",
              null
            ],
            "description": "주소가 일치한 가장 정밀한 수준입니다. 일치하는 항목이 없거나 `status`가 `unavailable`인 경우 `null`입니다."
          },
          "address": {
            "type": "object",
            "nullable": true,
            "description": "정규화된 주소입니다. `status`가 `unavailable`인 경우 `null`입니다.",
            "properties": {
              "address_line_1": {
                "type": "string",
                "nullable": true,
                "description": "해당 국가의 표기 방식에 따른 첫 번째 주소 라인입니다.",
                "example": "1600 Amphitheatre Pkwy"
              },
              "address_line_2": {
                "type": "string",
                "nullable": true,
                "description": "주소에 있는 경우 두 번째 배송 주소 라인(아파트, 건물 또는 주변 지역)."
              },
              "city": {
                "type": "string",
                "nullable": true,
                "example": "Mountain View"
              },
              "region": {
                "type": "string",
                "nullable": true,
                "description": "주, 도 또는 지역입니다.",
                "example": "CA"
              },
              "postal_code": {
                "type": "string",
                "nullable": true,
                "example": "94043-1351"
              },
              "country": {
                "type": "string",
                "nullable": true,
                "description": "ISO 3166-1 alpha-2 국가 코드입니다.",
                "example": "US"
              }
            }
          },
          "formatted_address": {
            "type": "string",
            "nullable": true,
            "description": "한 줄로 정규화된 주소입니다.",
            "example": "1600 Amphitheatre Pkwy, Mountain View CA 94043-1351"
          },
          "latitude": {
            "type": "number",
            "nullable": true,
            "example": 37.422022
          },
          "longitude": {
            "type": "number",
            "nullable": true,
            "example": -122.08429
          }
        }
      },
      "AddressValidationRequest": {
        "type": "object",
        "required": [
          "country"
        ],
        "description": "주소 1개입니다. 한 줄(`address`)로 입력하거나 최소 `address_line_1`을 포함하는 구조화된 필드로 입력할 수 있으며, 두 방식을 동시에 사용할 수는 없습니다.",
        "properties": {
          "address": {
            "type": "string",
            "maxLength": 500,
            "description": "한 줄로 작성된 전체 주소입니다.",
            "example": "Paseo de la Castellana 259, 28046 Madrid"
          },
          "address_line_1": {
            "type": "string",
            "maxLength": 255,
            "description": "도로명 및 번호.",
            "example": "1600 Amphitheatre Pkwy"
          },
          "address_line_2": {
            "type": "string",
            "maxLength": 255,
            "description": "아파트, 호수, 층 또는 건물입니다."
          },
          "city": {
            "type": "string",
            "maxLength": 128,
            "description": "시 또는 지역입니다.",
            "example": "Mountain View"
          },
          "region": {
            "type": "string",
            "maxLength": 128,
            "description": "주, 도 또는 지역입니다.",
            "example": "CA"
          },
          "postal_code": {
            "type": "string",
            "maxLength": 32,
            "example": "94043"
          },
          "country": {
            "type": "string",
            "maxLength": 3,
            "description": "주소 국가의 ISO 3166-1 alpha-2 또는 alpha-3 코드입니다.",
            "example": "US"
          }
        }
      },
      "AddressValidationResponse": {
        "type": "object",
        "required": [
          "request_id",
          "address_validation",
          "created_at"
        ],
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "이 요청의 식별자입니다. 지원팀에 문의할 때 언급하십시오. 세션은 생성되지 않습니다."
          },
          "address_validation": {
            "$ref": "#/components/schemas/AddressValidationResult"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TravelRuleWalletProofFailureReason": {
        "type": "string",
        "enum": [
          "",
          "SIGNATURE_INVALID",
          "SIGNATURE_UNSUPPORTED_SCHEME",
          "DEPOSIT_NOT_FOUND",
          "DEPOSIT_UNCONFIRMED",
          "DEPOSIT_LOOKUP_FAILED",
          "DEPOSIT_MISMATCH",
          "DEPOSIT_STALE",
          "TXID_REUSED",
          "CHAIN_UNSUPPORTED",
          "WINDOW_EXPIRED",
          "OWNERSHIP_CHANGED",
          "METHOD_SWITCHED",
          "REVIEW_REJECTED",
          "ABANDONED"
        ],
        "description": "지갑 소유권 증명 또는 마지막 시도가 VERIFIED에 도달하지 못한 이유입니다. 실패한 항목이 없으면 비어 있습니다. PENDING 증명에도 포함될 수 있습니다. 즉 마지막 시도가 실패했으며 최종 사용자가 다시 시도할 수 있습니다. DEPOSIT_MISMATCH, DEPOSIT_STALE, TXID_REUSED 및 REVIEW_REJECTED는 증명을 REJECTED 상태로 종료합니다. SIGNATURE_INVALID: 서명이 지갑 및 챌린지와 일치하지 않습니다. SIGNATURE_UNSUPPORTED_SCHEME: 지갑이 Didit에서 검증하지 않는 형식으로 서명했습니다. DEPOSIT_NOT_FOUND, DEPOSIT_UNCONFIRMED, DEPOSIT_LOOKUP_FAILED: 테스트 입금을 읽을 수 없거나 아직 확인되지 않았습니다. Didit은 테스트 기간이 종료될 때까지 계속 확인합니다. DEPOSIT_MISMATCH: 트랜잭션이 지갑에서 입금 주소로 예상 금액을 전송하지 않습니다. DEPOSIT_STALE: 트랜잭션이 챌린지보다 이전 시점의 것입니다. TXID_REUSED: 트랜잭션이 이미 다른 지갑을 증명했습니다. CHAIN_UNSUPPORTED: 이 체인에서는 해당 방식을 사용할 수 없습니다. WINDOW_EXPIRED: 테스트 기간이 만료되었습니다. OWNERSHIP_CHANGED: 위젯 세션이 생성된 후 지갑 소유자가 변경되었거나 주소록에서 지갑이 삭제되었습니다. METHOD_SWITCHED: 최종 사용자가 이 방식을 완료하기 전에 다른 방식을 선택했습니다. REVIEW_REJECTED: 검토자가 스크린샷을 거부했습니다. ABANDONED: 최종 사용자가 완료하기 전에 위젯 세션이 만료되었습니다."
      },
      "TravelRuleWidgetProofError": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string",
            "description": "사람이 읽기 쉬운 영어 메시지입니다."
          },
          "code": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason"
              }
            ],
            "description": "클라이언트가 자체 번역 메시지를 표시할 수 있도록 제공되는 기계 판독 가능한 사유입니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "VERIFIED",
              "REJECTED",
              "EXPIRED"
            ],
            "description": "증명이 종료되었을 때 표시됩니다. 방금 제출된 입금으로 인해 REJECTED(400)되거나, 이미 종료된 증명에 증빙 자료가 전송되었을 때 REJECTED 또는 EXPIRED(409)됩니다."
          },
          "proof_id": {
            "type": "string",
            "format": "uuid",
            "description": "상태와 함께 표시됩니다. 종료된 증명입니다."
          },
          "method": {
            "type": "string",
            "enum": [
              "MESSAGE_SIGNING",
              "SATOSHI_TEST",
              "SCREENSHOT",
              "SELF_DECLARATION"
            ],
            "description": "상태와 함께 표시됩니다. 종료된 증명의 방식입니다."
          },
          "max_attempts": {
            "type": "integer",
            "description": "상태와 함께 표시됩니다. 이 세션에서 허용하는 거부된 지갑 증명입니다."
          },
          "attempts_used": {
            "type": "integer",
            "description": "상태와 함께 표시됩니다. 지금까지 거부된 증명 목록입니다."
          },
          "attempts_remaining": {
            "type": "integer",
            "description": "상태와 함께 표시됩니다. 0인 경우 다른 증명을 시작하면 409가 반환되며 새 위젯 세션을 발급해야 합니다."
          }
        }
      },
      "TravelRuleWidgetProofCreate": {
        "type": "object",
        "required": [
          "method"
        ],
        "properties": {
          "method": {
            "type": "string",
            "enum": [
              "MESSAGE_SIGNING",
              "SATOSHI_TEST",
              "SCREENSHOT",
              "SELF_DECLARATION"
            ],
            "description": "최종 사용자가 선택한 증명 방식입니다. 컨텍스트의 allowed_methods 중 하나여야 합니다."
          },
          "wallet_address": {
            "type": "string",
            "maxLength": 128,
            "description": "기본값은 세션의 wallet_address입니다. 세션이 거래와 연결된 경우 거래의 지갑과 일치해야 합니다."
          },
          "chain": {
            "type": "string",
            "maxLength": 32,
            "description": "기본값은 세션의 체인입니다."
          }
        }
      },
      "TravelRuleWidgetProofVerifyResult": {
        "type": "object",
        "properties": {
          "proof_id": {
            "type": "string",
            "format": "uuid"
          },
          "method": {
            "type": "string",
            "enum": [
              "MESSAGE_SIGNING",
              "SATOSHI_TEST",
              "SCREENSHOT",
              "SELF_DECLARATION"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "VERIFIED",
              "REJECTED",
              "EXPIRED"
            ]
          },
          "is_ownership_verified": {
            "type": "boolean",
            "description": "증명이 VERIFIED 상태일 때 표시됩니다. 주소록 항목의 소유권이 확인되었습니다."
          },
          "transfer_status": {
            "type": "string",
            "nullable": true,
            "description": "증명이 VERIFIED 상태일 때 표시됩니다. 연결된 전송의 상태이며, 연결된 항목이 없으면 null입니다."
          },
          "detail": {
            "type": "string",
            "description": "증명이 PENDING 상태를 유지하는 동안 표시됩니다. 검토 대기 중인 제출된 스크린샷 또는 아직 확인되지 않은 테스트 입금입니다."
          },
          "code": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason"
              }
            ],
            "description": "보류 중인 테스트 입금에 표시됩니다. 아직 확인되지 않은 이유입니다."
          }
        }
      },
      "TravelRuleWalletProofReview": {
        "type": "object",
        "properties": {
          "proof_id": {
            "type": "string",
            "format": "uuid"
          },
          "method": {
            "type": "string",
            "enum": [
              "SCREENSHOT"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "VERIFIED",
              "REJECTED",
              "EXPIRED"
            ]
          },
          "wallet_address": {
            "type": "string"
          },
          "chain": {
            "type": "string",
            "description": "표준 체인 식별자입니다(예: ETH, BTC, SOL, TRX)."
          },
          "holder_name": {
            "type": "string"
          },
          "is_ownership_verified": {
            "type": "boolean",
            "description": "이 증명 또는 다른 증명을 통해 주소록 항목의 소유권이 확인되었는지 여부입니다."
          },
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "위젯 세션이 발급된 Travel Rule 전송에 해당하는 거래입니다. transaction_id 없이 발급된 세션의 경우 null입니다."
          },
          "file_name": {
            "type": "string",
            "nullable": true
          },
          "content_type": {
            "type": "string",
            "nullable": true
          },
          "screenshot_url": {
            "type": "string",
            "nullable": true,
            "description": "업로드된 스크린샷에 대한 시간 제한 링크입니다. 최신 링크를 가져오려면 대기열을 다시 나열하십시오."
          },
          "attempts": {
            "type": "integer",
            "description": "최종 사용자가 이 증명을 위해 업로드한 파일 수입니다."
          },
          "failure_reason": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason"
              }
            ],
            "description": "거부 후에는 REVIEW_REJECTED, 결정 전에 지갑 소유자가 변경되었거나 지갑이 삭제된 경우에는 OWNERSHIP_CHANGED입니다. 그 외의 경우에는 비어 있습니다."
          },
          "method_chosen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "최종 사용자가 스크린샷 방식을 선택한 시점입니다."
          },
          "decided_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "decided_by": {
            "type": "string",
            "description": "증명을 마감한 주체: 콘솔 검토자의 경우 review:<user identifier>, API 키 결정의 경우 review, Didit이 자동으로 마감한 경우 widget 또는 sweeper입니다. PENDING 상태인 동안에는 비어 있습니다."
          },
          "review_note": {
            "type": "string",
            "description": "결정과 함께 전송된 메모입니다. 없는 경우 비어 있습니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TravelRuleWalletProofDecision": {
        "type": "object",
        "required": [
          "decision"
        ],
        "properties": {
          "decision": {
            "type": "string",
            "enum": [
              "approve",
              "reject"
            ]
          },
          "note": {
            "type": "string",
            "maxLength": 512,
            "description": "선택 사항입니다. 증명과 함께 보관되며 review_note로 반환됩니다."
          }
        }
      },
      "DigitalIdWalletApiWalletDigitalCredentialsRequest": {
        "type": "object",
        "properties": {
          "protocol": {
            "type": "string",
            "description": "openid4vp-v1-signed."
          },
          "request": {
            "type": "object",
            "additionalProperties": {},
            "description": "그대로 전달하세요. 브라우저에서는 navigator.credentials.get({digital: request}), Android에서는 GetDigitalCredentialOption의 requestJson으로 JSON.stringify(request)를 사용합니다. 귀하의 애플리케이션을 위해 Didit이 서명했습니다."
          }
        },
        "required": [
          "protocol",
          "request"
        ]
      },
      "DigitalIdWalletApiGoogleWalletWalletVerificationStartRequest": {
        "type": "object",
        "description": "Google Wallet 인증(USA, GBR, BRA, SGP, TWN)을 시작합니다.",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "이 인증에 대한 귀하 고유의 참조값(예: 사용자 ID)입니다. 결과 및 webhook으로 반환됩니다."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "인증 건과 함께 저장되고 결과 및 webhook에 반환되는 선택적 JSON 객체입니다."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "샌드박스 애플리케이션 전용: 시뮬레이션된 결과 - 'wallet_cancelled', 'wallet_timeout' 또는 'wallet_provider_error'. 다른 시나리오(또는 시나리오를 지정하지 않은 경우)는 검증에 성공합니다. 프로덕션 애플리케이션에서는 거부됩니다. 전체 카탈로그는 GET /v1/sandbox/scenarios/에서 확인할 수 있습니다."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum"
              }
            ],
            "description": "Google Wallet 신원의 ISO 3166-1 alpha-3 국가입니다.\n\n* `USA` - USA\n* `GBR` - GBR\n* `BRA` - BRA\n* `SGP` - SGP\n* `TWN` - TWN"
          },
          "origin": {
            "type": "string",
            "minLength": 1,
            "description": "페이지 또는 앱이 지갑에 요청을 보낼 위치: 페이지의 https origin(해당 호스트는 애플리케이션의 allowed_return_hosts에 포함되어 있거나 화이트 라벨 도메인이어야 함, 예: https://app.example.com) 또는 android:apk-key-hash:<패딩 없는 앱 서명 인증서의 base64 SHA-256>. 지갑은 그 외의 모든 위치에서 요청을 거부합니다.",
            "maxLength": 256
          }
        },
        "required": [
          "country",
          "origin"
        ]
      },
      "DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum": {
        "enum": [
          "USA",
          "GBR",
          "BRA",
          "SGP",
          "TWN"
        ],
        "type": "string",
        "description": "* `USA` - USA\n* `GBR` - GBR\n* `BRA` - BRA\n* `SGP` - SGP\n* `TWN` - TWN"
      },
      "DigitalIdWalletApiWalletDigitalCredentialResponseRequest": {
        "type": "object",
        "description": "``request_digital_credential`` 인증에 대해 지갑이 페이지 또는 앱에 반환한 응답 내용입니다.",
        "properties": {
          "response": {
            "type": "object",
            "additionalProperties": {},
            "description": "지갑이 반환한 정확한 내용: navigator.credentials.get의 DigitalCredential {protocol, data} 또는 Android의 DigitalCredential을 파싱한 credentialJson입니다. Didit으로 암호화되어 있으므로 변경하지 마십시오."
          }
        },
        "required": [
          "response"
        ]
      },
      "SessionFilesExport": {
        "type": "object",
        "description": "세션의 모든 파일이 원본 품질로 포함된 ZIP 파일 1개입니다.",
        "required": [
          "export_id",
          "session_id",
          "status",
          "file_count",
          "size_bytes",
          "download_url",
          "expires_at",
          "error",
          "created_at",
          "completed_at"
        ],
        "properties": {
          "export_id": {
            "type": "string",
            "format": "uuid",
            "description": "내보내기 ID입니다. `GET /v3/session/{sessionId}/files-export/{exportId}/`에 전달하세요."
          },
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "파일이 속한 세션입니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "PROCESSING",
              "READY",
              "FAILED",
              "EXPIRED"
            ],
            "description": "ZIP 파일이 준비되는 동안 `PENDING` 및 `PROCESSING`, 다운로드 가능한 상태가 되면 `READY`, 준비할 수 없었던 경우(새 내보내기 요청 필요) `FAILED`, ZIP 파일이 삭제된 후 `EXPIRED`."
          },
          "file_count": {
            "type": "integer",
            "nullable": true,
            "description": "ZIP 내의 파일입니다. `status`가 `READY`일 때만 설정됩니다."
          },
          "size_bytes": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "ZIP 파일 크기(바이트 단위)입니다. `status`가 `READY`인 동안에만 설정됩니다."
          },
          "download_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "ZIP의 서명된 URL로, 짧은 시간 동안 유효합니다. `status`가 `READY`인 동안에만 설정되며, 새 URL을 받으려면 내보내기를 다시 조회하십시오."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "ZIP 파일이 준비된 후 24시간이 지나 삭제되는 시점입니다. `status`가 `READY`인 동안에만 설정됩니다."
          },
          "error": {
            "type": "string",
            "nullable": true,
            "description": "`status`가 `FAILED`일 때 내보내기가 실패한 이유입니다."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "내보내기가 요청된 시점입니다."
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "ZIP 파일이 준비되었거나 내보내기가 실패한 시점입니다."
          }
        }
      },
      "TransactionRuleSuggestionsCreatedEvent": {
        "description": "거래 규칙 제안 실행을 통해 애플리케이션에 대한 새로운 규칙 변경 사항이 제안되었습니다. 규칙 제안 설정에서 webhook 알림이 켜져 있을 때 전송됩니다. 최상위 `status`는 없습니다.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "transaction_rule_suggestions.created"
                ],
                "description": "항상 `transaction_rule_suggestions.created`입니다."
              },
              "run_id": {
                "type": "string",
                "format": "uuid",
                "description": "새 제안을 생성한 제안 실행입니다."
              },
              "open_count": {
                "type": "integer",
                "description": "새로운 제안을 포함하여 이번 실행 후에도 여전히 열려 있는 제안 수입니다."
              },
              "suggestions": {
                "type": "array",
                "description": "이 실행에서 생성된 제안입니다.",
                "items": {
                  "type": "object",
                  "required": [
                    "suggestion_id",
                    "kind",
                    "title",
                    "rule_id",
                    "expected_impact"
                  ],
                  "properties": {
                    "suggestion_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "ADD",
                        "TWEAK",
                        "DISABLE"
                      ],
                      "description": "`ADD`는 새 규칙을 제안하고, `TWEAK`는 기존 규칙을 변경하며, `DISABLE`은 규칙을 비활성화합니다."
                    },
                    "title": {
                      "type": "string"
                    },
                    "rule_id": {
                      "type": "string",
                      "format": "uuid",
                      "nullable": true,
                      "description": "`TWEAK` 또는 `DISABLE` 제안이 적용되는 규칙입니다. `ADD`의 경우 `null`입니다."
                    },
                    "expected_impact": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "Console의 제안에 표시된 대로 해당 변경이 수행할 작업입니다."
                    }
                  }
                }
              }
            },
            "required": [
              "webhook_type",
              "run_id",
              "open_count",
              "suggestions"
            ]
          }
        ]
      },
      "GeolocationCheck": {
        "type": "object",
        "description": "단일 워크플로 노드에서 승인된 시도에 대한 위치 인증 결과입니다. 측정값, 불확실성 및 진위 여부는 별도의 키로 제공되므로, 증명되지 않은 정밀한 위치 정보와 증명된 부정밀한 위치 정보가 서로 다르게 판독됩니다.",
        "properties": {
          "node_id": {
            "type": "string",
            "nullable": true,
            "description": "이 결과를 생성한 워크플로 노드입니다. 두 개의 위치 인증 단계가 있는 워크플로에서도 결과를 명확히 구분할 수 있습니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Finished",
              "Approved",
              "Declined",
              "In Review",
              "Resub Requested"
            ],
            "description": "경고를 기반으로 해결된 이 위치 확인 단계의 기능 수준 상태입니다. 세션 `status`와는 독립적입니다."
          },
          "outcome": {
            "type": "string",
            "nullable": true,
            "description": "이 시도에서 발생한 내용입니다.",
            "enum": [
              "verified",
              "low_accuracy",
              "accuracy_undetermined",
              "stale",
              "approximate",
              "denied",
              "restricted",
              "unavailable",
              "timeout",
              "mock_detected",
              "outside_geofence",
              "in_blocked_area",
              "anonymizer_detected",
              "skipped",
              "replay_rejected",
              "unsupported_client",
              null
            ]
          },
          "permission": {
            "type": "string",
            "nullable": true,
            "description": "운영체제 또는 브라우저가 부여한 권한입니다. `not_requested`는 해당 단계가 연결의 IP 위치만 사용하므로 사용자에게 권한을 요청하지 않음을 의미합니다.",
            "enum": [
              "granted_precise",
              "granted_approximate",
              "denied",
              "restricted",
              "unavailable",
              "timeout",
              "dismissed",
              "not_requested",
              null
            ]
          },
          "latitude": {
            "type": "number",
            "nullable": true,
            "description": "측위 위치의 WGS84 위도입니다. 측위 위치가 없으면 `null`입니다.",
            "format": "double"
          },
          "longitude": {
            "type": "number",
            "nullable": true,
            "description": "측위 위치의 WGS84 경도입니다. 측위 위치가 없으면 `null`입니다.",
            "format": "double"
          },
          "accuracy_m": {
            "type": "number",
            "nullable": true,
            "description": "`accuracy_confidence`의 신뢰도 수준에서의 불확실성 반경(미터 단위).",
            "format": "double"
          },
          "accuracy_confidence": {
            "type": "string",
            "nullable": true,
            "description": "플랫폼이 `accuracy_m`에 부여하는 신뢰 수준입니다: `p95`(브라우저), `p68`(Android) 또는 `unspecified`(iOS).",
            "enum": [
              "p95",
              "p68",
              "unspecified",
              null
            ]
          },
          "measured_at": {
            "type": "string",
            "nullable": true,
            "description": "기기 자체 시계를 기준으로 기기가 위치를 확정한 시점입니다.",
            "format": "date-time"
          },
          "age_seconds": {
            "type": "integer",
            "nullable": true,
            "description": "기기가 위치를 측위한 시점부터 Didit이 이를 수신하기까지의 시간(초)."
          },
          "source": {
            "type": "string",
            "nullable": true,
            "description": "플랫폼에서 명시하는 위치 고정(fix) 정보의 출처입니다. `ip`는 위치가 연결된 IP 주소의 위치임을 의미합니다.",
            "enum": [
              "gps",
              "fused",
              "network",
              "wifi",
              "cell",
              "browser",
              "unknown",
              "ip",
              null
            ]
          },
          "platform": {
            "type": "string",
            "nullable": true,
            "description": "수정을 생성한 클라이언트입니다.",
            "enum": [
              "web",
              "ios",
              "android",
              "react_native",
              "flutter",
              null
            ]
          },
          "sdk_version": {
            "type": "string",
            "nullable": true,
            "description": "수정을 생성한 SDK의 버전입니다."
          },
          "is_mock": {
            "type": "boolean",
            "nullable": true,
            "description": "기기에서 위치 정보가 모의 위치 제공자나 시뮬레이션 소프트웨어로부터 생성된 것임을 보고할 때 `true`입니다. 플랫폼에서 이를 보고하지 않는 경우(브라우저는 구별할 수 없음) `null`이며, `null`은 `false`를 의미하지 않습니다."
          },
          "produced_by_accessory": {
            "type": "boolean",
            "nullable": true,
            "description": "iOS 전용: 외부 액세서리에서 위치 측정값을 제공한 경우 `true`, 그 외에는 `null`입니다."
          },
          "integrity": {
            "type": "string",
            "enum": [
              "attested",
              "not_attested",
              "failed",
              "unsupported",
              "not_determined"
            ],
            "description": "수정이 기기 증명으로 뒷받침되는지 여부입니다. 웹에는 증명 메커니즘이 없기 때문에 브라우저는 `unsupported`로 보고하며, 이는 실패가 아닙니다."
          },
          "country_code": {
            "type": "string",
            "nullable": true,
            "description": "위치 측정값이 속한 ISO 3166-1 alpha-2 국가 코드입니다."
          },
          "region_code": {
            "type": "string",
            "nullable": true,
            "description": "위치 측정값이 속한 ISO 3166-2 행정 구역입니다."
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "검토자를 위한 라벨인 가장 가까운 인구 밀집 지역입니다."
          },
          "geofence": {
            "type": "object",
            "description": "해당 단계의 국가 및 지역 규칙 결과입니다.",
            "properties": {
              "enabled": {
                "type": "boolean",
                "description": "단계에서 국가 또는 지역 규칙을 적용하는지 여부입니다."
              },
              "result": {
                "type": "string",
                "nullable": true,
                "description": "규칙을 기준으로 한 해당 위치의 판정 결과입니다. `undetermined`는 정확도 원이 국경에 걸쳐 있거나 위치가 어떤 국가로도 확인되지 않았음을 의미하며, 외부에 있다는 증거는 아닙니다.",
                "enum": [
                  "inside",
                  "outside",
                  "undetermined",
                  null
                ]
              }
            }
          },
          "inside_geofence": {
            "type": "boolean",
            "nullable": true,
            "description": "`geofence.result`가 `inside`인 경우 `true`, `outside`인 경우 `false`, 그 외에는 `null`입니다."
          },
          "geofence_basis": {
            "type": "string",
            "nullable": true,
            "description": "지역 결과가 판정된 위치: `device` 위치 측정값 또는 연결의 `ip` 주소 위치입니다.",
            "enum": [
              "device",
              "ip",
              null
            ]
          },
          "inside_areas": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "해당 위치가 포함된 구성된 허용 영역의 ID 목록입니다."
          },
          "blocked_areas": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "해당 위치가 속한 구성된 차단 영역의 ID 목록입니다."
          },
          "position_source": {
            "type": "string",
            "nullable": true,
            "description": "설정에 따라 해당 단계에서 위치를 가져오는 방식: 기기 위치를 IP 위치와 대조하여 확인, 기기만 사용, 또는 IP 위치만 사용.",
            "enum": [
              "device_and_ip",
              "device_only",
              "ip_only",
              null
            ]
          },
          "anonymizers": {
            "type": "object",
            "nullable": true,
            "description": "연결 및 기기의 상태입니다. 소스에서 확인할 수 없는 경우 각각 `true`, `false` 또는 `null`입니다.",
            "properties": {
              "vpn": {
                "type": "boolean",
                "nullable": true
              },
              "proxy": {
                "type": "boolean",
                "nullable": true
              },
              "tor": {
                "type": "boolean",
                "nullable": true
              },
              "spoofing": {
                "type": "boolean",
                "nullable": true
              },
              "emulator": {
                "type": "boolean",
                "nullable": true
              }
            }
          },
          "ip_distance_km": {
            "type": "number",
            "nullable": true,
            "description": "두 불확실성 반경을 뺀 후 세션의 IP 위치까지의 거리입니다. 겹치는 경우 `0`입니다.",
            "format": "double"
          },
          "ip_distance_uncertainty_km": {
            "type": "number",
            "nullable": true,
            "description": "차감된 결합 반경: IP 위치 반경에 이 측정 위치의 정확도를 더한 값입니다.",
            "format": "double"
          },
          "ip_consistent": {
            "type": "boolean",
            "nullable": true,
            "description": "`ip_distance_km`이 단계에 구성된 거리 내에 있는지 여부입니다. 어느 한쪽을 알 수 없는 경우 `null`입니다."
          },
          "document_distance_km": {
            "type": "number",
            "nullable": true,
            "description": "신분증 문서 또는 주소 증명의 지오코딩된 주소까지의 거리입니다. 등록된 주소가 없는 경우 `null`입니다.",
            "format": "double"
          },
          "travel_excused": {
            "type": "boolean",
            "nullable": true,
            "description": "단계의 이동 허용 오차가 주소로부터의 거리를 허용했는지 여부입니다. 허용 오차가 꺼져 있으면 `null`입니다."
          },
          "consecutive_mismatches": {
            "type": "integer",
            "nullable": true,
            "description": "최종 시도 시: 이번 확인과 동일 인물의 이전 연속 불일치 내역이 포함됩니다."
          },
          "attempts": {
            "type": "integer",
            "description": "노드 내에서 1부터 시작하는 이번 시도의 번호입니다."
          },
          "consent": {
            "type": "object",
            "nullable": true,
            "description": "시스템 프롬프트 전에 사용자가 제공한 동의 내용으로, 사용자에게 표시된 문구 버전 및 언어와 함께 기록됩니다.",
            "properties": {
              "accepted_at": {
                "type": "string",
                "format": "date-time"
              },
              "version": {
                "type": "string",
                "nullable": true
              },
              "locale": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "feature": {
                  "type": "string",
                  "enum": [
                    "ID_VERIFICATION",
                    "NFC",
                    "LIVENESS",
                    "FACEMATCH",
                    "PROOF_OF_ADDRESS",
                    "PHONE",
                    "EMAIL",
                    "AML",
                    "LOCATION",
                    "DATABASE_VALIDATION",
                    "QUESTIONNAIRE",
                    "DOCUMENT_AI",
                    "KYB_REGISTRY",
                    "KYB_DOCUMENTS",
                    "KYB_KEY_PEOPLE",
                    "GEOLOCATION",
                    "SIGNATURE"
                  ],
                  "description": "이 경고를 생성한 기능입니다. 이 값은 경고가 속한 기능 블록을 식별합니다. 각 모듈의 경고 배열은 일반적으로 해당 모듈과 일치하는 값을 사용하지만(예: `phone_verifications[].warnings` 내부의 `PHONE`), 결정 payload의 모든 기능 경고에 대해서는 위의 enum이 기준이 됩니다."
                },
                "risk": {
                  "type": "string"
                },
                "additional_data": {
                  "type": "object",
                  "nullable": true
                },
                "log_type": {
                  "type": "string"
                },
                "short_description": {
                  "type": "string"
                },
                "long_description": {
                  "type": "string"
                },
                "node_id": {
                  "type": "string",
                  "description": "이 경고를 생성한 워크플로 그래프 노드 ID"
                }
              }
            },
            "description": "이 위치 인증 단계에서 발생한 경고로, `feature`는 `GEOLOCATION`으로 설정됩니다. 경고 코드는 `LOCATION_`으로 시작합니다."
          }
        }
      },
      "GeolocationAttempt": {
        "type": "object",
        "description": "위치 인증 단계 시도 1회입니다. `warnings`를 제외하고 `geolocation_checks[]`와 동일한 키 및 Didit이 이를 수신한 시간이 포함됩니다.",
        "properties": {
          "node_id": {
            "type": "string",
            "nullable": true,
            "description": "이 결과를 생성한 워크플로 노드입니다. 두 개의 위치 인증 단계가 있는 워크플로에서도 결과를 명확히 구분할 수 있습니다."
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Finished",
              "Approved",
              "Declined",
              "In Review",
              "Resub Requested"
            ],
            "description": "경고를 기반으로 해결된 이 위치 확인 단계의 기능 수준 상태입니다. 세션 `status`와는 독립적입니다."
          },
          "outcome": {
            "type": "string",
            "nullable": true,
            "description": "이 시도에서 발생한 내용입니다.",
            "enum": [
              "verified",
              "low_accuracy",
              "accuracy_undetermined",
              "stale",
              "approximate",
              "denied",
              "restricted",
              "unavailable",
              "timeout",
              "mock_detected",
              "outside_geofence",
              "in_blocked_area",
              "anonymizer_detected",
              "skipped",
              "replay_rejected",
              "unsupported_client",
              null
            ]
          },
          "permission": {
            "type": "string",
            "nullable": true,
            "description": "운영체제 또는 브라우저가 부여한 권한입니다. `not_requested`는 해당 단계가 연결의 IP 위치만 사용하므로 사용자에게 권한을 요청하지 않음을 의미합니다.",
            "enum": [
              "granted_precise",
              "granted_approximate",
              "denied",
              "restricted",
              "unavailable",
              "timeout",
              "dismissed",
              "not_requested",
              null
            ]
          },
          "latitude": {
            "type": "number",
            "nullable": true,
            "description": "측위 위치의 WGS84 위도입니다. 측위 위치가 없으면 `null`입니다.",
            "format": "double"
          },
          "longitude": {
            "type": "number",
            "nullable": true,
            "description": "측위 위치의 WGS84 경도입니다. 측위 위치가 없으면 `null`입니다.",
            "format": "double"
          },
          "accuracy_m": {
            "type": "number",
            "nullable": true,
            "description": "`accuracy_confidence`의 신뢰도 수준에서의 불확실성 반경(미터 단위).",
            "format": "double"
          },
          "accuracy_confidence": {
            "type": "string",
            "nullable": true,
            "description": "플랫폼이 `accuracy_m`에 부여하는 신뢰 수준입니다: `p95`(브라우저), `p68`(Android) 또는 `unspecified`(iOS).",
            "enum": [
              "p95",
              "p68",
              "unspecified",
              null
            ]
          },
          "measured_at": {
            "type": "string",
            "nullable": true,
            "description": "기기 자체 시계를 기준으로 기기가 위치를 확정한 시점입니다.",
            "format": "date-time"
          },
          "age_seconds": {
            "type": "integer",
            "nullable": true,
            "description": "기기가 위치를 측위한 시점부터 Didit이 이를 수신하기까지의 시간(초)."
          },
          "source": {
            "type": "string",
            "nullable": true,
            "description": "플랫폼에서 명시하는 위치 고정(fix) 정보의 출처입니다. `ip`는 위치가 연결된 IP 주소의 위치임을 의미합니다.",
            "enum": [
              "gps",
              "fused",
              "network",
              "wifi",
              "cell",
              "browser",
              "unknown",
              "ip",
              null
            ]
          },
          "platform": {
            "type": "string",
            "nullable": true,
            "description": "수정을 생성한 클라이언트입니다.",
            "enum": [
              "web",
              "ios",
              "android",
              "react_native",
              "flutter",
              null
            ]
          },
          "sdk_version": {
            "type": "string",
            "nullable": true,
            "description": "수정을 생성한 SDK의 버전입니다."
          },
          "is_mock": {
            "type": "boolean",
            "nullable": true,
            "description": "기기에서 위치 정보가 모의 위치 제공자나 시뮬레이션 소프트웨어로부터 생성된 것임을 보고할 때 `true`입니다. 플랫폼에서 이를 보고하지 않는 경우(브라우저는 구별할 수 없음) `null`이며, `null`은 `false`를 의미하지 않습니다."
          },
          "produced_by_accessory": {
            "type": "boolean",
            "nullable": true,
            "description": "iOS 전용: 외부 액세서리에서 위치 측정값을 제공한 경우 `true`, 그 외에는 `null`입니다."
          },
          "integrity": {
            "type": "string",
            "enum": [
              "attested",
              "not_attested",
              "failed",
              "unsupported",
              "not_determined"
            ],
            "description": "수정이 기기 증명으로 뒷받침되는지 여부입니다. 웹에는 증명 메커니즘이 없기 때문에 브라우저는 `unsupported`로 보고하며, 이는 실패가 아닙니다."
          },
          "country_code": {
            "type": "string",
            "nullable": true,
            "description": "위치 측정값이 속한 ISO 3166-1 alpha-2 국가 코드입니다."
          },
          "region_code": {
            "type": "string",
            "nullable": true,
            "description": "위치 측정값이 속한 ISO 3166-2 행정 구역입니다."
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "검토자를 위한 라벨인 가장 가까운 인구 밀집 지역입니다."
          },
          "geofence": {
            "type": "object",
            "description": "해당 단계의 국가 및 지역 규칙 결과입니다.",
            "properties": {
              "enabled": {
                "type": "boolean",
                "description": "단계에서 국가 또는 지역 규칙을 적용하는지 여부입니다."
              },
              "result": {
                "type": "string",
                "nullable": true,
                "description": "규칙을 기준으로 한 해당 위치의 판정 결과입니다. `undetermined`는 정확도 원이 국경에 걸쳐 있거나 위치가 어떤 국가로도 확인되지 않았음을 의미하며, 외부에 있다는 증거는 아닙니다.",
                "enum": [
                  "inside",
                  "outside",
                  "undetermined",
                  null
                ]
              }
            }
          },
          "inside_geofence": {
            "type": "boolean",
            "nullable": true,
            "description": "`geofence.result`가 `inside`인 경우 `true`, `outside`인 경우 `false`, 그 외에는 `null`입니다."
          },
          "geofence_basis": {
            "type": "string",
            "nullable": true,
            "description": "지역 결과가 판정된 위치: `device` 위치 측정값 또는 연결의 `ip` 주소 위치입니다.",
            "enum": [
              "device",
              "ip",
              null
            ]
          },
          "inside_areas": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "해당 위치가 포함된 구성된 허용 영역의 ID 목록입니다."
          },
          "blocked_areas": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "해당 위치가 속한 구성된 차단 영역의 ID 목록입니다."
          },
          "position_source": {
            "type": "string",
            "nullable": true,
            "description": "설정에 따라 해당 단계에서 위치를 가져오는 방식: 기기 위치를 IP 위치와 대조하여 확인, 기기만 사용, 또는 IP 위치만 사용.",
            "enum": [
              "device_and_ip",
              "device_only",
              "ip_only",
              null
            ]
          },
          "anonymizers": {
            "type": "object",
            "nullable": true,
            "description": "연결 및 기기의 상태입니다. 소스에서 확인할 수 없는 경우 각각 `true`, `false` 또는 `null`입니다.",
            "properties": {
              "vpn": {
                "type": "boolean",
                "nullable": true
              },
              "proxy": {
                "type": "boolean",
                "nullable": true
              },
              "tor": {
                "type": "boolean",
                "nullable": true
              },
              "spoofing": {
                "type": "boolean",
                "nullable": true
              },
              "emulator": {
                "type": "boolean",
                "nullable": true
              }
            }
          },
          "ip_distance_km": {
            "type": "number",
            "nullable": true,
            "description": "두 불확실성 반경을 뺀 후 세션의 IP 위치까지의 거리입니다. 겹치는 경우 `0`입니다.",
            "format": "double"
          },
          "ip_distance_uncertainty_km": {
            "type": "number",
            "nullable": true,
            "description": "차감된 결합 반경: IP 위치 반경에 이 측정 위치의 정확도를 더한 값입니다.",
            "format": "double"
          },
          "ip_consistent": {
            "type": "boolean",
            "nullable": true,
            "description": "`ip_distance_km`이 단계에 구성된 거리 내에 있는지 여부입니다. 어느 한쪽을 알 수 없는 경우 `null`입니다."
          },
          "document_distance_km": {
            "type": "number",
            "nullable": true,
            "description": "신분증 문서 또는 주소 증명의 지오코딩된 주소까지의 거리입니다. 등록된 주소가 없는 경우 `null`입니다.",
            "format": "double"
          },
          "travel_excused": {
            "type": "boolean",
            "nullable": true,
            "description": "단계의 이동 허용 오차가 주소로부터의 거리를 허용했는지 여부입니다. 허용 오차가 꺼져 있으면 `null`입니다."
          },
          "consecutive_mismatches": {
            "type": "integer",
            "nullable": true,
            "description": "최종 시도 시: 이번 확인과 동일 인물의 이전 연속 불일치 내역이 포함됩니다."
          },
          "attempts": {
            "type": "integer",
            "description": "노드 내에서 1부터 시작하는 이번 시도의 번호입니다."
          },
          "consent": {
            "type": "object",
            "nullable": true,
            "description": "시스템 프롬프트 전에 사용자가 제공한 동의 내용으로, 사용자에게 표시된 문구 버전 및 언어와 함께 기록됩니다.",
            "properties": {
              "accepted_at": {
                "type": "string",
                "format": "date-time"
              },
              "version": {
                "type": "string",
                "nullable": true
              },
              "locale": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "received_at": {
            "type": "string",
            "nullable": true,
            "description": "Didit이 시도를 수신한 시점입니다.",
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BiometricRetention": {
        "type": "object",
        "description": "이 세션의 라이브 생체 데이터가 삭제되는 시점입니다.",
        "required": [
          "jurisdictions",
          "deletes_at"
        ],
        "properties": {
          "jurisdictions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "해당 인물에 대한 삭제 기한을 설정하는 생체 인식 규정이 있는 미국 주의 코드(주를 알 수 없는 경우 `US`). 해당하는 규정이 없으면 비어 있습니다."
          },
          "deletes_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "애플리케이션의 데이터 보존 설정과 해당 인물의 관할권 법적 한도(적용되는 경우)에 따라 이 세션의 라이브 생체 데이터(얼굴 이미지 및 템플릿)가 삭제되는 날짜입니다. 아직 적용되는 날짜가 없는 경우 `null`입니다."
          }
        }
      },
      "TravelRuleManualMatchRequest": {
        "type": "object",
        "required": [
          "transaction_id"
        ],
        "properties": {
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "description": "수신된 Travel Rule 메시지(`kind: message` 행)의 `transaction_id`입니다."
          }
        }
      },
      "TravelRuleManualMatchResponse": {
        "type": "object",
        "required": [
          "deposit",
          "message"
        ],
        "properties": {
          "deposit": {
            "$ref": "#/components/schemas/TravelRuleTransferRow"
          },
          "message": {
            "$ref": "#/components/schemas/TravelRuleTransferRow"
          }
        }
      }
    },
    "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 를 참고하십시오."
      },
      "TransactionTokenAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Transaction-Token",
        "description": "백엔드에서 POST /v3/transactions/sdk-token/을 통해 발행한 유효 기간이 짧은 범위 지정 token입니다. 디바이스용 /v1/transactions/ endpoints에서 Didit SDK가 사용합니다."
      },
      "SessionTokenAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Session-Token",
        "description": "POST /v3/session/의 `session_token` 필드로 반환되는 유효 기간이 짧은 token입니다. 호스팅 인증 흐름(및 커스텀 샌드박스 UI)에서 서버 측 API 키 없이 인증 중인 사용자를 대신하여 세션 범위의 endpoints를 호출하는 데 사용됩니다."
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "애플리케이션의 클라이언트 자격 증명 액세스 token입니다."
      },
      "CaseRequestToken": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Case-Request-Token",
        "description": "보안 링크에서 제공되는 요청별 자격 증명입니다. 이 요청에 대한 액세스 권한만 부여합니다."
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "권한 없음",
        "content": {
          "application/json": {
            "examples": {
              "Invalid API Key": {
                "summary": "유효하지 않은 API 키",
                "value": {
                  "detail": "Invalid API Key."
                }
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "금지됨",
        "content": {
          "application/json": {
            "examples": {
              "No Permission": {
                "summary": "권한 없음",
                "value": {
                  "detail": "You do not have permission to perform this action."
                }
              },
              "Not Enough Credits": {
                "summary": "크레딧 부족",
                "value": {
                  "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                }
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "찾을 수 없음",
        "content": {
          "application/json": {
            "examples": {
              "Not Found": {
                "summary": "찾을 수 없음",
                "value": {
                  "detail": "Resource not found."
                }
              }
            }
          }
        }
      },
      "PhoneRiskValidationError": {
        "description": "요청 유효성 검사에 실패했습니다.",
        "content": {
          "application/json": {
            "examples": {
              "Missing phone number": {
                "summary": "전화번호가 누락되었습니다",
                "value": {
                  "phone_number": [
                    "This field is required."
                  ]
                }
              },
              "Invalid phone number": {
                "summary": "유효하지 않은 전화번호",
                "value": {
                  "phone_number": [
                    "Invalid phone number provided."
                  ]
                }
              },
              "Invalid signal IP": {
                "summary": "유효하지 않은 신호 IP",
                "value": {
                  "signals": {
                    "ip": [
                      "Enter a valid IPv4 or IPv6 address."
                    ]
                  }
                }
              }
            }
          }
        }
      },
      "EmailRiskValidationError": {
        "description": "요청 유효성 검사에 실패했습니다.",
        "content": {
          "application/json": {
            "examples": {
              "Missing email": {
                "summary": "이메일이 누락되었습니다",
                "value": {
                  "email": [
                    "This field is required."
                  ]
                }
              },
              "Invalid email": {
                "summary": "유효하지 않은 이메일",
                "value": {
                  "email": [
                    "Enter a valid email address."
                  ]
                }
              },
              "Invalid country hint": {
                "summary": "유효하지 않은 국가 힌트",
                "value": {
                  "country_code": [
                    "Ensure this field has no more than 3 characters."
                  ]
                }
              }
            }
          }
        }
      },
      "IPRiskValidationError": {
        "description": "요청 유효성 검사에 실패했습니다.",
        "content": {
          "application/json": {
            "examples": {
              "Missing IP address": {
                "summary": "IP 주소가 누락되었습니다",
                "value": {
                  "ip_address": [
                    "This field is required."
                  ]
                }
              },
              "Invalid IP address": {
                "summary": "유효하지 않은 IP 주소",
                "value": {
                  "ip_address": [
                    "Enter a valid IPv4 or IPv6 address."
                  ]
                }
              },
              "Country hint too long": {
                "summary": "국가 힌트가 너무 김",
                "value": {
                  "claimed_country": [
                    "Ensure this field has no more than 3 characters."
                  ]
                }
              }
            }
          }
        }
      },
      "RiskPermissionDenied": {
        "description": "API 키가 누락되었거나 유효하지 않거나, 조직이 실시간 조회 비용을 충당할 수 없습니다. 이 API는 절대 `401`을 반환하지 않습니다.",
        "content": {
          "application/json": {
            "examples": {
              "Missing or invalid API key": {
                "summary": "`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다",
                "value": {
                  "detail": "You do not have permission to perform this action."
                }
              },
              "Not enough credits": {
                "summary": "조직 잔액이 조회 가격을 충당할 수 없습니다",
                "value": {
                  "error": "You don't have enough credits to perform this request."
                }
              }
            }
          }
        }
      },
      "RateLimitedWrite": {
        "description": "API 키당 분당 300개의 요청을 처리하는 공유 쓰기 속도 제한을 초과했습니다. 다시 시도하기 전에 `Retry-After`를 준수하십시오.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "detail"
              ],
              "properties": {
                "detail": {
                  "type": "string"
                }
              }
            },
            "example": {
              "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
            }
          }
        }
      },
      "AddressValidationValidationError": {
        "description": "요청 본문이 잘못되었습니다. `country`가 누락되었거나 알 수 없음, 주소 없음, 또는 `address`와 구조화된 필드가 모두 포함되어 있습니다.",
        "content": {
          "application/json": {
            "examples": {
              "Unknown country": {
                "value": {
                  "country": [
                    "Use an ISO 3166-1 alpha-2 or alpha-3 country code, e.g. 'US' or 'USA'."
                  ]
                }
              },
              "No address": {
                "value": {
                  "address": [
                    "Send the address: 'address' on one line, or the structured fields with 'address_line_1'."
                  ]
                }
              },
              "Both shapes": {
                "value": {
                  "address": [
                    "Send either 'address' or the structured fields (address_line_1, ...), not both."
                  ]
                }
              }
            }
          }
        }
      },
      "AddressValidationPermissionDenied": {
        "description": "API 키가 누락되었거나 유효하지 않음, 스코프 키에 `sessions` 쓰기 권한이 없음, 또는 조직이 검증 비용을 충당할 수 없습니다. 이 API는 절대 `401`을 반환하지 않습니다.",
        "content": {
          "application/json": {
            "examples": {
              "Missing or invalid API key": {
                "value": {
                  "detail": "You do not have permission to perform this action."
                }
              },
              "Not enough credits": {
                "value": {
                  "detail": "You don't have enough credits to perform this request. Please top up at https://business.didit.me",
                  "code": "insufficient_credits"
                }
              }
            }
          }
        }
      },
      "DocumentProcessingBusy": {
        "description": "현재 너무 많은 문서가 처리 중이므로 이 업로드가 처리되지 않았습니다. 아무것도 저장되지 않았으며 시도 횟수도 사용되지 않았습니다. `Retry-After`의 시간(초)이 지난 후 동일한 파일을 다시 전송하세요. 메시지 텍스트가 아닌 `code`를 기준으로 분기하세요.",
        "headers": {
          "Retry-After": {
            "description": "동일한 요청을 다시 전송하기 전에 대기해야 하는 시간(초)입니다.",
            "schema": {
              "type": "integer",
              "example": 10
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "detail",
                "code"
              ],
              "properties": {
                "detail": {
                  "type": "string"
                },
                "code": {
                  "type": "string",
                  "enum": [
                    "document_processing_busy"
                  ]
                }
              }
            },
            "example": {
              "detail": "We are busy processing documents. Please try again in a moment.",
              "code": "document_processing_busy"
            }
          }
        }
      }
    },
    "parameters": {
      "WebhookSignature": {
        "name": "X-Signature",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "대상 시크릿으로 키가 지정된 정확한 원시 요청 본문의 소문자 16진수 HMAC-SHA256입니다."
      },
      "WebhookSignatureV2": {
        "name": "X-Signature-V2",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "대상 시크릿으로 키가 지정된 본문의 표준 JSON(키 정렬, 공백 없음, 비 ASCII 문자 이스케이프 해제)의 소문자 16진수 HMAC-SHA256입니다. 본문을 재인코딩하는 미들웨어를 거쳐도 유지되므로 권장됩니다."
      },
      "WebhookSignatureSimple": {
        "name": "X-Signature-Simple",
        "in": "header",
        "required": true,
        "deprecated": true,
        "schema": {
          "type": "string"
        },
        "description": "대상의 시크릿을 키로 사용하는 `{timestamp}:{session_id}:{status}:{webhook_type}`의 소문자 16진수 HMAC-SHA256(누락된 필드는 빈 문자열 처리). payload는 포함되지 않으며 엔벨로프에만 적용됩니다."
      },
      "WebhookTimestamp": {
        "name": "X-Timestamp",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "본문의 `timestamp`와 동일한 Unix 시간(초)입니다. 몇 분 이상 지난 전송은 거부해야 합니다."
      }
    }
  },
  "x-webhooks": {
    "status.updated": {
      "post": {
        "summary": "세션 상태가 변경되었습니다",
        "description": "인증 세션 상태가 변경되었습니다. `decision`은 `Approved`, `Declined`, `In Review`, `Abandoned`에 대해서만 전송됩니다. webhook 버전 3(기본값) 대상의 경우 `GET /v3/session/{sessionId}/decision/` 형태를 가지며, 버전 1 또는 2 대상의 경우 이전 축소 형태를 가집니다. 기업 세션은 항상 버전 3 기업 결정을 수신합니다.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionStatusUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "모든 2xx 응답은 전송을 확인합니다. 기타 응답 및 시간 초과는 재시도됩니다. https://docs.didit.me/integration/webhooks를 참조하십시오."
          }
        }
      }
    },
    "data.updated": {
      "post": {
        "summary": "세션 데이터가 변경되었습니다",
        "description": "수동 검토 수정, 단계 오버라이드 또는 지속적인 모니터링 재스크리닝 후와 같이 상태 변경 없이 인증 세션의 데이터가 변경되었습니다. `decision`은 `Approved`, `Declined`, `In Review`, `Abandoned`에 대해서만 전송됩니다. webhook 버전 3(기본값) 대상의 경우 `GET /v3/session/{sessionId}/decision/` 형태를 가지며, 버전 1 또는 2 대상의 경우 이전의 축소된 형태를 가집니다. 기업 세션은 항상 버전 3 기업 결정을 수신합니다.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionDataUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "모든 2xx 응답은 전송을 확인합니다. 기타 응답 및 시간 초과는 재시도됩니다. https://docs.didit.me/integration/webhooks를 참조하십시오."
          }
        }
      }
    },
    "user.status.updated": {
      "post": {
        "summary": "사용자 상태가 변경되었습니다",
        "description": "사용자 상태가 변경되었습니다. 사용자가 생성될 때는 전송되지 않습니다.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserStatusUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "모든 2xx 응답은 전송을 확인합니다. 기타 응답 및 시간 초과는 재시도됩니다. https://docs.didit.me/integration/webhooks를 참조하십시오."
          }
        }
      }
    },
    "user.data.updated": {
      "post": {
        "summary": "사용자 데이터가 변경되었습니다",
        "description": "사용자의 필드가 변경되었습니다. 사용자가 생성될 때는 전송되지 않습니다. 한 번의 저장으로 상태 이벤트와 데이터 이벤트가 모두 생성될 수 있습니다.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserDataUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "모든 2xx 응답은 전송을 확인합니다. 기타 응답 및 시간 초과는 재시도됩니다. https://docs.didit.me/integration/webhooks를 참조하십시오."
          }
        }
      }
    },
    "business.status.updated": {
      "post": {
        "summary": "기업 상태 변경됨",
        "description": "기업의 상태가 변경되었습니다. 기업이 생성될 때는 전송되지 않습니다.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BusinessStatusUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "모든 2xx 응답은 전송을 확인합니다. 기타 응답 및 시간 초과는 재시도됩니다. https://docs.didit.me/integration/webhooks를 참조하십시오."
          }
        }
      }
    },
    "business.data.updated": {
      "post": {
        "summary": "기업 데이터 변경됨",
        "description": "기업의 필드가 변경되었습니다. 기업이 생성될 때는 전송되지 않습니다. 한 번의 저장으로 상태 이벤트와 데이터 이벤트가 모두 생성될 수 있습니다.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BusinessDataUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "모든 2xx 응답은 전송을 확인합니다. 기타 응답 및 시간 초과는 재시도됩니다. https://docs.didit.me/integration/webhooks를 참조하십시오."
          }
        }
      }
    },
    "transaction.created": {
      "post": {
        "summary": "거래 생성됨",
        "description": "거래가 생성되고 스크리닝되었습니다. 프로덕션 애플리케이션에 대해서만 전송됩니다.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionCreatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "모든 2xx 응답은 전송을 확인합니다. 기타 응답 및 시간 초과는 재시도됩니다. https://docs.didit.me/integration/webhooks를 참조하십시오."
          }
        }
      }
    },
    "transaction.status.updated": {
      "post": {
        "summary": "거래 상태가 변경됨",
        "description": "규칙, 검토 또는 최종 사용자의 작업으로 인해 거래 상태가 변경되었습니다. 프로덕션 애플리케이션에 대해서만 전송됩니다.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionStatusUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "모든 2xx 응답은 전송을 확인합니다. 기타 응답 및 시간 초과는 재시도됩니다. https://docs.didit.me/integration/webhooks를 참조하십시오."
          }
        }
      }
    },
    "travel_rule.status.updated": {
      "post": {
        "summary": "Travel Rule 상태가 변경됨",
        "description": "Travel Rule 교환 상태가 변경되었습니다. `FINISHED`, `CANCELLED` 또는 `EXPIRED`를 포함한 모든 전환 시 전송되며, 그 이후에는 전송되지 않습니다. 프로덕션 애플리케이션에 대해 전송되며, Travel Rule 교환의 경우 샌드박스 애플리케이션(`environment: sandbox`)에 대해서도 전송됩니다. 최상위 `status`는 없습니다.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleStatusUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "모든 2xx 응답은 전송을 확인합니다. 기타 응답 및 시간 초과는 재시도됩니다. https://docs.didit.me/integration/webhooks를 참조하십시오."
          }
        }
      }
    },
    "workflow.compliance_changed": {
      "post": {
        "summary": "워크플로 컴플라이언스 변경됨",
        "description": "재평가 후 게시된 워크플로의 컴플라이언스 상태가 변경되었습니다. 워크플로당 하나의 이벤트가 발생합니다. 최상위 `status`는 없습니다.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WorkflowComplianceChangedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "모든 2xx 응답은 전송을 확인합니다. 기타 응답 및 시간 초과는 재시도됩니다. https://docs.didit.me/integration/webhooks를 참조하십시오."
          }
        }
      }
    },
    "kyb.registry_search.resolved": {
      "post": {
        "summary": "기업 검색 완료(서명되지 않은 콜백)",
        "description": "등기부 검색이 완료되면 `POST /v3/kyb/search/`의 `webhook_url`로 전송되는 콜백의 본문입니다. 서명되지 않습니다. 요청에 `X-Didit-Unsigned-Callback: true`가 포함되고 서명 헤더는 포함되지 않으므로, 시작한 검색의 `request_id`와 대조하여 확인하십시오. `webhook_type`이 아닌 `event_type`을 사용합니다.",
        "tags": [
          "Webhook"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KYBRegistrySearchResolvedCallback"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "모든 2xx 응답은 전송을 확인합니다. 기타 응답 및 시간 초과는 재시도됩니다. https://docs.didit.me/integration/webhooks를 참조하십시오."
          }
        }
      }
    },
    "transaction_rule_suggestions.created": {
      "post": {
        "summary": "거래 규칙 제안 생성됨",
        "description": "거래 규칙 제안 실행을 통해 애플리케이션에 대한 새로운 규칙 변경 사항이 제안되었습니다. 규칙 제안 설정에서 webhook 알림이 켜져 있을 때 전송됩니다. 최상위 `status`는 없습니다.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRuleSuggestionsCreatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "모든 2xx 응답은 전송을 확인합니다. 기타 응답 및 시간 초과는 재시도됩니다. https://docs.didit.me/integration/webhooks를 참조하십시오."
          }
        }
      }
    }
  }
}
