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

# 완전한 온보딩 가이드

> ARGOS ID check를 처음 도입하는 고객사를 위한 단계별 통합 가이드

# 완전한 ID check 온보딩 가이드

이 가이드는 **처음으로 ID check를 서비스에 도입하는 고객사 개발자**를 위해 작성되었습니다. 실제 통합 과정에서 맞닥뜨리는 고민들을 순서대로 짚어가며, 각 단계에서 ARGOS가 제공하는 기술을 안내합니다.

<Info>
  **사전 준비물**

  * ARGOS Identity 계정 ([idcheck.argosidentity.com](https://idcheck.argosidentity.com/) 가입)
  * 대시보드 접속 및 API 키 확인
</Info>

***

## ID check 통합의 핵심 원리

ID check를 시스템에 통합할 때, 가장 먼저 이해해야 할 내용이 있습니다.

<Warning>
  **ID check는 Liveform 기반의 서비스입니다.**

  사용자가 신원을 인증하는 과정(카메라로 신분증 촬영, 셀피 촬영, AI 검증)은 **ARGOS가 호스팅하는 Liveform**에서 이루어집니다. 고객사가 이 UI를 직접 구축하거나 대체할 수 없습니다.

  고객사가 해야 할 일은 단 하나입니다: **사용자를 Liveform URL로 보내는 것.**
</Warning>

**API의 역할:**

ID check의 API는 ARGOS 시스템으로 들어오고 나가는 정보의 안전한 전송을 위한 파이프라인 역할을 합니다. 주요 용도는 다음과 같습니다.

| 목적              | 관련 API                                 | 설명                                       |
| --------------- | -------------------------------------- | ---------------------------------------- |
| **Token 관리**    | POST/GET/DELETE Token                  | Private mode에서 일회용 URL 생성 및 관리           |
| **데이터 획득 및 관리** | GET/PATCH/DELETE Submission, GET Image | 검증 완료된 Submission 데이터 조회, 수정, 삭제, 이미지 조회 |
| **시스템 연결**      | POST Review, PUT Image                 | Pending 건 검수 처리, 이미지 추가/교체 등 워크플로우 연동    |
| **Migration**   | POST Submission                        | 기존 KYC 데이터 이전, 특수한 상황에서 데이터 삽입, 개발 테스트   |

***

## 목차

<CardGroup cols={3}>
  <Card title="파트 1: 기초" icon="1">
    계정 설정, 핵심 개념 이해
  </Card>

  <Card title="파트 2: 통합" icon="2">
    Liveform 연결, 결과 수신, 데이터 활용
  </Card>

  <Card title="파트 3: 운영" icon="3">
    보안 강화, 테스트, 라이브 전환
  </Card>
</CardGroup>

***

## 파트 1: 기초

### ARGOS ID check란?

ARGOS ID check는 **AI 기반 신원 인증 플랫폼**입니다. 사용자가 신분증을 촬영하고 셀피를 찍으면, AI가 문서 진위 여부를 분석하고 결과를 내려줍니다.

<CardGroup cols={2}>
  <Card title="문서 검증" icon="id-card">
    여권, 운전면허증, 국가 신분증, 거주 허가증 등 다양한 국가의 신분증을 검증합니다.
  </Card>

  <Card title="AI 사기 탐지" icon="shield-halved">
    위조, 사진 대체, 문서 변조를 AI로 자동 감지합니다.
  </Card>

  <Card title="데이터 추출" icon="database">
    신분증에서 이름, 생년월일, 국적 등의 정보를 자동 추출합니다.
  </Card>

  <Card title="KYC/AML 컴플라이언스" icon="scale-balanced">
    검증 규칙 커스터마이즈 및 감사 추적(Audit Trail)을 제공합니다.
  </Card>
</CardGroup>

***

### 계정 설정 및 필수 정보 확인

<Steps>
  <Step title="계정 만들기">
    [idcheck.argosidentity.com](https://idcheck.argosidentity.com/) 에서 가입하고 이메일을 인증한 뒤 대시보드에 로그인하세요.
  </Step>

  <Step title="필수 정보 확인">
    대시보드에서 아래 세 가지 정보를 확인하세요. 각 항목은 신규 대시보드의 **프로젝트 관리** 메뉴에서 확인할 수 있습니다.

    **1. Project ID (PID) 및 Liveform URL**

    **프로젝트 관리 → 프로젝트 설정 → 프로젝트 정보** 에서 확인합니다.

    * **Project ID (PID)** — 프로젝트 고유 식별자
    * **Liveform URL** — 사용자에게 제공할 신원 인증 페이지 URL (프로젝트 파이프라인 섹션)

    <Frame caption="프로젝트 정보 페이지에서 PID 및 Liveform URL 확인">
      <img src="https://mintcdn.com/argosidentity/IPUXz6Pq0_-rrbuX/images/dashboard/new/pj/project-setting/project-info/main.png?fit=max&auto=format&n=IPUXz6Pq0_-rrbuX&q=85&s=40ec8325672b2a525ede664f933f7a76" alt="프로젝트 정보 — PID 및 Liveform URL 확인" width="2048" height="571" data-path="images/dashboard/new/pj/project-setting/project-info/main.png" />
    </Frame>

    **2. API Key**

    **프로젝트 관리 → 프로젝트 설정 → 연동 정보** 에서 확인합니다.

    * **API Key** — API 요청 인증에 사용 (절대 외부에 노출하지 마세요)

    <Frame caption="연동 정보 페이지에서 API Key 확인">
      <img src="https://mintcdn.com/argosidentity/O8OeSMtlnaLv75Zo/images/dashboard/new/pj/project-setting/integration-info/api_key.png?fit=max&auto=format&n=O8OeSMtlnaLv75Zo&q=85&s=d5a76a82645fead42baa500edd087f54" alt="연동 정보 — API Key 확인" width="1686" height="137" data-path="images/dashboard/new/pj/project-setting/integration-info/api_key.png" />
    </Frame>

    ```
    API Key:      argos_live_abc123xyz...
    Project ID:   pid_abc123
    Liveform URL: https://form.argosidentity.com?pid=pid_abc123
    ```

    <Warning>
      **보안 주의**: API 키는 비밀번호처럼 관리하세요. 클라이언트 코드(프론트엔드)에 노출하거나 git에 커밋해서는 안 됩니다. 항상 서버 측 환경 변수에 저장하세요.
    </Warning>
  </Step>
</Steps>

***

### 핵심 개념

<AccordionGroup>
  <Accordion title="Submission (제출)" icon="file-lines">
    **Submission**은 단일 신원 인증 시도를 의미합니다. 사용자가 Liveform에서 신분증을 촬영하고 제출하면 Submission이 생성됩니다.

    **주요 속성:**

    * **Submission ID** — 고유 식별자 (예: `sub_abc123`)
    * **KYC 상태** — `approved` (승인), `rejected` (거절), `pending` (수동 심사 대기), `incomplete` (미완료 / 미제출)
    * **추출 데이터** — 이름, 생년월일, 국적 등
    * **이미지** — 신분증 사진과 셀피
    * **메타데이터** — 타임스탬프, IP, 고객사가 전달한 userid/email 등

    **Submission 상태 흐름:**

    ```
    (사용자가 Liveform 접속/작성) → Incomplete (제출 전 / 미완료)
                                  → 제출 후 심사 → Approved | Rejected | Pending
    ```

    `Created`는 KYC 상태가 아니라 웹훅 트리거 이름입니다. 공식 KYC 상태 enum은 `Approved`, `Rejected`, `Pending`, `Incomplete` 네 가지입니다.
  </Accordion>

  <Accordion title="Liveform" icon="browser">
    **Liveform**은 ARGOS가 호스팅하는 신원 인증 페이지입니다. 고객사는 이 URL을 사용자에게 제공하기만 하면 됩니다.

    * **데스크톱**: QR 코드를 표시하여 모바일로 스캔 유도
    * **모바일**: 바로 카메라 인터페이스로 진행

    **기본 URL 구조:**

    ```
    https://form.argosidentity.com?pid={project_id}
    ```

    쿼리 스트링 파라미터를 추가하여 사용자 정보 전달, 국가 제한, 보안 옵션 등을 커스터마이즈할 수 있습니다.
  </Accordion>

  <Accordion title="Webhook (웹훅)" icon="webhook">
    **웹훅**은 검증 이벤트가 발생할 때 고객사 서버로 실시간 HTTP POST 요청을 보내는 기능입니다. 운영 환경에서 검증 결과를 받는 **가장 권장되는 방법**입니다.

    **주요 이벤트:**

    * `approved` — 검증 승인
    * `rejected` — 검증 거절
    * `submit` — 보류(pending) 상태로 제출
    * `updated` — 데이터 업데이트
    * `delete` — Submission 삭제
    * `created` — Submission 생성
    * `retry` — 사용자 재시도
    * `token_expired` — Token 만료
    * `injection` — API를 통한 데이터 주입
    * `aml` — AML 검사 완료
    * `aml_monitor` — AML 온고잉 모니터링 결과

    웹훅 URL은 **프로젝트 관리 → 프로젝트 설정 → 연동 정보**에서 등록합니다.
  </Accordion>

  <Accordion title="Token (토큰) — Private Mode" icon="key">
    **Token**을 사용하면 Liveform URL을 일회용으로 만들 수 있습니다 (Private Mode).

    **용도:**

    * 동일한 URL이 여러 사람에게 공유되는 것 방지
    * 특정 사용자에게만 유효한 인증 링크 제공
    * 보안이 중요한 서비스(금융, 의료 등)에서 사용

    **작동 방식:**

    * 서버에서 고유한 tokenId를 생성하여 ARGOS에 등록
    * `token` 파라미터를 Liveform URL에 추가하여 사용자에게 전달
    * 최초 사용 후 3분 또는 제출이 결정 상태에 도달하면 만료
  </Accordion>

  <Accordion title="Return URL" icon="arrow-turn-down-right">
    **Return URL**은 사용자가 인증을 완료하고 "OK" 버튼을 누르거나 5초 후, 고객사 앱으로 돌아올 URL입니다.

    대시보드에서 설정하며, KYC 상태(`kycStatus`), 이메일, userid, 커스텀 필드 등이 쿼리 파라미터로 함께 전달됩니다.

    **예시:**

    ```
    https://yourapp.com/verification-complete?kycStatus=approved&userid=user123&email=user@example.com
    ```

    <Info>
      Return URL은 사용자 경험(UX) 흐름을 위한 것입니다. 검증 결과의 공식 수신 채널로는 **웹훅**을 사용하세요.
    </Info>
  </Accordion>

  <Accordion title="쿼리 스트링 및 암호화" icon="lock">
    **쿼리 스트링**으로 Liveform 동작을 커스터마이즈할 수 있습니다:

    * `email`, `userid`, `cf1`\~`cf3` — 사용자 정보 미리 입력
    * `blacklistCountries=false`, `ageLimit=false` — 정책 일시 해제

    **보안이 필요한 파라미터는 반드시 암호화**해야 합니다:

    * `allowedCountries` — 허용 국가 제한
    * `allowedIdTypes` — 허용 문서 유형 제한
    * `selectedIssuingCountry`, `selectedIdType` — 선택 화면 건너뛰기
    * `token` — Private mode 토큰

    **암호화 모듈:**

    * **AES-256-ECB** — 빠르고 간단한 블록 암호화 방식
    * **AES-256-GCM** — 인증 및 무결성 기능을 포함한 강화된 암호화 방식

    **암호화 키:**

    * **API 키** — 프로젝트에 부여된 기본 API 키
    * **Custom secretKey** — 대시보드에서 별도로 발급받아 사용하는 전용 키 (발급 후 한 번만 표시되므로 분실 시 재발급 필요)

    대시보드의 **쿼리스트링 암복호화 툴**(**프로젝트 관리 → 프로젝트 설정 → 프로젝트 정보**)로 코드 없이 직접 암호화된 URL을 생성하고 테스트할 수 있습니다.

    더 알아보기: [쿼리 스트링 및 토큰 가이드](/ko/idcheck/getting-started/liveform-url/querystring-and-token-guide) | [암호화 가이드](/ko/idcheck/getting-started/encrypt-and-decrypt-data/overview)
  </Accordion>
</AccordionGroup>

***

## 파트 2: 통합

고객사 개발자가 실제로 직면하는 고민들을 단계별로 해결합니다.

***

### Q1. "어떻게 내 앱에서 사용자에게 신원 인증을 시키나?"

**답: Liveform URL을 사용자에게 전달하세요.**

대시보드에서 Liveform URL을 복사하여 버튼 링크, 리디렉션, 이메일 링크 등 어떤 방식으로든 사용자에게 전달하면 됩니다.

<Steps>
  <Step title="Liveform URL 확인">
    대시보드 **프로젝트 관리 → 프로젝트 설정 → 프로젝트 정보** 의 프로젝트 파이프라인 섹션에서 Liveform URL을 복사하세요:

    ```
    https://form.argosidentity.com?pid={your_project_id}
    ```
  </Step>

  <Step title="앱에서 사용자에게 전달">
    **웹앱 — 링크 버튼:**

    ```html theme={null}
    <a href="https://form.argosidentity.com?pid={your_pid}" target="_blank">
      신원 인증하기
    </a>
    ```

    **모바일 앱 — 외부 브라우저 열기:**

    ```javascript theme={null}
    // React Native 예시
    import { Linking } from 'react-native';

    const startVerification = () => {
      Linking.openURL('https://form.argosidentity.com?pid={your_pid}');
    };
    ```

    **백엔드에서 리디렉션:**

    ```javascript theme={null}
    // Node.js Express 예시
    app.get('/verify', (req, res) => {
      res.redirect('https://form.argosidentity.com?pid={your_pid}');
    });
    ```
  </Step>

  <Step title="기본 플로우 확인">
    브라우저에서 URL을 직접 열어 기본 검증 플로우를 테스트하세요.

    <div style={{ display: 'flex', gap: '1rem', alignItems: 'flex-start', flexWrap: 'wrap' }}>
      <div style={{ flex: 4, minWidth: '280px' }}>
        <Frame>
          <img src="https://mintcdn.com/argosidentity/VXdwPNlYPp7G6zXO/images/liveform/liveForm_pc.png?fit=max&auto=format&n=VXdwPNlYPp7G6zXO&q=85&s=50b9e176f461f0303e1221e745bba8e3" alt="Liveform Interface from pc" style={{ width: 'auto', height: '30', objectFit: 'contain' }} width="1917" height="993" data-path="images/liveform/liveForm_pc.png" />
        </Frame>
      </div>

      <div style={{ flex: 1, minWidth: '10' }}>
        <Frame>
          <img src="https://mintcdn.com/argosidentity/VXdwPNlYPp7G6zXO/images/liveform/liveForm_mobile.png?fit=max&auto=format&n=VXdwPNlYPp7G6zXO&q=85&s=d0c4a0f86e72d735b58f716e7f00d998" alt="Liveform Interface from mobile" style={{ width: 'auto', height: '40', objectFit: 'contain' }} width="411" height="907" data-path="images/liveform/liveForm_mobile.png" />
        </Frame>
      </div>
    </div>

    * **데스크톱**: QR 코드가 표시되며, 모바일로 스캔하여 계속 진행
    * **모바일**: 바로 카메라 인터페이스로 진행
  </Step>
</Steps>

***

### Q2. "내 서비스의 사용자 정보를 미리 전달할 수 있나?"

**답: 쿼리 스트링 파라미터를 URL에 추가하세요.**

사용자가 이미 회원 가입을 한 상태라면, 이메일·사용자 ID 등을 미리 넣어주면 사용자가 Liveform에서 다시 입력하지 않아도 됩니다. 또한 이 값들은 Submission 데이터와 함께 저장되어 나중에 웹훅이나 GET Submission API로 조회할 때 활용할 수 있습니다.

**주요 파라미터:**

| 파라미터                | 설명                            | 예시                 |
| ------------------- | ----------------------------- | ------------------ |
| `email`             | 사용자 이메일                       | `user@example.com` |
| `userid`            | 내부 사용자 ID                     | `user_12345`       |
| `cf1`, `cf2`, `cf3` | 커스텀 메타데이터 (예: 캠페인 ID, 서비스 구분) | `campaign_summer`  |
| `sid`               | Submission ID (업데이트 시 사용)     | `sub_abc123`       |

**예시 URL:**

```javascript theme={null}
const email = encodeURIComponent("user@example.com");
const userid = "user_12345";
const liveformUrl = `https://form.argosidentity.com?pid={your_pid}&email=${email}&userid=${userid}&cf1=campaign_summer`;
```

<Tip>
  `userid`에 내부 시스템의 사용자 ID를 넣어두면, 나중에 웹훅이나 GET Submission API에서 이 값으로 해당 사용자의 인증 결과를 바로 찾을 수 있습니다.
</Tip>

***

### Q3. "URL이 여러 사람에게 공유되는 게 우려된다"

**답: Token을 등록하여 Private Mode (일회용 URL)를 사용하세요.**

Token을 Liveform URL에 추가하면, 해당 URL은 일회용이 됩니다. 최초 사용 후 3분이 지나거나 인증이 완료되면 더 이상 사용할 수 없습니다.

<Steps>
  <Step title="서버에서 고유 tokenId 생성 후 ARGOS에 등록">
    ```bash theme={null}
    curl -X POST 'https://rest-api.argosidentity.com/v3/submission/tokens' \
      -H 'x-api-key: YOUR_API_KEY' \
      -H 'Content-Type: text/plain' \
      -d '{"tokenId": ["user-session-001", "user-session-002"]}'
    ```

    **응답:**

    ```json theme={null}
    {
      "success": true,
      "message": "All tokens are now in the pool",
      "summary": {
        "totalSubmitted": 2,
        "currentCount": 2
      }
    }
    ```

    <Warning>
      Token 등록 API는 반드시 **서버 측에서만** 호출하세요. API 키가 포함되므로 클라이언트(프론트엔드)에서 직접 호출해서는 안 됩니다.
    </Warning>
  </Step>

  <Step title="Token이 포함된 Liveform URL을 사용자에게 전달">
    ```javascript theme={null}
    const tokenId = "user-session-001";
    const secureUrl = `https://form.argosidentity.com?pid={your_pid}&token=${tokenId}`;

    // 이메일, SMS 등을 통해 사용자에게 전달
    sendEmail(userEmail, `인증 링크: ${secureUrl}`);
    ```
  </Step>

  <Step title="Token 만료 처리">
    Token은 다음 경우에 무효화됩니다:

    * 최초 사용 후 **3분** 경과
    * 해당 Token으로 Submission이 결정 상태(승인/거절/보류)에 도달

    Token이 만료되면 사용자에게 새로운 Token을 생성하여 전달하세요.

    **Token 관련 제한사항:**

    * 프로젝트당 최대 **100,000개** Token 보관 가능
    * API 요청당 최대 **500개** Token 등록 가능
    * Token ID 형식: 8–64자, 영숫자 + `-_.`
  </Step>
</Steps>

더 알아보기: [POST Token API](/ko/idcheck/api-reference/api-reference-guide/post-token) | [쿼리 스트링 및 토큰 가이드](/ko/idcheck/getting-started/liveform-url/querystring-and-token-guide)

***

### Q4. "특정 국가 또는 문서 유형만 허용하고 싶다"

**답: 암호화된 쿼리 스트링 파라미터를 사용하세요.**

`allowedCountries`, `allowedIdTypes` 등 보안이 필요한 파라미터는 암호화하여 `encrypted` 파라미터에 담아야 합니다. 암호화 모듈은 **AES-256-ECB** 또는 **AES-256-GCM** 중 선택할 수 있으며, 암호화 키는 프로젝트 **API 키** 또는 대시보드에서 별도 발급한 **Custom secretKey**를 사용할 수 있습니다.

<Tip>
  **대시보드에서 바로 암호화된 URL 만들기**

  코드 없이 암호화된 Liveform URL을 생성하고 테스트하려면 대시보드의 **쿼리스트링 암복호화 툴**을 활용하세요.

  → **프로젝트 관리 → 프로젝트 설정 → 프로젝트 정보 → 쿼리스트링 암복호화 툴**

  암호화할 파라미터를 입력하면 암호화된 URL이 자동 생성되며, 기존 암호화된 URL을 복호화하여 포함된 파라미터를 확인할 수도 있습니다.
</Tip>

<Frame caption="쿼리스트링 암복호화 툴">
  <img src="https://mintcdn.com/argosidentity/IPUXz6Pq0_-rrbuX/images/dashboard/new/pj/project-setting/project-info/encryption_tool.png?fit=max&auto=format&n=IPUXz6Pq0_-rrbuX&q=85&s=6f4a93f3ff8e727ea7638491c218881e" alt="쿼리스트링 암복호화 툴 화면" width="1631" height="859" data-path="images/dashboard/new/pj/project-setting/project-info/encryption_tool.png" />
</Frame>

**코드로 암호화하는 방법:**

```javascript theme={null}
const CryptoJS = require('crypto-js');

function encryptQueryParams(data, apiKey) {
  const hashedKey = CryptoJS.SHA256(apiKey);
  const key = CryptoJS.lib.WordArray.create(hashedKey.words.slice(0, 8), 32);
  const encrypted = CryptoJS.AES.encrypt(
    JSON.stringify(data),
    key,
    { mode: CryptoJS.mode.ECB }
  );
  return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}

// 예시 1: 허용 국가 및 문서 유형 제한
const config1 = {
  allowedCountries: "USA,KOR,JPN",        // ISO Alpha-3 코드
  allowedIdTypes: "passport,drivers_license"
};

// 예시 2: 국가 및 문서 유형 미리 선택 (선택 화면 건너뛰기)
const config2 = {
  selectedIssuingCountry: "KOR",
  selectedIdType: "drivers_license"
};

const encrypted = encryptQueryParams(config1, YOUR_API_KEY);
const liveformUrl = `https://form.argosidentity.com?pid={your_pid}&encrypted=${encodeURIComponent(encrypted)}`;
```

**암호화가 필요한 파라미터:**

| 파라미터                              | 설명                                                         |
| --------------------------------- | ---------------------------------------------------------- |
| `allowedCountries`                | 허용할 국가 (ISO Alpha-3 코드, 쉼표 구분)                             |
| `allowedIdTypes`                  | 허용할 문서 유형                                                  |
| `selectedIssuingCountry`          | 국가 선택 화면을 건너뛰고 지정                                          |
| `selectedIdType`                  | 문서 유형 선택 화면을 건너뛰고 지정 (반드시 `selectedIssuingCountry`와 함께 사용) |
| `projectionId` / `projectionName` | 특정 필드를 제외하는 Projection 적용                                  |
| `auxidField`                      | 추가 신원 검증 (예: 전화번호 SMS 인증)                                  |

<Warning>
  `selectedIdType`은 반드시 `selectedIssuingCountry`와 함께 사용해야 합니다. 단독 사용 시 오류가 발생합니다.
</Warning>

더 알아보기: [쿼리 스트링 및 토큰 가이드](/ko/idcheck/getting-started/liveform-url/querystring-and-token-guide)

***

### Q5. "인증 완료 후 사용자를 내 앱으로 돌려보내고 싶다"

**답: 대시보드에서 Return URL을 설정하세요.**

사용자가 인증을 마치고 "OK"를 누르면 설정한 URL로 리디렉션됩니다. KYC 결과가 쿼리 파라미터로 함께 전달됩니다.

<Steps>
  <Step title="대시보드에서 Return URL 설정">
    **프로젝트 관리 → 프로젝트 설정 → 연동 정보**에서 Return URL을 입력하세요:

    <Frame caption="리턴 URL 설정">
      <img src="https://mintcdn.com/argosidentity/bSOR6O7Y3jW8lg8K/images/dashboard/new/pj/project-setting/integration-info/return_url.png?fit=max&auto=format&n=bSOR6O7Y3jW8lg8K&q=85&s=3ad886f9c3f9f7164be808099cb4f9fe" alt="리턴 URL 설정 화면" width="779" height="470" data-path="images/dashboard/new/pj/project-setting/integration-info/return_url.png" />
    </Frame>

    ```
    https://yourapp.com/verification-complete
    ```
  </Step>

  <Step title="리디렉션 결과 처리">
    사용자는 아래와 같은 파라미터와 함께 리디렉션됩니다:

    ```
    https://yourapp.com/verification-complete?kycStatus=approved&userid=user123&email=user@example.com&cf1=campaign_summer
    ```

    **전달되는 파라미터:**

    * `kycStatus` — `approved`, `rejected`, `pending`
    * `userid` — Liveform URL에 전달했던 사용자 ID
    * `email` — 사용자 이메일
    * `cf1`, `cf2`, `cf3` — 커스텀 필드

    ```javascript theme={null}
    // Express.js 예시
    app.get('/verification-complete', async (req, res) => {
      const { userid, kycStatus } = req.query;

      if (kycStatus === 'approved') {
        await updateUser(userid, { verified: true });
        res.render('verification-success');
      } else if (kycStatus === 'pending') {
        res.render('verification-pending');
      } else {
        res.render('verification-rejected');
      }
    });
    ```
  </Step>
</Steps>

<Warning>
  Return URL로 전달되는 `kycStatus`는 사용자 경험(UX) 화면 전환용입니다. 검증 결과를 데이터베이스에 기록하거나 내부 시스템에 반영하는 공식 채널로는 **웹훅**을 사용하는 것을 권장합니다. Return URL 파라미터는 변조될 수 있습니다.
</Warning>

더 알아보기: [Return URL 가이드](/ko/idcheck/getting-started/liveform-url/return-url-guide)

***

### Q6. "인증 결과를 실시간으로 서버에서 받고 싶다"

**답: 웹훅(Webhook)을 설정하세요.**

웹훅은 인증 이벤트가 발생할 때 고객사 서버로 즉시 HTTP POST 요청을 보내는 기능입니다. 이 방법이 인증 결과를 수신하는 **가장 안정적이고 권장되는 방법**입니다.

<Steps>
  <Step title="웹훅 엔드포인트 생성">
    POST 요청을 받을 HTTPS 엔드포인트를 서버에 만드세요:

    ```javascript theme={null}
    // Node.js Express 예시
    const express = require('express');
    const app = express();
    app.use(express.json());

    app.post('/webhooks/idcheck', async (req, res) => {
      const event = req.body;

      // 이벤트 유형에 따라 처리
      switch (event.webhook_trigger) {
        case 'approved':
          // 사용자 검증 완료 처리
          await db.users.update({ id: event.userid, verified: true });
          break;

        case 'rejected':
          // 검증 거절 처리
          await db.users.update({ id: event.userid, verified: false });
          break;

        case 'submit':
          // 수동 심사 대기 처리
          await notifyAdmin(`${event.userid} 수동 심사 필요`);
          break;
      }

      // 수신 즉시 200 응답 반환 (ARGOS 웹훅은 단발성, 재전송 없음)
      res.status(200).json({ received: true });
    });
    ```

    <Warning>
      **중요한 웹훅 구현 원칙:**

      * ARGOS는 이벤트 발생 후 **통상 5초 이내**에 웹훅을 전송합니다. 웹훅은 단발성(one-way) 알림이며, 전송 실패 시 자동 재전송되지 않습니다. 수신 누락에 대비해 GET Submission API 보완 조회를 고려하세요.
      * 수신 즉시 200 OK를 반환하고, 무거운 처리 로직은 비동기로 실행하세요.
      * 동일한 Submission ID로 동일 트리거 웹훅이 다시 발생할 수 있으므로(예: `updated` 이벤트) **멱등성(idempotency)** 처리를 구현하세요.
    </Warning>
  </Step>

  <Step title="대시보드에서 웹훅 URL 등록">
    **프로젝트 관리 → 프로젝트 설정 → 연동 정보**의 **웹훅 설정** 섹션에서 엔드포인트 URL을 입력하세요:

    ```
    https://yourapp.com/webhooks/idcheck
    ```

    <Frame caption="웹훅 URL 설정">
      <img src="https://mintcdn.com/argosidentity/O8OeSMtlnaLv75Zo/images/dashboard/new/pj/project-setting/integration-info/webhook-setting.png?fit=max&auto=format&n=O8OeSMtlnaLv75Zo&q=85&s=1a3cb0514cbaab8b1d426a49506f1abd" alt="웹훅 설정 화면" width="1688" height="1014" data-path="images/dashboard/new/pj/project-setting/integration-info/webhook-setting.png" />
    </Frame>

    <Info>
      웹훅 URL은 반드시 **HTTPS**를 사용해야 합니다. 로컬 개발 시에는 [ngrok](https://ngrok.com/) 또는 [webhook.site](https://webhook.site)를 사용하여 테스트하세요.
    </Info>
  </Step>

  <Step title="웹훅 이벤트 확인">
    **전체 이벤트 유형:**

    | 이벤트             | 설명                        | 활용 예시                  |
    | --------------- | ------------------------- | ---------------------- |
    | `approved`      | 검증 승인                     | 사용자 상태 업데이트, 서비스 이용 허가 |
    | `rejected`      | 검증 거절                     | 사용자 알림, 재제출 요청         |
    | `submit`        | 보류(pending) 상태            | 관리자 알림, 수동 심사 요청       |
    | `updated`       | 데이터 업데이트                  | DB 동기화                 |
    | `delete`        | Submission 삭제             | 관련 데이터 정리              |
    | `created`       | Submission 생성             | 인증 시작 추적               |
    | `retry`         | 사용자 재시도                   | 재시도 패턴 모니터링            |
    | `token_expired` | Token 만료                  | 새 Token 발급             |
    | `injection`     | API를 통한 데이터 주입(Injection) | API 작업 로깅              |
    | `aml`           | AML 검사 완료                 | 컴플라이언스 결과 처리           |
    | `aml_monitor`   | AML 온고잉 모니터링 결과           | 지속적 모니터링 처리            |

    더 알아보기: [웹훅 이벤트 상세 가이드](/ko/idcheck/webhooks/overview)
  </Step>
</Steps>

***

### Q7. "인증 데이터를 우리 DB/시스템과 연동하고 싶다"

**답: GET Submission API로 검증 데이터를 조회하세요.**

웹훅으로 실시간 수신도 가능하지만, 필요한 시점에 직접 특정 Submission의 데이터를 조회하고 싶을 때 GET Submission API를 사용합니다.

```bash theme={null}
# Submission ID로 단일 조회
curl -X GET 'https://rest-api.argosidentity.com/v3/submission?submission_id={submission_id}' \
  -H 'x-api-key: YOUR_API_KEY'

# 사용자 ID로 조회
curl -X GET 'https://rest-api.argosidentity.com/v3/submission?userid={userid}' \
  -H 'x-api-key: YOUR_API_KEY'

# 이메일로 조회
curl -X GET 'https://rest-api.argosidentity.com/v3/submission?email={email}' \
  -H 'x-api-key: YOUR_API_KEY'

# 전체 목록 조회 (페이지네이션)
curl -X GET 'https://rest-api.argosidentity.com/v3/submission?count=50' \
  -H 'x-api-key: YOUR_API_KEY'
```

**조회 파라미터:**

| 파라미터                      | 설명                                             |
| ------------------------- | ---------------------------------------------- |
| `submission_id`           | 특정 제출 건의 고유 ID로 단일 조회                          |
| `userid`                  | 사용자 ID와 일치하는 모든 제출 건 조회                        |
| `email`                   | 이메일과 일치하는 모든 제출 건 조회                           |
| `count`                   | 반환할 결과 수 (기본값: 50)                             |
| `start_date` / `end_date` | 조회 기간 필터 (YYYY-MM-DD)                          |
| `request_type`            | 특정 데이터 유형만 조회 (`kyc`, `aml`, `data`, `others`) |

**응답 예시:**

```json theme={null}
{
  "Items": [
    {
      "data": {
        "full_name": "John Doe",
        "gender": "male",
        "nationality": "USA",
        "date_of_birth": "1990-01-01",
        "idType": "passport",
        "idcard_issuingCountry": "USA",
        "cf1": "campaign_summer"
      },
      "email": "user@example.com",
      "submission_id": "sub_abc123",
      "userid": "user_12345",
      "created_at": "2024-01-15-10-30-00-000",
      "kyc": {
        "result": "approved",
        "comment": [],
        "commentCode": []
      },
      "image": {
        "idImage": "{idImage URL}",
        "selfieImage": "{selfieImage URL}"
      }
    }
  ]
}
```

**기타 데이터 관리 및 시스템 연결 API:**

| API                          | 용도                                                |
| ---------------------------- | ------------------------------------------------- |
| `PATCH /submission`          | Submission 데이터 수정 (kycStatus, fullName, email 등)  |
| `DELETE /submission`         | Submission 전체 삭제 (GDPR 등 개인정보 삭제 요청 대응)           |
| `DELETE /submission/partial` | 이미지만 삭제 (메타데이터 유지)                                |
| `GET /image`                 | Submission에 저장된 이미지(신분증, 셀피 등) 조회                 |
| `PUT /image`                 | 기존 Submission에 이미지 추가 또는 교체 (Base64 인코딩)          |
| `POST /submission/review`    | Pending 상태의 Submission을 API로 승인/거절 처리 (수동 심사 자동화) |

<Info>
  `POST /submission/review` 는 프로젝트 설정에서 검토자가 'Client'로 설정된 경우, 고객사가 API를 통해 직접 pending 건을 심사할 수 있게 해줍니다. 이미 승인/거절된 건은 수정할 수 없습니다.
</Info>

더 알아보기: [GET Submission API](/ko/idcheck/api-reference/api-reference-guide/get-submission) | [REVIEW API](/ko/idcheck/api-reference/api-reference-guide/post-client-review)

***

### Q8. "기존에 보유한 KYC 데이터를 ARGOS에 이전하고 싶다"

**답: POST Submission API (Migration)를 사용하세요.**

이 API는 다음과 같은 상황에서 사용합니다:

* **데이터 마이그레이션**: 기존 시스템의 KYC 완료 데이터를 ARGOS 대시보드로 이전
* **특수한 상황**: ID Check 검증을 거치기 어려운 예외적 케이스에서 직접 데이터 삽입
* **개발 및 테스트**: 개발 단계에서 다양한 시나리오를 테스트할 때 활용

<Warning>
  이 API를 통해 생성된 Submission은 **ARGOS의 표준 검증 절차(AI 검증)를 거치지 않습니다.** 제출된 데이터의 정확성과 유효성에 대한 책임은 전적으로 고객사에게 있습니다.

  일반적인 신규 사용자의 신원 인증은 반드시 **Liveform**을 통해 진행해야 합니다.
</Warning>

```bash theme={null}
curl -X POST 'https://rest-api.argosidentity.com/v3/submission/migration' \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: YOUR_API_KEY' \
  -d '{
    "admin": "admin@yourcompany.com",
    "email": "user@example.com",
    "fullName": "John Doe",
    "birthDate": "1990-01-01",
    "kycStatus": "approved",
    "idType": "passport",
    "issuingCountry": "USA",
    "nationality": "USA",
    "gender": "male",
    "userid": "user_12345"
  }'
```

**필수 필드:**

| 필드          | 설명                              |
| ----------- | ------------------------------- |
| `admin`     | 프로젝트 관리자 이메일 (대시보드에 등록되어 있어야 함) |
| `email`     | KYC 제출자의 이메일 주소                 |
| `fullName`  | 제출자의 전체 이름                      |
| `birthDate` | 생년월일 (YYYY-MM-DD)               |
| `kycStatus` | `approved` 또는 `rejected`        |

**선택 필드:** `idType`, `issuingCountry`, `nationality`, `gender`, `issueDate`, `expireDate`, `identityNumber`, `documentNumber`, `userid`, `cf1`\~`cf3` 등

**주의사항:**

* 문자열 데이터만 지원합니다. 이미지 데이터는 별도로 [PUT Image API](/ko/idcheck/api-reference/api-reference-guide/put-image)를 사용하세요.
* 보안 강화를 위해 요청 본문을 AES-256-ECB로 암호화하여 전송할 수 있습니다.

더 알아보기: [POST Submission API](/ko/idcheck/api-reference/api-reference-guide/post-submission)

***

## 파트 3: 운영 배포

### 보안 강화

운영 환경 배포 전 아래 보안 설정을 완료하세요.

<AccordionGroup>
  <Accordion title="1. API 키 안전하게 관리" icon="key">
    API 키는 절대 클라이언트 코드(프론트엔드)나 git에 노출되어서는 안 됩니다.

    **환경 변수 사용 (필수):**

    ```bash theme={null}
    # .env 파일
    ARGOS_API_KEY=argos_live_abc123xyz...
    ARGOS_PROJECT_ID=pid_abc123
    ```

    ```javascript theme={null}
    // Node.js에서 로드
    require('dotenv').config();
    const apiKey = process.env.ARGOS_API_KEY;
    ```

    **백엔드 프록시 패턴 (권장):**

    ```javascript theme={null}
    // ❌ 프론트엔드에서 직접 ARGOS API 호출 — 절대 금지
    // fetch('https://rest-api.argosidentity.com/...', { headers: { 'x-api-key': '...' } })

    // ✅ 프론트엔드는 자체 백엔드 API만 호출
    // 백엔드 서버에서 ARGOS API 호출 후 결과 전달
    app.post('/api/start-verification', authenticateUser, async (req, res) => {
      const tokenId = `session-${req.user.id}-${Date.now()}`;

      // 서버 측에서만 ARGOS API 호출
      await fetch('https://rest-api.argosidentity.com/v3/submission/tokens', {
        method: 'POST',
        headers: { 'x-api-key': process.env.ARGOS_API_KEY, 'Content-Type': 'text/plain' },
        body: JSON.stringify({ tokenId: [tokenId] })
      });

      const liveformUrl = `https://form.argosidentity.com?pid=${process.env.ARGOS_PROJECT_ID}&token=${tokenId}`;
      res.json({ liveformUrl });
    });
    ```

    `.gitignore`에 반드시 추가하세요:

    ```
    .env
    .env.local
    .env.production
    ```
  </Accordion>

  <Accordion title="2. IP 화이트리스트 설정" icon="shield-check">
    ARGOS API를 호출하는 서버 IP를 화이트리스트에 등록하면 허가되지 않은 IP에서의 API 접근이 차단됩니다(403).

    **프로젝트 관리 → 프로젝트 설정 → 시스템 운영 → IP 화이트리스트 관리**에서 서버 IP를 등록하세요:

    <Frame caption="IP 화이트리스트 관리">
      <img src="https://mintcdn.com/argosidentity/O8OeSMtlnaLv75Zo/images/dashboard/new/pj/project-setting/system-operation/ip_whitelist.png?fit=max&auto=format&n=O8OeSMtlnaLv75Zo&q=85&s=246d02aa77850b1614e0452500d0886a" alt="IP 화이트리스트 관리 화면" width="1129" height="304" data-path="images/dashboard/new/pj/project-setting/system-operation/ip_whitelist.png" />
    </Frame>

    ```
    52.12.34.56
    52.12.34.57
    ```

    <Warning>
      API를 호출하는 **모든** 서버 IP를 등록해야 합니다: 운영 서버, 스테이징 서버, CI/CD 파이프라인 IP 등.
    </Warning>
  </Accordion>

  <Accordion title="3. 웹훅 데이터 암호화 활성화" icon="lock">
    웹훅으로 전송되는 민감한 KYC 데이터를 암호화할 수 있습니다.

    **프로젝트 관리 → 보안설정 → 데이터 보호**에서 \*\*"안전한 데이터 전송"\*\*을 **ON**으로 설정하세요.

    <Frame caption="보안 전송 설정">
      <img src="https://mintcdn.com/argosidentity/352WpTnZFyEfW7I6/images/dashboard/new/data_protection/secure_data_transfer.png?fit=max&auto=format&n=352WpTnZFyEfW7I6&q=85&s=cedeafc03cbd672531f76091fc3e6786" alt="보안 데이터 전송 설정" width="2246" height="227" data-path="images/dashboard/new/data_protection/secure_data_transfer.png" />
    </Frame>

    활성화하면 웹훅 페이로드가 아래 형식으로 암호화되어 전달됩니다:

    ```json theme={null}
    {
      "response": {
        "body": "encrypted-string"
      }
    }
    ```

    **복호화 방법 (AES-256-CBC):**

    ```javascript theme={null}
    const CryptoJS = require('crypto-js');

    function decryptWebhook(encryptedData, apiKey) {
      const hashedKey = CryptoJS.SHA256(apiKey);
      const key = CryptoJS.lib.WordArray.create(hashedKey.words.slice(0, 8), 32);
      const iv = CryptoJS.lib.WordArray.create(hashedKey.words.slice(8, 12), 16);

      const cipherParams = CryptoJS.lib.CipherParams.create({
        ciphertext: CryptoJS.enc.Base64.parse(encryptedData)
      });

      const decrypted = CryptoJS.AES.decrypt(cipherParams, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
      });

      return JSON.parse(decrypted.toString(CryptoJS.enc.Utf8));
    }

    app.post('/webhooks/idcheck', (req, res) => {
      const event = decryptWebhook(req.body.response.body, process.env.ARGOS_API_KEY);
      // 이벤트 처리...
      res.status(200).json({ received: true });
    });
    ```

    <Warning>
      **암호화 방식 차이:**

      * **웹훅** 복호화: **AES-256-CBC**
      * **API 요청/응답**: **AES-256-ECB**
      * **쿼리 스트링**: **AES-256-ECB** 또는 **AES-256-GCM**

      각 용도별 암호화 방식을 혼동하지 마세요.
    </Warning>

    더 알아보기: [암호화 가이드](/ko/idcheck/getting-started/encrypt-and-decrypt-data/overview)
  </Accordion>
</AccordionGroup>

***

### 테스트 체크리스트

운영 배포 전 아래 항목들을 확인하세요.

<Steps>
  <Step title="Liveform 플로우 테스트">
    <AccordionGroup>
      <Accordion title="기본 플로우" icon="browser">
        * [ ] 기본 Liveform URL이 데스크톱/모바일에서 정상 로드됨
        * [ ] QR 코드가 모바일에서 스캔되어 플로우 진행됨
        * [ ] 카메라 권한 요청이 정상 동작함
        * [ ] 문서 및 셀피 촬영 후 제출이 완료됨
      </Accordion>

      <Accordion title="쿼리 스트링 파라미터" icon="link">
        * [ ] `email`, `userid` 파라미터로 사용자 정보가 미리 입력됨
        * [ ] 암호화된 파라미터(`allowedCountries` 등)가 정상 동작함
        * [ ] Token을 통한 Private mode URL이 정상 작동함
        * [ ] 만료된 Token 접근 시 적절한 오류 화면이 표시됨
      </Accordion>

      <Accordion title="Return URL" icon="arrow-turn-down-right">
        * [ ] 검증 완료 후 Return URL로 리디렉션됨
        * [ ] `kycStatus`, `userid`, `email` 파라미터가 올바르게 전달됨
        * [ ] 암호화 옵션 활성화 시 `encrypted` 파라미터로 전달됨
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="웹훅 테스트">
    <AccordionGroup>
      <Accordion title="웹훅 수신 확인" icon="webhook">
        **테스트 방법 1: webhook.site 사용**

        ```
        1. https://webhook.site 방문
        2. 생성된 고유 URL 복사
        3. 대시보드 Webhook URL 필드에 입력
        4. Liveform에서 테스트 인증 수행
        5. webhook.site에서 페이로드 확인
        ```

        **테스트 방법 2: ngrok 사용 (로컬 개발)**

        ```bash theme={null}
        # 로컬 서버 실행
        node server.js   # 포트 3000

        # 별도 터미널에서 외부 노출
        ngrok http 3000

        # 생성된 HTTPS URL을 대시보드에 입력
        # 예: https://abc123.ngrok.io/webhooks/idcheck
        ```

        * [ ] 웹훅 엔드포인트가 이벤트를 정상 수신함
        * [ ] `approved`, `rejected`, `submit` 이벤트가 올바르게 처리됨
        * [ ] 웹훅 수신 즉시 200 OK 응답이 반환됨
        * [ ] 중복 웹훅에 대한 멱등성 처리가 작동함
        * [ ] 암호화된 웹훅이 올바르게 복호화됨
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="API 테스트">
    * [ ] GET Submission이 올바른 데이터를 반환함
    * [ ] `userid`, `email`로 조회가 가능함
    * [ ] Token 등록(POST Token) 및 조회(GET Token)가 정상 동작함
    * [ ] IP 화이트리스트가 활성화된 경우 허가된 IP에서만 접근 가능함
    * [ ] 잘못된 API 키로 요청 시 403 응답이 반환됨
  </Step>

  <Step title="보안 테스트">
    * [ ] API 키가 클라이언트 코드에 노출되지 않음
    * [ ] API 키가 git 이력에 포함되지 않음
    * [ ] 웹훅 URL이 HTTPS를 사용함
    * [ ] Return URL 파라미터만으로 권한을 부여하지 않음 (웹훅을 통해 검증)
  </Step>
</Steps>

***

### 운영 전환 체크리스트

<Steps>
  <Step title="대시보드 설정 최종 확인">
    * [ ] 웹훅 URL이 운영 서버 주소로 설정됨 (HTTPS)
    * [ ] IP 화이트리스트에 모든 운영 서버 IP가 등록됨
    * [ ] Secure Data Transfer (웹훅 암호화)가 필요에 따라 설정됨
    * [ ] Return URL이 운영 앱 주소로 설정됨
    * [ ] 프로젝트 설정 (허용 문서 유형, 국가 블랙리스트, 연령 제한 등)이 요구사항과 일치함
  </Step>

  <Step title="코드 최종 확인">
    * [ ] API 키가 환경 변수에서 로드됨
    * [ ] 코드에 하드코딩된 API 키가 없음
    * [ ] 웹훅 핸들러에 오류 처리 및 로깅이 구현됨
    * [ ] 웹훅 멱등성 처리가 구현됨
    * [ ] 프론트엔드에서 ARGOS API를 직접 호출하지 않음
  </Step>

  <Step title="모니터링 설정">
    운영 중 추적할 주요 지표:

    * 검증 시작 수 vs 완료 수
    * 승인 / 거절 / 보류 비율
    * 웹훅 수신 실패율
    * Token 만료로 인한 재발급 빈도
  </Step>
</Steps>

***

## 다음 단계

통합을 완료했다면 아래 문서들을 참고하여 고급 기능을 탐색하세요.

<CardGroup cols={2}>
  <Card title="쿼리 스트링 & 토큰 가이드" icon="link" href="/ko/idcheck/getting-started/liveform-url/querystring-and-token-guide">
    Liveform 커스터마이즈의 모든 옵션
  </Card>

  <Card title="웹훅 이벤트 레퍼런스" icon="webhook" href="/ko/idcheck/webhooks/overview">
    각 이벤트별 페이로드 상세 가이드
  </Card>

  <Card title="암호화 가이드" icon="lock" href="/ko/idcheck/getting-started/encrypt-and-decrypt-data/overview">
    AES-256-ECB, GCM, CBC 암호화 구현 방법
  </Card>

  <Card title="API 레퍼런스" icon="code" href="/ko/idcheck/api-reference/api-reference-guide/overview">
    GET Submission, Token API 등 전체 API 명세
  </Card>

  <Card title="Return URL 가이드" icon="arrow-turn-down-right" href="/ko/idcheck/getting-started/liveform-url/return-url-guide">
    인증 완료 후 리디렉션 설정
  </Card>

  <Card title="권장 브라우저 및 기기" icon="mobile" href="/ko/idcheck/getting-started/recommended-browsers-and-devices">
    Liveform 지원 환경 확인
  </Card>
</CardGroup>
