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

# 세션 상태 업데이트 API: 승인 및 거부

> Didit의 PATCH /v3/session/{id}/update-status/로 세션을 승인, 거부, 검토 중으로 변경합니다. KYC·KYB 지원, 사용량 기반 요금, 월 최소 약정 없음.



세션 상태 업데이트 프롬프트
        프롬프트를 클립보드에 복사



      
      

\<pre>

\`Manually approve, decline, or re-open a Didit verification session.

Endpoint:
PATCH https://verification.didit.me/v3/session/{session_id}/update-status/

Authentication:
Use the x-api-key header with your Didit API key (or a user-auth token). Privilege: write:sessions.

Path parameter:
\- session_id (UUID) — KYC or KYB; Didit resolves it against both session types.

Request body:
\- new_status (string, required) — One of "Approved", "Declined", "Resubmitted". Any other value is rejected.
\- comment (string, optional) — Free-text note saved on the audit trail (visible in the Console review log).
\- nodes_to_resubmit (array, required when new_status="Resubmitted") — Which feature steps the user must redo. Each entry: { "node_id": "feature_poa_1", "feature": "POA" }. KYB-only nodes "KYB_REGISTRY" and "KYB_KEY_PEOPLE" cannot be resubmitted directly (the parent recomputes from child KYCs).
\- send_email (boolean, optional, default false): if true, email the person. "Approved" and "Declined" send their decision email; "Resubmitted" sends a fresh hosted link with the reasons.
\- email_address (string, required when send_email=true).
\- email_language (string, optional, default "en") — ISO 639-1.
\- email_preview_token (string, optional): the preview_token from Preview Decision Email ("Approved", "Declined") or Preview Resubmission Email ("Resubmitted"). Only valid with send_email=true; without it the request returns 400 { "email_preview_token": ["A preview receipt is only valid when the email is sent."] }. The update then sends exactly the previewed email, or returns 409 before changing anything if the email or the session changed since the preview.

Optional preview step (all three statuses):
1\. Preview the email. Neither call changes the session or sends anything.
\- Approved or Declined: POST https://verification.didit.me/v3/session/{session_id}/decision-email-preview/ with { "new_status": "Approved", "email_language": "en" } (see /sessions-api/preview-decision-email).
\- Resubmitted: POST https://verification.didit.me/v3/session/{session_id}/resubmission-preview/ with { "nodes_to_resubmit": [...], "email_language": "en" } (see /sessions-api/preview-resubmission). email_address is optional there; without it the email goes to the person's own address.
2\. Check subject, html, recipient, will_be_sent and not_sent_reason in the response.
3\. Confirm here with the same new_status (and the same nodes_to_resubmit for Resubmitted), send_email=true, email_address=<recipient>, email_language=<the language you previewed>, email_preview_token=<preview_token>.
The receipt expires after 15 minutes.

Allowed transitions:
Current status must be one of: Approved, Declined, In Review, Kyc Expired, Abandoned, Resubmitted. Otherwise the API returns 400 { "detail": "Only sessions with status Approved, Declined, In Review, Kyc Expired, Abandoned, Resubmitted can be updated. Current status: ..." }.
Setting "Approved" or "Declined" on a session that already has that status is a no-op: 200, nothing changes, and no webhook or email goes out. Setting "Resubmitted" on a session that is already Resubmitted returns 400 ["The new status is the same as the current status."].

curl example — approve after manual review:
curl -X PATCH https://verification.didit.me/v3/session/<SESSION_ID>/update-status/ \
-H "x-api-key: <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"new_status": "Approved",
"comment": "Cleared after compliance review."
}'

curl example: approve and send the email you previewed:
curl -X PATCH https://verification.didit.me/v3/session/<SESSION_ID>/update-status/ \
-H "x-api-key: <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"new_status": "Approved",
"send_email": true,
"email_address": "<recipient from the preview>",
"email_language": "en",
"email_preview_token": "<preview_token from the preview>"
}'

curl example — request resubmission of the proof-of-address step:
curl -X PATCH https://verification.didit.me/v3/session/<SESSION_ID>/update-status/ \
-H "x-api-key: <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"new_status": "Resubmitted",
"nodes_to_resubmit": [{ "node_id": "feature_poa_1", "feature": "POA" }],
"comment": "Please upload a clearer proof of address",
"send_email": true,
"email_address": "user@example.com"
}'

Response: { "session_id": "<uuid>" } only. Fetch the refreshed session with GET /v3/session/{session_id}/decision/.

Side effects:
\- Fires a status.updated webhook (plus user.status.updated or business.status.updated alias).
\- Writes an entry to the Console review trail with the actor and your comment.
\- "Approved" or "Declined" with send_email=true emails the decision to email_address. Preview Decision Email tells you beforehand whether it will be sent (for example, not to the contact_details address of a session created without contact_details.send_notification_emails=true).
\- "Resubmitted" sends the user back to the steps in nodes_to_resubmit, resets the session expiration window, and (if send_email=true) emails the user a fresh link. What those steps returned before stays readable: the decision endpoint returns it with include=resubmissions (see Retrieve Session).

Failure modes:
\- 400: invalid new_status (only "Approved", "Declined" and "Resubmitted" are accepted), current status not allowed, nothing to resubmit, send_email=true without email_address, or email_preview_token without send_email=true. Field errors look like { "<field>": ["..."] }.
\- 401: the scoped API key has expired.
\- 403: { "detail": "..." } when credentials are missing or invalid, the caller lacks write:sessions (a scoped API key needs decisions write), or the session belongs to another application.
\- 404: { "detail": "Not found." } when no session with this session_id exists.
\- 409: { "detail": "This email preview changed or expired. Preview the message again before confirming." } when email_preview_token no longer matches the email or the session, or is older than 15 minutes. Nothing changed and no email was sent: preview again.
\- 429 - { "detail": "..." } when a resubmit that only targets backend-only features (AML, DATABASE_VALIDATION, IP_ANALYSIS) repeats within 30 seconds of the previous resubmit. Those features re-run automatically with no user interaction, so an immediate repeat cannot change the outcome; honor the Retry-After header instead of retrying in a loop (e.g. from a webhook handler).

Idempotency:
Repeating "Approved" or "Declined" returns 200 and changes nothing. Repeating "Resubmitted" returns 400.

Next step:
After updating, call GET /v3/session/{session_id}/decision/ to fetch the refreshed payload — see /sessions-api/retrieve-session.

For end-to-end Didit integration, paste in the full prompt at /integration/integration-prompt.`

