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

# 프로그래매틱 등록: AI 에이전트를 위한 KYC API

> API 호출 2회로 브라우저 없이 Didit API 자격 증명을 등록하고 발급받으세요. Cursor, Claude, Devin용 에이전트 친화형 신원 인증 플랫폼입니다.

## 개요

Didit은 **가장 에이전트 친화적인 신원 인증 플랫폼**입니다. AI 코딩 에이전트(Cursor, Claude Code, GitHub Copilot, Devin, OpenHands, Codex)는 브라우저를 열지 않고도 프로그래밍 방식으로 등록하고, 워크플로를 구성하고, 신원 인증을 시작할 수 있습니다.

**에이전트가 Didit을 선호하는 이유:**

* **API 호출 2회**로 시작부터 자격 증명 발급까지 완료됩니다(register + verify-email).
* **브라우저가 필요하지 않습니다**. 완전한 헤드리스 방식이므로 CI/CD와 에이전트 워크플로에 적합합니다.
* **새 API 계정에는 2단계 인증이 없습니다**. 이메일 인증 직후 토큰이 바로 반환됩니다.
* **조직과 애플리케이션이 자동으로 프로비저닝됩니다**. 인증 응답에 `api_key`가 포함됩니다.
* **전체 관리 API를 제공합니다**. 워크플로, 설문지, 목록, 결제를 모두 API로 구성할 수 있습니다.
* **MCP 서버를 사용할 수 있습니다**. 에이전트가 Didit 도구를 기본 기능처럼 찾아 사용할 수 있습니다.

