> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# KYC API 연동 가이드: 엔드투엔드 전체 흐름

> Didit REST API를 엔드투엔드로 연동하세요. 자격 증명 발급, 세션 생성, 인증 링크 공유, webhook 처리, KYC 결정 조회까지 몇 분 안에 완료할 수 있습니다.

이 가이드는 REST API를 통해 Didit 신원 확인을 연동하는 전체 절차를 안내합니다. 자격 증명 받기, 세션 생성, 사용자에게 세션 제시, 결과 수신 순서로 진행합니다.

***

## 1단계: 자격 증명 받기

`api_key`를 얻는 방법은 두 가지입니다.

### 옵션 A: 프로그래밍 방식 등록(브라우저 불필요)

CI/CD 및 AI 에이전트에 적합합니다. `POST /programmatic/register/`와 `POST /programmatic/verify-email/` 두 번의 API 호출로 응답에 `api_key`가 바로 포함되어 반환됩니다.

→ 전체 절차, 비밀번호 규칙, JWT 수명, 잠금 정책은 [프로그래밍 방식 등록](https://docs.didit.me/ko/integration/programmatic-registration.md)을 참조하십시오.

### 옵션 B: Didit 콘솔에서 받기

1. [Didit 콘솔](https://business.didit.me)으로 이동합니다.
2. 조직을 생성하거나 선택합니다.
3. **설정** → **API & Webhooks**로 이동합니다.
4. 다음 항목을 복사합니다.
   * **API 키**: 모든 인증 호출에서 `x-api-key` 헤더로 사용됩니다.
   * **webhook 비밀 키**: webhook HMAC 서명을 검증하는 데 사용됩니다.

### 환경 변수

```bash theme={null}
# Required
DIDIT_API_KEY=your_api_key_here
DIDIT_WEBHOOK_SECRET=your_webhook_secret_here

# Your workflow ID (from the Console)
DIDIT_WORKFLOW_ID=your_workflow_id_here
```

***

## 2단계: 워크플로 만들기

세션을 생성하기 전에 인증 워크플로가 필요합니다. 워크플로는 사용자가 거치게 될 인증 단계를 정의합니다.

### 콘솔에서 만들기

1. [Didit 콘솔](https://business.didit.me)으로 이동하여 **워크플로**를 선택합니다.
2. **워크플로 만들기**를 클릭합니다.
3. 기본 템플릿을 선택합니다:

| 템플릿 | 적합한 용도 |
| - | - |
| **KYC** | 신분증을 사용한 전체 신원 확인 |
| **적응형 연령 확인** | 선택적 신분증 보조 수단을 제공하는 연령 확인 |
| **생체 인증** | 재방문 사용자 재인증 |
| **주소 확인** | 주소 증명 검증 |

4. 선택적 기능을 추가합니다:

| 기능 | 설명 |
| - | - |
| NFC 인증 | 여권/신분증 칩 데이터 읽기 |
| 라이브니스 감지 | 셀피 영상으로 스푸핑 방지 |
| 얼굴 대조 | 셀피를 문서 사진과 대조 |
| 전화번호 인증 | SMS로 전화번호 확인 |
| 이메일 인증 | 이메일 주소 확인 |
| AML 스크리닝 | 제재 및 PEP 목록과 대조 |
| 데이터베이스 검증 | 정부 데이터베이스와 대조하여 검증 |
| 기기 및 IP 분석 | VPN, 프록시, 위치 정보 탐지 |

5. **워크플로 ID**를 복사합니다.

> [!NOTE]
>
> 자세한 구성 옵션은 [워크플로 문서](https://docs.didit.me/ko/console/workflows.md)를 참조하십시오.

***

## 3단계: 검증 세션 생성

사용자를 위한 세션을 만들려면 API를 호출합니다.

### 요청

```bash theme={null}
curl -X POST https://verification.didit.me/v3/session/ \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "workflow_id": "your-workflow-id",
    "callback": "https://yourapp.com/verification-complete",
    "vendor_data": "user-123"
  }'
```

### 요청 파라미터

| 파라미터 | 필수 여부 | 설명 |
| - | - | - |
| `workflow_id` | 예 | 콘솔에서 확인한 워크플로 UUID입니다. |
| `callback` | 아니요 | 검증이 끝난 후 사용자를 보낼 URL입니다. Didit은 쿼리 파라미터로 `verificationSessionId`와 `status`를 추가합니다. 사용자 지정 스킴(예: `myapp://`)을 지원합니다. 생략하면 워크플로에 설정된 콜백 URL을 사용합니다. |
| `callback_method` | 아니요 | 리디렉션을 처리할 기기를 지정합니다: `initiator`, `completer`, `both`. 기본값은 `initiator`입니다. |
| `vendor_data` | 아니요 | 내부 사용자 식별자입니다. 웹훅에 그대로 반환되어 데이터를 연결하는 데 쓰입니다. |
| `metadata` | 아니요 | 세션과 함께 저장되고 웹훅에 그대로 반환되는 임의의 JSON 객체입니다. |
| `language` | 아니요 | UI 언어 힌트입니다(ISO 639-1, 예: `en`, `es`). 생략하면 브라우저 언어를 자동으로 감지합니다. |
| `contact_details` | 아니요 | 사전 입력과 이메일 알림에 사용할 사용자의 이메일 또는 전화번호입니다. |
| `expected_details` | 아니요 | 인증된 데이터와 교차 검증할 사용자의 예상 세부 정보입니다. |
| `portrait_image` | 조건부 | Base64로 인코딩된 얼굴 이미지입니다(최대 2MB, JPEG, PNG, WebP 또는 TIFF). 생체 인증 또는 얼굴 대조 우선 워크플로에서 기준 얼굴로 사용합니다. `vendor_data` 사용자에게 저장된 얼굴(승인된 라이브니스 얼굴, 전자여권 사진, 신분증 초상 또는 등록된 프로필 얼굴)이 이미 있으면 생략할 수 있으며, Didit이 이를 자동으로 재사용합니다. 둘 다 없으면 `400`을 반환합니다. |
| `sandbox_scenario` | 아니요 | 샌드박스 전용 시나리오 슬러그(예: `approve`, `decline_aml_hit`)입니다. 세션에 매직 입력값을 자동으로 채웁니다. |

### 모든 옵션을 포함한 전체 예시

```bash theme={null}
curl -X POST https://verification.didit.me/v3/session/ \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "workflow_id": "11111111-2222-3333-4444-555555555555",
    "callback": "https://yourapp.com/verification-complete",
    "vendor_data": "user-123",
    "metadata": {
      "plan": "premium",
      "signup_source": "mobile-app"
    },
    "contact_details": {
      "email": "alex.sample@example.com",
      "email_lang": "en",
      "send_notification_emails": true,
      "phone": "+15550101000"
    },
    "expected_details": {
      "first_name": "John",
      "last_name": "Doe",
      "date_of_birth": "1990-01-01",
      "expected_document_types": ["P", "ID"]
    }
  }'
```

> [!NOTE]
>
> `expected_details.expected_document_types`는 신분증 인증 단계를 특정 문서 유형으로 제한합니다. 문서 선택 화면에는 요청한 유형만 표시됩니다. 허용되는 값: `P`(여권), `ID`(주민등록증), `DL`(운전면허증), `RP`(거주 허가증), `HIC`(건강보험 카드), `TC`(납세자 카드), `SSC`(사회보장 카드). 값은 대소문자를 구분하지 않으며 중복은 제거됩니다. 알 수 없는 값은 `400`을 반환합니다. 전체 스키마는 [세션 생성 참조](https://docs.didit.me/ko/sessions-api/create-session.md)를 확인하세요.

### 응답

`201 Created`:

```json theme={null}
{
  "session_id": "11111111-2222-3333-4444-555555555555",
  "session_number": 43762,
  "session_token": "3FaJ9wLqX2Mz",
  "url": "https://verify.didit.me/session/3FaJ9wLqX2Mz",
  "vendor_data": "user-123",
  "metadata": {
    "plan": "premium",
    "signup_source": "mobile-app"
  },
  "status": "Not Started",
  "workflow_id": "11111111-2222-3333-4444-555555555555",
  "workflow_version": 3,
  "callback": "https://yourapp.com/verification-complete"
}
```

### 주요 응답 필드

| 필드 | 설명 |
| - | - |
| `session_id` | 이 세션의 고유 UUID입니다. `GET /v3/session/{sessionId}/decision/` 요청과 웹훅에 사용합니다. |
| `session_number` | Didit 콘솔에 표시되는 사람이 읽을 수 있는 순번입니다. |
| `session_token` | 최종 사용자가 호스팅 플로우를 열 수 있도록 승인하고 네이티브 SDK를 초기화하는 12자 URL 안전 토큰입니다(웹 SDK는 대신 `url`을 사용합니다). 비밀 값으로 취급하세요. |
| `url` | 사용자를 리디렉션하거나 iframe에 삽입하는 데 사용할 호스팅 인증 페이지 URL입니다. (필드 이름은 `verification_url`이 아니라 `url`입니다.) 요청에 `language`가 포함되면 URL에 언어 경로 세그먼트가 포함됩니다(예: `https://verify.didit.me/en/session/3FaJ9wLqX2Mz`). |
| `status` | 현재 상태입니다. 새로 생성된 세션은 `"Not Started"`입니다. |
| `workflow_id` | 세션이 실행되는 고정 워크플로 식별자입니다. |
| `workflow_version` | 생성 시 세션에 고정된 게시된 워크플로 버전입니다. |

> [!NOTE]
>
> **멱등성.** `vendor_data`가 제공되었고, 같은 `vendor_data`를 가진 미완료 세션(`Not Started`, `In Progress`, `Resubmitted`, `Awaiting User` 중 하나)이 워크플로의 최신 게시 버전에 이미 있으면, 중복을 만들지 않고 그 기존 세션을 반환합니다(여전히 `201`). 이때 `callback`과 `metadata`는 새 값으로 업데이트되며, `status`는 기존 세션의 상태를 반영합니다.

> [!NOTE]
>
> **`x-api-key` 헤더가 없으면 `403`을 반환합니다.** 응답 본문은 `{"detail": "You do not have permission to perform this action."}`이며, 권한이 없는 유효한 키를 사용했을 때와 같습니다. 잘못되었거나, 폐기되었거나, 만료된 키는 `401`을 반환합니다. 크레딧이 부족하면 `400`을 반환합니다. 전체 문서는 [세션 생성 API 참조](https://docs.didit.me/ko/sessions-api/create-session.md)를 확인하세요.

***

## 4단계: 사용자에게 인증 플로우 제공

사용자에게 인증 플로우를 제공하는 방법을 선택하세요.

### 옵션 A: 네이티브 SDK (모바일에 권장)

카메라, NFC, 생체 인증 연동을 위해 `session_token`을 네이티브 SDK와 함께 사용합니다.

→ [iOS SDK](https://docs.didit.me/ko/integration/native-sdks/ios-sdk.md) · [Android SDK](https://docs.didit.me/ko/integration/native-sdks/android-sdk.md) · [React Native](https://docs.didit.me/ko/integration/native-sdks/react-native-sdk.md) · [Flutter](https://docs.didit.me/ko/integration/native-sdks/flutter-sdk.md)

### 옵션 B: InContext iframe (웹에 권장)

3단계에서 반환된 `url`을 사용해 페이지에 검증을 삽입합니다.

```html theme={null}
<iframe
  src="{url}"
  style="width: 100%; height: 700px; border: none;"
  allow="camera; microphone; geolocation; clipboard-write; fullscreen; autoplay; encrypted-media; digital-credentials-get"
></iframe>
```

→ [InContext iframe](https://docs.didit.me/ko/integration/web-sdks/incontext-iframe.md)

### 옵션 C: 리디렉션

사용자를 검증 URL로 리디렉션합니다.

```javascript theme={null}
window.location.href = session.url;
```

→ [웹 리디렉션](https://docs.didit.me/ko/integration/web-sdks/web-redirect.md)

### 옵션 D: 모바일 WebView

네이티브 SDK가 없는 모바일 앱용입니다.

```jsx theme={null}
// React Native
<WebView source={{ uri: session.url }} />
```

→ [iOS/Android의 WebView](https://docs.didit.me/ko/integration/web-sdks/webview-in-ios-android.md)

***

## 5단계: 결과 수신

### webhook 사용 (권장)

인증 상태가 변경되면 webhook이 서버에 실시간으로 알림을 보냅니다.

**설정:**

1. [콘솔](https://business.didit.me)(**API & Webhooks**)에서 webhook 대상을 생성하거나, `webhook_version: "v3"`와 `subscribed_events` 배열(예: `["status.updated"]`)을 포함하여 [`POST /v3/webhook/destinations/`](https://docs.didit.me/ko/management-api/webhook/create-destination)를 호출하십시오.
2. 생성 시 반환되는 `secret_shared_key`를 저장하십시오. 이 값은 모든 서명 변형에 사용되는 HMAC 비밀 키입니다.
3. 서버에 webhook endpoint를 구현하십시오.

**webhook payload 예시:**

`decision` 내부의 기능별 결과는 모두 **복수형 배열**(`id_verifications[]`, `nfc_verifications[]`, `liveness_checks[]`, `face_matches[]`, …)로 전달되며, 워크플로의 노드마다 항목이 하나씩 들어 있습니다. 이는 V3 계약이며 절대적으로 준수해야 합니다. 단수형 `nfc` / `id_verification` / `liveness` 키를 기준으로 코드를 작성하지 마십시오.

```json theme={null}
{
  "event_id": "9c0c8b8a-1111-4222-9333-444444444444",
  "webhook_type": "status.updated",
  "timestamp": 1774970000,
  "created_at": 1774969994,
  "application_id": "11111111-2222-3333-4444-555555555555",
  "environment": "live",
  "session_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "status": "Approved",
  "workflow_id": "22222222-3333-4444-5555-666666666666",
  "workflow_version": 4,
  "vendor_data": "user-123",
  "metadata": { "plan": "premium" },
  "decision": {
    "session_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
    "status": "Approved",
    "id_verifications": [
      { "node_id": "id_verification_1", "status": "Approved", "document_type": "Passport", "warnings": [] }
    ],
    "liveness_checks": [
      { "node_id": "liveness_1", "status": "Approved", "method": "PASSIVE", "score": 95.4, "warnings": [] }
    ],
    "face_matches": [
      { "node_id": "face_match_1", "status": "Approved", "score": 96.1, "warnings": [] }
    ],
    "reviews": []
  }
}
```

`decision` 객체는 `status`가 `Approved`, `Declined`, `In Review` 또는 `Abandoned`일 때만 존재합니다(`Resubmitted` 이벤트에는 `resubmit_info`가 포함됩니다). Didit은 재시도와 여러 전송 대상에 같은 `event_id`를 재사용하므로, 멱등성 처리의 기준으로 이 값을 사용하십시오. 모든 복수형 배열과 필드에 대해서는 [데이터 모델](https://docs.didit.me/ko/reference/data-models.md)을 참조하십시오.

**서명 검증(X-Signature-V2, 권장):**

`X-Signature-V2`는 JSON 본문을 정규형으로 다시 인코딩한 값에 대한 HMAC-SHA256입니다. 정수 값을 가진 실수는 정수로 줄이고, 키는 재귀적으로 정렬하며, 구분자는 압축 형식을 사용하고, 유니코드는 그대로 유지합니다.

```javascript theme={null}
const crypto = require("crypto");

// Match Didit's float normalisation: whole-valued floats serialise as ints.
function shortenFloats(data) {
  if (Array.isArray(data)) return data.map(shortenFloats);
  if (data !== null && typeof data === "object") {
    return Object.fromEntries(
      Object.entries(data).map(([key, value]) => [key, shortenFloats(value)])
    );
  }
  return data;
}

// Sort object keys recursively before re-stringifying.
function sortKeys(obj) {
  if (Array.isArray(obj)) return obj.map(sortKeys);
  if (obj !== null && typeof obj === "object") {
    return Object.keys(obj).sort().reduce((acc, key) => {
      acc[key] = sortKeys(obj[key]);
      return acc;
    }, {});
  }
  return obj;
}

function verifyWebhook(rawBody, signatureV2, timestamp, secret) {
  // 1. Reject anything older than 5 minutes
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - parseInt(timestamp, 10)) > 300) return false;

  // 2. Recompute HMAC-SHA256 against the canonical JSON Didit signs
  const canonical = JSON.stringify(sortKeys(shortenFloats(JSON.parse(rawBody))));
  const expected = crypto.createHmac("sha256", secret).update(canonical, "utf8").digest("hex");

  // 3. Constant-time compare
  const a = Buffer.from(expected, "utf8");
  const b = Buffer.from(signatureV2, "utf8");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
```

→ 원시 바이트 기반 `X-Signature`, 더 이상 권장되지 않는 엔벨로프 전용 `X-Signature-Simple`, 그리고 선택 방법을 포함한 [webhook 전체 문서](https://docs.didit.me/ko/integration/webhooks.md)를 확인하십시오.

Didit는 전송에 실패한 경우(`5xx`, `404`, 시간 초과) 최대 2회 재시도합니다(약 1분 후, 이후 약 4분 후). 응답 대기 시간은 **5초**이므로 `2xx` 응답을 빠르게 반환하십시오.

### API 사용 (선택 사항)

언제든지 같은 decision payload를 가져올 수 있습니다:

```bash theme={null}
curl https://verification.didit.me/v3/session/{session_id}/decision/ \
  -H "x-api-key: YOUR_API_KEY"
```

응답 구조(복수형 배열)는 webhook payload 내 `decision` 객체와 동일하며, 이 endpoint는 세션 수명 주기의 어느 시점에서든 호출할 수 있습니다. 실시간 업데이트에는 webhook을 사용하고, API 호출은 백필, 감사, 재구축 용도로만 사용하십시오. `/decision/` 엔드포인트는 API 키당 분당 GET 요청 600회로 속도가 제한됩니다([속도 제한](https://docs.didit.me/ko/integration/rate-limiting.md) 참조). 오류 동작은 다음과 같습니다. 알 수 없는 `session_id`는 `{"detail": "Not found."}`와 함께 `404`를 반환합니다. 인증 실패는 `403`으로 나타나며, 이 endpoint는 `401`을 반환하지 않습니다. 응답에 포함된 미디어 URL은 수명이 짧은 사전 서명 링크이므로, 저장하지 말고 즉시 가져오십시오.

→ [세션 조회 API 참조](https://docs.didit.me/ko/sessions-api/retrieve-session.md)

***

## 전체 코드 예제

### Node.js / Express

```javascript theme={null}
const express = require("express");
const crypto = require("crypto");
const app = express();

// Create verification session
app.post("/api/verify", async (req, res) => {
  const { userId } = req.body;

  const response = await fetch("https://verification.didit.me/v3/session/", {
    method: "POST",
    headers: {
      "x-api-key": process.env.DIDIT_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      workflow_id: process.env.DIDIT_WORKFLOW_ID,
      callback: `${process.env.APP_URL}/verification-complete`,
      vendor_data: userId,
    }),
  });

  const session = await response.json();

  // Store session_id associated with user
  await db.users.update({
    where: { id: userId },
    data: { verificationSessionId: session.session_id },
  });

  res.json({
    verificationUrl: session.url,             // hosted verification URL
    sessionToken: session.session_token,      // for native/web SDKs
  });
});

// Handle webhook — uses verifyWebhook / shortenFloats / sortKeys from Step 5
app.post(
  "/api/webhook",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const signature = req.get("X-Signature-V2");
    const timestamp = req.get("X-Timestamp");

    if (
      !verifyWebhook(
        req.body.toString("utf8"),
        signature,
        timestamp,
        process.env.DIDIT_WEBHOOK_SECRET,
      )
    ) {
      return res.status(401).json({ error: "Invalid signature" });
    }

    const payload = JSON.parse(req.body);
    const { event_id, session_id, status, vendor_data } = payload;

    // Idempotency: the same event_id is reused on retries and fan-out.
    // Skip events you have already processed (e.g. a processed_events table).

    // Update user's verification status (status values are case-sensitive strings)
    if (status === "Approved") {
      db.users.update({
        where: { id: vendor_data },
        data: { isVerified: true, verifiedAt: new Date() },
      });
    }

    // Return 2xx quickly (Didit's delivery timeout is 5s); do heavy work asynchronously
    res.json({ received: true });
  },
);

app.listen(3000);
```

### Python / FastAPI

```python theme={null}
from fastapi import FastAPI, Request, HTTPException
import httpx
import hashlib
import hmac
import json
import os
import time

app = FastAPI()

@app.post("/api/verify")
async def create_verification(user_id: str):
    async with httpx.AsyncClient() as client:
        response = await client.post(
            "https://verification.didit.me/v3/session/",
            headers={
                "x-api-key": os.environ["DIDIT_API_KEY"],
                "Content-Type": "application/json"
            },
            json={
                "workflow_id": os.environ["DIDIT_WORKFLOW_ID"],
                "callback": f"{os.environ['APP_URL']}/verification-complete",
                "vendor_data": user_id
            }
        )

    session = response.json()
    return {
        "verification_url": session["url"],            # hosted verification URL
        "session_token": session["session_token"],     # for native/web SDKs
    }

def shorten_floats(data):
    """Match Didit: whole-valued floats serialise as ints."""
    if isinstance(data, dict):
        return {k: shorten_floats(v) for k, v in data.items()}
    if isinstance(data, list):
        return [shorten_floats(x) for x in data]
    if isinstance(data, float) and data.is_integer():
        return int(data)
    return data

@app.post("/api/webhook")
async def handle_webhook(request: Request):
    payload = await request.json()
    signature = request.headers.get("X-Signature-V2")
    timestamp = request.headers.get("X-Timestamp")

    # Verify timestamp freshness
    if not signature or not timestamp or abs(int(time.time()) - int(timestamp)) > 300:
        raise HTTPException(status_code=401, detail="Request too old")

    # Recompute Didit's V2 canonical JSON: shortened floats, sorted keys,
    # compact separators, Unicode preserved (ensure_ascii=False)
    canonical = json.dumps(
        shorten_floats(payload),
        sort_keys=True,
        separators=(",", ":"),
        ensure_ascii=False,
    )
    expected = hmac.new(
        os.environ["DIDIT_WEBHOOK_SECRET"].encode("utf-8"),
        canonical.encode("utf-8"),
        hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(signature, expected):
        raise HTTPException(status_code=401, detail="Invalid signature")

    # Idempotency: dedupe on payload["event_id"] (reused on retries)

    if payload["status"] == "Approved":
        # Update user in database
        pass

    return {"received": True}
```

***

## 세션 상태

다음은 `status`의 가능한 10가지 값입니다. 대소문자를 구분하는 정확한 문자열이며, `Kyc Expired`는 대문자 `K`가 하나만 들어간다는 점에 유의하십시오.

| 상태 | 설명 |
| - | - |
| `Not Started` | 세션은 생성되었지만 사용자가 아직 링크를 열지 않았습니다. |
| `In Progress` | 사용자가 현재 인증을 진행 중입니다. |
| `In Review` | 인증이 수동 검토 대상으로 표시되었습니다. |
| `Approved` | 모든 검사를 통과했습니다. |
| `Declined` | 하나 이상의 검사에 실패했습니다. |
| `Resubmitted` | 검토자가 특정 단계를 다시 수행하도록 요청했습니다. |
| `Awaiting User` | KYB 상위 세션이 하위 KYC 당사자들이 완료하기를 기다리고 있습니다. |
| `Abandoned` | 사용자가 시작했지만 허용된 시간 안에 완료하지 않았습니다. |
| `Expired` | 사용자가 링크를 열기 전에 세션 시간이 초과되었습니다. |
| `Kyc Expired` | 이전에 승인된 세션으로, 문서가 만료일을 지났습니다. |

전체 수명 주기, 상태 전환 및 Mermaid 다이어그램은 [인증 상태](https://docs.didit.me/ko/integration/verification-statuses.md)를 참조하십시오.

***

## 다음 단계

1. **연동 방식 선택**:
   * 모바일 앱 → [네이티브 SDK](https://docs.didit.me/ko/integration/native-sdks/overview.md)
   * 웹 앱 → [웹 SDK](https://docs.didit.me/ko/integration/web-sdks/overview.md)
2. **webhook 구성**: [webhook](https://docs.didit.me/ko/integration/webhooks.md)
3. **용량 계획**: [속도 제한](https://docs.didit.me/ko/integration/rate-limiting.md)
4. **모든 상태 처리**: [인증 상태](https://docs.didit.me/ko/integration/verification-statuses.md)
5. **워크플로 사용자 지정**: [워크플로](https://docs.didit.me/ko/console/workflows.md)
6. **API 연결 확인**: [상태 확인](https://docs.didit.me/ko/api-reference/healthcheck.md)

## 도움이 필요하신가요?

* **지원**: [support@didit.me](mailto:support@didit.me)
* **프로그래밍 방식 온보딩**: [프로그래밍 방식 등록](https://docs.didit.me/ko/integration/programmatic-registration.md)


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