\</pre>



      
      

붙여넣을 곳

## KYC 및 KYB 지원이 endpoint는 **사용자 인증(KYC)** 세션과 **기업 확인(KYB)** 세션에 동일하게 작동합니다. Didit은 두 세션 유형 모두에 대해 `session_id`를 확인하며, 상태 전환 검증은 두 유형에 동일하게 적용됩니다(두 유형에 같은 상태 열거형이 적용됩니다).응답에는 `session_id`만 포함됩니다.
다운스트림 로직에서 세션 유형에 따라 분기해야 할 경우 [세션 조회](https://docs.didit.me/ko/sessions-api/retrieve-session.md)에서 `session_kind`를 읽으세요.## 허용되는 상태 전환세션을 `Approved`, `Declined`, 또는 `Resubmitted`로 변경할 수 있습니다.
그 외의 `new_status` 값(`In Review` 포함)은 `400`을 반환합니다.
세션의 현재 상태는 `Approved`, `Declined`, `In Review`, `Kyc Expired`, `Abandoned`, `Resubmitted` 중 하나여야 합니다. 그렇지 않으면 API가 `400`을 반환합니다.세션이 이미 해당 상태일 때 `Approved` 또는 `Declined`를 설정하면 아무 작업도 일어나지 않습니다. API는 `200`을 반환하며 아무것도 변경하지 않고, webhook도 발송하지 않고, 이메일도 보내지 않습니다.
이미 `Resubmitted` 상태인 세션에 `Resubmitted`를 설정하면 `400`(`The new status is the same as the current status.`)을 반환합니다.`nodes_to_resubmit`에 백엔드 전용 기능(`AML`, `DATABASE_VALIDATION`, `IP_ANALYSIS`)만 포함된 재제출은 자동으로 실행되며, 사용자 상호작용 없이 세션을 결정된 상태로 되돌립니다.
이러한 재제출을 30초 이내에 반복하면 `Retry-After` 헤더와 함께 `429 Too Many Requests`를 반환합니다. 즉시 반복해도 다른 결과가 나올 수 없기 때문입니다.
`In Review` 상태를 받을 때마다 webhook 핸들러에서 자동으로 재제출하지 마세요. 먼저 결과를 검토하거나 기반 데이터를 변경하세요.## 먼저 이메일 미리보기`send_email: true`를 설정하면 `Approved`와 `Declined`는 해당 사용자에게 결정 이메일을 보내고, `Resubmitted`는 사유와 함께 새 링크를 보냅니다.
무엇이든 변경하기 전에 이 이메일을 미리 확인할 수 있습니다.1) `Approved` 또는 `Declined`에는 [결정 이메일 미리보기](https://docs.didit.me/ko/sessions-api/preview-decision-email.md)를, `Resubmitted`에는 [재제출 이메일 미리보기](https://docs.didit.me/ko/sessions-api/preview-resubmission.md)를 호출하세요.
2) 렌더링된 `subject`와 `html`, `recipient`, 그리고 `will_be_sent` / `not_sent_reason`을 확인하세요.
3) 동일한 `new_status`(재제출인 경우 동일한 `nodes_to_resubmit`도 함께), `send_email: true`, `recipient` 값으로 설정한 `email_address`, 미리 본 `email_language`, 그리고 `preview_token` 값으로 설정한 `email_preview_token`을 사용해 이 endpoint를 호출하세요.두 미리보기 모두 세션을 변경하지 않으며 아무것도 보내지 않습니다.
업데이트는 미리 본 이메일과 정확히 같은 이메일만 보냅니다.
영수증은 15분 후에 만료됩니다.
미리보기 이후 수신자, 언어, 세션 상태, 발신자 또는 이메일이 변경되었다면, 아무것도 바뀌기 전에 업데이트가 `409`를 반환합니다. 이 경우 다시 미리보기를 하고 새 영수증으로 확인하세요.
`send_email: true` 없이 `email_preview_token`을 보내면 `400`을 반환합니다.
미리보기 단계는 선택 사항입니다. 기존 연동은 이 단계 없이 계속 이 endpoint를 호출할 수 있습니다.## 예제> [tab] 사용자 인증(KYC) 세션 승인
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/4c5c7f3a-.../update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Approved",
>     "comment": "Cleared after manual review by compliance team"
>   }'
> ```> [tab] 기업 확인(KYB) 세션 거부
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/bs-01HJX1.../update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Declined",
>     "comment": "Sanctioned subsidiary detected in ownership chain"
>   }'
> ```> [tab] 재제출 요청
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/.../update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Resubmitted",
>     "nodes_to_resubmit": [
>       { "node_id": "feature_poa_1", "feature": "POA" }
>     ],
>     "comment": "Please upload a clearer proof of address",
>     "send_email": true,
>     "email_address": "user@example.com"
>   }'
> ```> [tab] 승인하고 미리 본 이메일 보내기
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/.../update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Approved",
>     "send_email": true,
>     "email_address": "user@example.com",
>     "email_language": "en",
>     "email_preview_token": "PREVIEW_TOKEN_FROM_THE_PREVIEW"
>   }'
> ```## 권한`write:sessions` 권한이 필요합니다. 같은 권한이 두 유형 모두에 적용됩니다.## 관련 문서- [인증 상태](https://docs.didit.me/ko/integration/verification-statuses.md) — 상태 머신 참고 자료.
- [세션 조회](https://docs.didit.me/ko/sessions-api/retrieve-session.md) — 업데이트 후 결정 결과를 가져옵니다.
- [세션 개요](https://docs.didit.me/ko/sessions-api/overview.md) — 세션 유형 구분.
- [결정 이메일 미리보기](https://docs.didit.me/ko/sessions-api/preview-decision-email.md): 보내기 전에 승인 또는 거부 이메일을 확인하세요.
- [재제출 이메일 미리보기](https://docs.didit.me/ko/sessions-api/preview-resubmission.md): 보내기 전에 재제출 이메일을 확인하세요.


## OpenAPI

````yaml ko/openapi-25.json PATCH /v3/session/{sessionId}/update-status/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: 신분증 인증 API입니다. x-api-key 헤더로 인증합니다.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/session/{sessionId}/update-status/:
    patch:
      tags:
        - Sessions
      summary: 인증 세션 승인, 거부 또는 재제출 요청
      description: >-
        KYC 또는 KYB 인증 세션의 최종 결정을 수동으로 재지정합니다. `new_status`를 `Approved` 또는
        `Declined`로 설정하여 수동 결정을 기록하거나, `Resubmitted`로 설정하여 특정 인증 단계를 초기화하고 사용자가
        동일한 인증 URL을 통해 해당 단계를 다시 진행하도록 할 수 있습니다. 이 endpoint는 사용자(KYC) 및 기업(KYB)
        세션 ID를 모두 허용합니다.


        세션이 검토 가능한 상태에 도달한 후에 호출하십시오. 현재 상태는 `Approved`, `Declined`, `In
        Review`, `Kyc Expired`, `Abandoned` 또는 `Resubmitted`여야 합니다. 여전히 `Not
        Started`, `In Progress` 또는 `Awaiting User` 상태이거나 `Expired`로 종료된 세션은
        `400`을 반환합니다. API 키에는 `write:sessions` 권한이 필요합니다(범위가 지정된 API 키에는 결정에 대한
        쓰기 권한이 필요함). 대상 상태 확인은 본문 유효성 검사 전에 실행되므로, 부적격한 세션은 payload 역시 유효하지 않더라도
        `Wrong Current Status` 오류를 반환합니다.


        `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 세션을 재제출하면 상위 기업 세션이 자동으로 다시 계산됩니다.


        상태를 변경하는 모든 호출은 변경 사항이 커밋되면 `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`를 반환합니다.


        이미 해당 상태인 세션에 대해 `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
      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.
        '409':
          description: >-
            이메일 미리보기가 변경되었거나 만료되었습니다. 확인하기 전에 새 미리보기를 생성하세요. 세션 변경이나 이메일 전송은
            발생하지 않습니다.
          content:
            application/json:
              examples:
                Preview Changed:
                  summary: 영수증이 더 이상 일치하지 않거나 15분이 경과했습니다.
                  value:
                    detail: >-
                      This email preview changed or expired. Preview the message
                      again before confirming.
        '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.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X PATCH \
              https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-status/ \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "new_status": "Approved",
                "comment": "All checks passed manual review"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.sessions.update_status(
                "11111111-2222-3333-4444-555555555555",
                new_status="Approved",
                comment="All checks passed manual review",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: >-
            import Didit from "@didit-protocol/sdk-node";


            // Reads DIDIT_API_KEY.

            const didit = new Didit();


            const result = await
            didit.sessions.updateStatus("11111111-2222-3333-4444-555555555555",
            {
              new_status: "Approved",
              comment: "All checks passed manual review",
            });

            console.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;

            import me.didit.types.SessionsUpdateStatusParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.sessions().updateStatus("11111111-2222-3333-4444-555555555555",
            SessionsUpdateStatusParams.builder()
                    .newStatus(SessionsUpdateStatusParams.NewStatus.of("Approved"))
                    .comment("All checks passed manual review")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: >-
            <?php


            require 'vendor/autoload.php';


            use Didit\DiditClient;


            // Reads DIDIT_API_KEY.

            $didit = new DiditClient();


            $result =
            $didit->sessions->updateStatus('11111111-2222-3333-4444-555555555555',
            [
                'new_status' => 'Approved',
                'comment' => 'All checks passed manual review',
            ]);

            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

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

            result = didit.sessions.update_status(
              "11111111-2222-3333-4444-555555555555",
              new_status: "Approved",
              comment: "All checks passed manual review"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await
            client.Sessions.UpdateStatusAsync("11111111-2222-3333-4444-555555555555",
            new SessionsUpdateStatusParams

            {
                NewStatus = "Approved",
                Comment = "All checks passed manual review",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Business Console의 Developers -> API keys에서 발급받은 귀하 애플리케이션의 API 키입니다. 기본
        키는 전체 접근 권한을 갖습니다. 이름이 지정된 키는 리소스별 none, read, write 범위로 권한을 제한할 수 있으며
        특정 워크플로나 승인된 세션, IP 주소 목록, 만료일 등으로 제한할 수도 있습니다. 401은 키가 잘못되었거나 폐기되었거나
        만료되었음을 의미합니다. 403은 키가 전송되지 않았거나, 키에 해당 리소스나 작업에 대한 접근 권한이 없거나, 요청이 허용된
        IP 목록 외부 주소에서 발생했음을 의미합니다. 세션 경로에서의 404는 해당 세션이 키의 허용 워크플로 또는 상태 범위를
        벗어났음을 의미합니다. 미디어 접근 권한이 없는 키는 이미지, 비디오, PDF URL을 null로 수신하며, 세션 write
        권한이 없는 키는 세션 링크와 token을 null로 수신합니다.
        https://docs.didit.me/console/api-keys 를 참고하십시오.

````

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