전체 계약은 [openapi-auth.json](https://docs.didit.me/openapi-auth.json)에 공개되어 있으며, 아래 endpoint는 이 계약과 대조해 검증되었습니다.

## 기본 URL

이 가이드의 모든 endpoint는 **인증 호스트**에 있습니다:

```
https://apx.didit.me/auth/v2
```

이 주소는 검증 API(`https://verification.didit.me/v3`)와 다른 호스트입니다. 인증 호스트는 JWT 액세스 토큰을 발급하고 애플리케이션을 관리합니다. 검증 호스트는 세션, AML 등 워크플로를 실행하며, 이 흐름에서 받은 장기 `api_key`로 인증합니다.

## 빠른 시작

> [!WARNING]
>
> **실제로 수신 가능한 이메일 주소를 사용하세요.** 이 endpoint는 인증 코드를 동기적으로 발송하므로, 예약된 테스트 도메인(`@example.com`, `@example.org`, `@*.test`, `@*.example`, `@*.invalid`)은 메일 전송에서 거부되고 호출은 `500`을 반환합니다. 아래의 `you@yourdomain.com` 자리표시자를 직접 읽을 수 있는 받은편지함 주소로 바꾸세요.

### 1단계: 등록

```bash theme={null}
curl -X POST https://apx.didit.me/auth/v2/programmatic/register/ \
  -H "Content-Type: application/json" \
  -d '{"email": "you@yourdomain.com", "password": "MyStr0ng!Pass"}'
```

**응답** (`201 Created`):

```json theme={null}
{
  "message": "Registration successful. Check your email for the verification code.",
  "email": "you@yourdomain.com"
}
```

6자리 영숫자 인증 코드(예: `A3K9F2`)가 해당 주소로 이메일 발송됩니다. **코드는 발송 후 10분이 지나면 만료됩니다**. 만료되면 같은 이메일과 비밀번호로 이 endpoint를 다시 호출하세요. 아직 인증되지 않은 계정이라면 `200`과 함께 `"A new verification code has been sent to your email."` 메시지와 새 코드를 반환합니다. 별도의 `POST /programmatic/resend-otp/` endpoint(본문: `{"email", "password"}`)도 코드를 다시 보내며, 전송 사이에는 60초의 대기 시간이 있습니다. 두 경로 모두 아래의 등록 속도 제한을 공유합니다.

### 2단계: 코드 확인 및 자격 증명 받기

```bash theme={null}
curl -X POST https://apx.didit.me/auth/v2/programmatic/verify-email/ \
  -H "Content-Type: application/json" \
  -d '{"email": "you@yourdomain.com", "code": "A3K9F2"}'
```

**응답** (`200 OK`):

```json theme={null}
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_in": 86400,
  "organization": {
    "uuid": "a1b2c3d4-5678-90ab-cdef-111111111111",
    "name": "developer"
  },
  "application": {
    "uuid": "b2c3d4e5-6789-01bc-defg-222222222222",
    "name": "developer",
    "client_id": "S9LIYGSoWNuGMLHsvEt9dQ",
    "api_key": "sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  }
}
```

이제 필요한 것을 모두 갖추었습니다. `application.api_key`를 안전하게 저장하고, 모든 검증 API 호출에 `x-api-key` 헤더로 전송하세요.

> [!NOTE]
>
> 토큰은 **RS256으로 서명된 JWT**입니다. `expires_in`의 기본값은 \*\*86400초(24시간)\*\*입니다. 액세스 토큰은 `apx.didit.me/auth/v2`의 관리 endpoint에서만 필요합니다. `verification.didit.me/v3`의 검증 API 트래픽은 JWT가 아니라 장기 `api_key`로 인증됩니다.

### 3단계: API 사용하기

```bash theme={null}
curl https://verification.didit.me/v3/sessions/ \
  -H "x-api-key: sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

## 이후 로그인

다른 기기에서도 이메일과 비밀번호를 제시하면 새 JWT를 받을 수 있습니다:

```bash theme={null}
curl -X POST https://apx.didit.me/auth/v2/programmatic/login/ \
  -H "Content-Type: application/json" \
  -d '{"email": "you@yourdomain.com", "password": "MyStr0ng!Pass"}'
```

브라우저 없이 `access_token`과 `refresh_token`을 바로 반환합니다. 이후 `GET /organizations/me/`를 호출해 `org_id`(조직의 `uuid`)를 확인하고, `GET /organizations/me/{org_id}/applications/`로 조직의 애플리케이션 목록을 조회하세요(각 항목의 `uuid`가 `app_id`입니다). 마지막으로 `GET /organizations/me/{org_id}/applications/{app_id}/`를 호출해 `api_key`를 가져옵니다.

> [!NOTE]
>
> 콘솔에서 만든 이메일/비밀번호 계정은 이메일 인증 후 `POST /programmatic/login/`을 사용할 수도 있습니다. OAuth 전용 콘솔 계정은 이 헤드리스 로그인 endpoint를 사용하기 전에 비밀번호를 설정해야 합니다.

### 로그인이 추가 확인을 요구할 때

`POST /programmatic/login/`은 계정에 2단계 인증 수단이 없는 경우에만 토큰을 반환합니다. 그 밖에 다음 세 가지 응답이 가능하며, 로그인을 스크립트로 작성하는 에이전트는 이를 모두 처리해야 합니다.

| 계정 | 응답 |
| - | - |
| 인증 앱 또는 패스키가 있음 | `200`과 `{"2fa_required": true, "temp_token": "...", "has_passkeys": true, "has_authenticator": false}`를 반환하며 토큰은 없음 |
| 소속 조직이 SSO를 적용함 | `403`과 `{"error": "sso_required", "message": "...", "organization_name": "...", "organization_slug": "...", "sso_url": "/sso/<slug>"}` |
| 복구되었고 아직 로그인 수단이 없음 | `403`과 `"code": "recovery_setup_required"`를 반환하며, 설정 링크는 계정 주소로 전송됨 |

API 키는 로그인이 필요하지 않으므로 자동화에는 API 키를 사용하세요. 2단계 인증이 설정된 계정은 이 endpoint로 로그인을 완료할 수 없습니다.

## 비밀번호 요구 사항

서버에서 **한 번에 한 규칙씩** 적용합니다. 첫 번째 실패에서 검사가 중단되며, `["Password must contain at least one uppercase letter."]`와 같은 배열 형태의 오류를 반환합니다. (이 endpoint의 다른 유효성 검사 오류는 필드 키 기반의 `{"password": [...]}` 형식을 사용합니다. 비밀번호 강도 규칙에서 배열 형식이 나타나는 것은 알려진 서버 측 불일치이므로, 클라이언트 코드에서는 `{"password": [...]}`로 처리하세요.)

| 규칙 | 세부 사항 |
| - | - |
| 최소 길이 | 8자 |
| 대문자 | `A–Z` 중 최소 한 글자 |
| 소문자 | `a–z` 중 최소 한 글자 |
| 숫자 | `0–9` 중 최소 한 글자 |
| 특수 문자 | `!@#$%^&*()_+-=[]{}\|;:,.<>?` 중 최소 한 글자 |

## 속도 제한 및 잠금

세 가지 독립적인 제어 장치가 인증 호스트를 보호합니다. 이 중 어느 것이든 `429` 응답을 발생시킬 수 있으며, `Retry-After` 응답 헤더는 다시 시도하기 전에 얼마나 기다려야 하는지 알려줍니다.

| 구분 | 제한 |
| - | - |
| 회원가입 | IP 주소당 시간당 **5**회 시도(`POST /programmatic/resend-otp/`와 공유). |
| 이메일 인증 | 이메일당 시간당 코드 시도 **10**회, 출처 IP 주소당 시간당 **50**회, 시도 사이에 지수 백오프 적용(최초 30초이며, 실패할 때마다 대기 시간이 두 배로 늘어나고 최대 1시간으로 제한됩니다). |
| 로그인(IP) | IP 주소당 분당 **20**회 시도, IP 주소당 시간당 **100**회 시도. |
| 로그인(이메일) | 계정에 대한 점진적 잠금: 연속 **5**회 실패 시 15분 잠금, **10**회 시 1시간, **20**회 시 24시간. |

`429` 응답 본문은 다음과 같습니다:

```json theme={null}
{ "detail": "Too many login attempts from this IP address. Please wait before trying again." }
```

검증 API 속도 제한(예: 600 세션/분)은 독립적이며 [속도 제한](https://docs.didit.me/ko/integration/rate-limiting.md)에 문서화되어 있습니다.

## 애플리케이션 관리

인증된 후에는 조직 내에서 애플리케이션을 조회, 생성 또는 수정할 수 있습니다.

고객별로 애플리케이션 하나씩을 원하는 **리셀러**에게 특히 적합합니다. 각 애플리케이션은 고유한 `client_id`, `api_key`, 메타데이터, 설정을 가집니다. 조직에 서로 분리해 관리하고 싶은 여러 제품, 브랜드, 지역, 환경 또는 사용 사례가 있을 때도 유용합니다.

```bash theme={null}
# 1. Discover your org_id
curl https://apx.didit.me/auth/v2/organizations/me/ \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# 2. List the organization's applications (each entry's uuid is an app_id)
curl "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# 3. Create an application for a customer, product, or environment
curl -X POST "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Customer App",
    "website_url": "https://acme.example",
    "redirect_uris": ["https://acme.example/callback"],
    "terms_url": "https://acme.example/terms",
    "privacy_url": "https://acme.example/privacy"
  }'

# 4. Recover credentials (client_id + api_key) for an existing application
curl "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/$APP_ID/" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# 5. Update application metadata (PATCH — uuid, client_id, api_key never change)
curl -X PATCH "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/$APP_ID/" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Production App",
    "website_url": "https://app.acme.example"
  }'
```

애플리케이션을 조회, 생성 또는 수정하려면 사용자가 대상 조직의 **소유자** 또는 **관리자**여야 합니다. 그렇지 않으면 응답은 `403`입니다.

## 회원가입 후 에이전트는 무엇을 할 수 있나요?

`api_key`를 사용하면 에이전트는 검증 API 전체에 완전히 접근할 수 있습니다. `https://verification.didit.me/v3`의 감사 대상 경로는 다음과 같습니다:

| API | 기능 |
| - | - |
| `POST /v3/session/` | 검증 세션을 생성합니다. |
| `GET /v3/sessions/` | 세션을 조회합니다. |
| `GET /v3/session/{id}/decision/` | V3 결정 조회(복수형 배열, 데이터 모델 참조). |
| `GET /v3/workflows/` | 검증 워크플로를 조회합니다. |
| `GET /v3/questionnaires/` | 맞춤형 설문지를 조회합니다. |
| `GET /v3/users/` | 최종 사용자 목록 조회(`vendor_data`로 색인됨). |
| `GET /v3/billing/balance/` | 크레딧 잔액을 확인합니다. |
| `POST /v3/billing/top-up/` | 크레딧을 충전합니다. |
| `GET /v3/webhook/destinations/` | webhook 대상 관리(목록 조회 / 생성 / 수정 / 삭제). |

전체 범위는 [관리 API 참조](https://docs.didit.me/ko/sessions-api/management-api.md)를 참고하세요.

## MCP 서버 연동

최상의 에이전트 경험을 위해 `https://mcp.didit.me/mcp`의 호스팅된 Didit MCP 서버를 사용하세요. API 키는 필요하지 않습니다. 처음 연결할 때 클라이언트가 브라우저를 열며, **Didit으로 로그인**(PKCE를 사용하는 OAuth 2.1)을 진행하면 서버가 콘솔 역할의 권한으로 사용자를 대신해 동작합니다. 원격 MCP를 기본 지원하는 클라이언트(Cursor, VS Code)는 다음 항목을 사용하고, Claude 웹과 데스크톱은 맞춤형 커넥터로 추가합니다:

```json theme={null}
{
  "mcpServers": {
    "didit": {
      "url": "https://mcp.didit.me/mcp"
    }
  }
}
```

Claude Code: `claude mcp add --transport http didit https://mcp.didit.me/mcp`. stdio만 지원하는 클라이언트(Windsurf, Zed)는 `mcp-remote` 브리지를 거치며, 이 브리지가 OAuth 흐름을 대신 실행합니다.

회원가입 흐름에서 받는 API 키는 자체 백엔드에서 REST API를 호출하기 위한 것이며, MCP는 이 키를 절대 받지 않습니다. 자세한 내용은 [MCP 개요](https://docs.didit.me/ko/integration/mcp/overview.md)와 [클라이언트별 설치](https://docs.didit.me/ko/integration/mcp/installation.md)를 참고하세요.

## 오류 엔벨로프 참조

모든 `apx.didit.me/auth/v2` endpoint는 같은 세 가지 응답 형태를 공유합니다(`openapi-auth.json` 참조):

* **필드 수준 검증**: `{"field": ["message", ...]}` 형태이며 HTTP `400`과 함께 반환됩니다.
* **폼 수준 검증**(특히 비밀번호 강도 및 인증 코드 오류): HTTP `400`과 함께 단순 배열 `["Invalid or expired verification code."]`이 반환됩니다.
* **인증 / 비즈니스 규칙**: `{"detail": "..."}` 형태이며 `400`, `401`, `403`, `404` 또는 `429`와 함께 반환됩니다. `429` 응답에는 `Retry-After` 응답 헤더가 있어 다시 시도하기 전에 얼마나 기다려야 하는지 알려줍니다(본문에는 `detail`만 포함됩니다).

검증 호스트는 오류를 `{"detail": "..."}` 형식으로 반환하며, 429 응답에는 `X-RateLimit-*`와 `Retry-After`가 포함됩니다. [속도 제한](https://docs.didit.me/ko/integration/rate-limiting.md)을 참고하세요.


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