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

# Perbarui Status Sesi API: Setujui & Tolak

> Setujui, tolak, atau tandai sesi Didit dalam peninjauan via PATCH /v3/session/{id}/update-status/. Untuk KYC dan KYB, tanpa minimum bulanan.



Prompt Pembaruan Status Sesi
        Salin prompt ke papan klip



      
      

\<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>



      
      

Tempel ke

## Dukungan KYC dan KYBEndpoint ini bekerja sama persis untuk sesi **Verifikasi Pengguna (KYC)** dan **Verifikasi Bisnis (KYB)**. Didit mencocokkan `session_id` dengan kedua jenis sesi; validasi transisi status sama untuk keduanya (enum status yang sama berlaku untuk keduanya).Respons hanya berisi `session_id`.
Baca `session_kind` dari [Ambil Sesi](https://docs.didit.me/id/sessions-api/retrieve-session.md) jika logika di sisi hilir Anda perlu membedakan jenisnya.## Transisi yang diizinkanAnda dapat memindahkan sesi ke `Approved`, `Declined`, atau `Resubmitted`.
Nilai `new_status` lain, termasuk `In Review`, mengembalikan `400`.
Status sesi saat ini harus salah satu dari `Approved`, `Declined`, `In Review`, `Kyc Expired`, `Abandoned`, atau `Resubmitted`; jika tidak, API mengembalikan `400`.Mengatur `Approved` atau `Declined` pada sesi yang sudah memiliki status tersebut tidak berpengaruh: API mengembalikan `200` dan tidak mengubah apa pun, tidak memicu webhook, dan tidak mengirim email.
Mengatur `Resubmitted` pada sesi yang sudah berstatus `Resubmitted` mengembalikan `400` (`The new status is the same as the current status.`).Pengajuan ulang yang `nodes_to_resubmit`-nya hanya berisi fitur khusus backend (`AML`, `DATABASE_VALIDATION`, `IP_ANALYSIS`) dijalankan secara otomatis dan mengembalikan sesi ke status yang sudah diputuskan tanpa interaksi pengguna.
Mengulangi pengajuan ulang seperti itu dalam 30 detik mengembalikan `429 Too Many Requests` dengan header `Retry-After`, karena pengulangan segera tidak dapat menghasilkan hasil yang berbeda.
Jangan lakukan auto-resubmit dari handler webhook setiap kali Anda menerima status `In Review`; tinjau temuannya atau ubah data yang mendasarinya terlebih dahulu.## Pratinjau email terlebih dahuluDengan `send_email: true`, `Approved` dan `Declined` mengirimkan email keputusan kepada orang tersebut, dan `Resubmitted` mengirimkan tautan baru beserta alasannya.
Anda dapat melihat email tersebut sebelum mengubah apa pun:1) Panggil [Pratinjau Email Keputusan](https://docs.didit.me/id/sessions-api/preview-decision-email.md) untuk `Approved` atau `Declined`, atau [Pratinjau Email Pengajuan Ulang](https://docs.didit.me/id/sessions-api/preview-resubmission.md) untuk `Resubmitted`.
2) Periksa `subject` dan `html` yang dirender, `recipient`, serta `will_be_sent` / `not_sent_reason`.
3) Panggil endpoint ini dengan `new_status` yang sama (dan, untuk pengajuan ulang, `nodes_to_resubmit` yang sama), `send_email: true`, `email_address` diisi dengan `recipient`, `email_language` yang Anda pratinjau, dan `email_preview_token` diisi dengan `preview_token`.Kedua pratinjau tidak mengubah sesi maupun mengirim apa pun.
Pembaruan kemudian mengirim tepat email yang Anda pratinjau.
Tanda terima kedaluwarsa setelah 15 menit.
Jika penerima, bahasa, status sesi, pengirim, atau email berubah sejak pratinjau, pembaruan mengembalikan `409` sebelum ada yang berubah; lakukan pratinjau ulang dan konfirmasi dengan tanda terima yang baru.
Mengirim `email_preview_token` tanpa `send_email: true` mengembalikan `400`.
Langkah pratinjau bersifat opsional: integrasi yang sudah ada dapat terus memanggil endpoint ini tanpa langkah tersebut.## Contoh> [tab] Setujui sesi Verifikasi Pengguna (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] Tolak sesi Verifikasi Bisnis (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] Minta pengajuan ulang
>
> ```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] Setujui dan kirim email yang sudah dipratinjau
>
> ```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"
>   }'
> ```## IzinMemerlukan izin `write:sessions`. Izin yang sama berlaku untuk kedua jenis sesi.## Terkait- [Status verifikasi](https://docs.didit.me/id/integration/verification-statuses.md): referensi mesin status.
- [Ambil sesi](https://docs.didit.me/id/sessions-api/retrieve-session.md): ambil keputusan setelah memperbarui.
- [Ikhtisar sesi](https://docs.didit.me/id/sessions-api/overview.md): membedakan jenis sesi.
- [Pratinjau Email Keputusan](https://docs.didit.me/id/sessions-api/preview-decision-email.md): lihat email Approved atau Declined sebelum Anda mengirimkannya.
- [Pratinjau Email Pengajuan Ulang](https://docs.didit.me/id/sessions-api/preview-resubmission.md): lihat email pengajuan ulang sebelum Anda mengirimkannya.


## OpenAPI

````yaml id/openapi-25.json PATCH /v3/session/{sessionId}/update-status/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API Verifikasi Identitas. Lakukan autentikasi dengan header x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/session/{sessionId}/update-status/:
    patch:
      tags:
        - Sessions
      summary: Setujui, tolak, atau minta pengiriman ulang untuk sesi verifikasi
      description: >-
        Ganti keputusan akhir sesi verifikasi KYC atau KYB secara manual. Atur
        `new_status` ke `Approved` atau `Declined` untuk mencatat keputusan
        manual, atau ke `Resubmitted` untuk mengosongkan langkah verifikasi
        tertentu dan mengizinkan pengguna mengulanginya melalui URL verifikasi
        yang sama. Endpoint ini menerima ID sesi pengguna (KYC) dan bisnis
        (KYB).


        Panggil endpoint ini setelah sesi mencapai status yang dapat ditinjau:
        status saat ini harus berupa `Approved`, `Declined`, `In Review`, `Kyc
        Expired`, `Abandoned`, atau `Resubmitted`. Sesi yang masih `Not
        Started`, `In Progress`, atau `Awaiting User`, atau yang berakhir
        sebagai `Expired`, akan mengembalikan `400`. Kunci API Anda memerlukan
        izin `write:sessions` (kunci API dengan cakupan memerlukan akses tulis
        ke keputusan). Pemeriksaan status yang memenuhi syarat berjalan sebelum
        validasi isi permintaan, sehingga sesi yang tidak memenuhi syarat
        mengembalikan kesalahan `Wrong Current Status` meskipun payload juga
        tidak valid.


        Untuk `Resubmitted`, teruskan `nodes_to_resubmit` untuk memilih langkah
        alur kerja mana yang harus diulangi pengguna, atau hilangkan parameter
        ini untuk memilih otomatis upaya fitur yang ada dalam status yang dapat
        dikirim ulang (`Declined`, `In Review`, `Not Finished`, `Expired`).
        Fitur yang belum pernah dicoba tidak akan dipilih secara otomatis:
        cantumkan secara eksplisit di `nodes_to_resubmit`, atau permintaan
        mengembalikan `400` jika tidak ada upaya tercatat yang perlu dikirim
        ulang. Hasil sebelumnya dari langkah yang dipilih akan dipindahkan ke
        riwayat pengiriman ulang (dikembalikan oleh Dapatkan Keputusan dengan
        `include=resubmissions`), langkah-langkah diurutkan ulang agar sesuai
        dengan graf alur kerja, batas waktu kedaluwarsa sesi dimulai ulang, dan
        URL verifikasi asli dapat digunakan kembali. Langkah khusus backend
        (`AML`, `DATABASE_VALIDATION`, `IP_ANALYSIS`) di bagian awal daftar
        langsung dijalankan tanpa interaksi pengguna; jika setiap langkah yang
        dikirim ulang merupakan langkah khusus backend, sesi akan diselesaikan
        ulang dalam permintaan yang sama. `KYB_REGISTRY` dan `KYB_KEY_PEOPLE`
        tidak dapat dikirim ulang secara langsung: kirim ulang sesi KYC turunan
        yang relevan dan sesi bisnis induk akan dihitung ulang secara otomatis.


        Setiap panggilan yang mengubah status akan memicu
        [webhook](/id/integration/webhooks) `status.updated` setelah perubahan
        diterapkan dan menambahkan entri aktivitas (dengan atribusi pelaku dan
        `comment` Anda) ke `reviews` sesi, yang terlihat di [Dapatkan
        Keputusan](#get-/v3/session/-sessionId-/decision/) dan di linimasa
        aktivitas konsol. Agregat profil pengguna yang ditautkan ke
        `vendor_data` sesi juga diperbarui. Penolakan akan menonaktifkan
        pemantauan AML berkelanjutan untuk sesi tersebut; menyetujui ulang akan
        mengaktifkannya kembali (dari `Resubmitted`, `Declined`, atau `Kyc
        Expired`) saat pemantauan diaktifkan pada alur kerja. Menyetujui atau
        menolak KYC turunan milik pemeriksaan pihak kunci KYB akan menghitung
        ulang status sesi bisnis induk. Tetapkan `send_email: true` (dengan
        `email_address`) untuk memberi tahu pengguna: pemberitahuan status untuk
        `Approved`/`Declined`, atau email pengiriman ulang yang berisi tautan
        verifikasi dan alasan per langkah untuk `Resubmitted`. Untuk memeriksa
        email terlebih dahulu, pratinjau dengan [Pratinjau Email
        Keputusan](/id/sessions-api/preview-decision-email) (`Approved`,
        `Declined`) atau [Pratinjau Email Pengiriman
        Ulang](/id/sessions-api/preview-resubmission) (`Resubmitted`) dan
        teruskan `preview_token` miliknya sebagai `email_preview_token`:
        pembaruan kemudian mengirimkan email persis seperti yang dipratinjau,
        atau mengembalikan `409` sebelum mengubah apa pun jika email atau sesi
        telah berubah sejak pratinjau atau tanda terima berusia lebih dari 15
        menit.


        Mengulangi `Approved` atau `Declined` pada sesi yang sudah memiliki
        status tersebut tidak akan mengubah apa pun dan mengembalikan `200`:
        tidak ada webhook, entri aktivitas, maupun email. Mengulangi
        `Resubmitted` mengembalikan `400` (`The new status is the same as the
        current status.`). Kredensial yang hilang atau tidak valid serta izin
        yang hilang mengembalikan `403`; kunci API dengan cakupan yang
        kedaluwarsa mengembalikan `401`.
      operationId: patch_v3_session_update_status
      parameters:
        - in: path
          name: sessionId
          required: true
          description: >-
            UUID sesi verifikasi yang akan diperbarui. Menerima ID sesi pengguna
            (KYC) dan bisnis (KYB) — layanan mencari ID tersebut di kedua jenis
            sesi.
          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: >-
                    Status target. `Approved` dan `Declined` mencatat keputusan
                    manual akhir (masing-masing juga dapat membatalkan yang
                    lain). `Resubmitted` menghapus langkah-langkah yang dipilih
                    dan mengirimkan sesi kembali ke pengguna. Nilai lainnya
                    mengembalikan `400`.
                  enum:
                    - Approved
                    - Declined
                    - Resubmitted
                  example: Approved
                comment:
                  type: string
                  description: >-
                    Alasan teks bebas untuk perubahan tersebut, disimpan pada
                    jejak peninjauan sesi dan dikembalikan dalam array `reviews`
                    pada [Dapatkan
                    Keputusan](#get-/v3/session/-sessionId-/decision/). Misalnya
                    `Duplicated user`.
                  example: All checks passed manual review
                nodes_to_resubmit:
                  type: array
                  description: >-
                    Langkah alur kerja yang harus diulang oleh pengguna. Hanya
                    ditindaklanjuti ketika `new_status` bernilai `Resubmitted`.
                    Untuk `Approved`/`Declined`, entri tetap divalidasi skemanya
                    (nilai `feature` yang tidak valid mengembalikan `400`),
                    tetapi entri yang valid secara skema diabaikan secara
                    semantik. Jika dihilangkan, server secara otomatis memilih
                    percobaan OCR, Liveness, Pencocokan Wajah, POA, Phone,
                    Email, AML, Validasi Database, dan Kuesioner yang ada yang
                    statusnya `Declined`, `In Review`, `Not Finished`, atau
                    `Expired` (percobaan NFC, analisis IP, estimasi usia,
                    pencarian wajah, dan dokumen KYB tidak pernah dipilih secara
                    otomatis; percobaan wajah non-face-match dipilih sebagai
                    `LIVENESS`) — fitur yang tidak pernah dicoba oleh pengguna
                    (tidak ada rekaman percobaan) TIDAK dipilih, sehingga sesi
                    dengan nol percobaan mengembalikan `400` ("No features found
                    that need resubmission") meskipun tidak ada yang disetujui;
                    teruskan `nodes_to_resubmit` secara eksplisit dalam kasus
                    tersebut. Langkah-langkah dieksekusi dalam urutan graf alur
                    kerja terlepas dari urutan pengirimannya. `KYB_REGISTRY`,
                    `KYB_KEY_PEOPLE`, dan alias `KYB` ditolak dengan `400` —
                    pemeriksaan induk tersebut dihitung ulang dari sesi KYC anak
                    mereka.
                  items:
                    type: object
                    required:
                      - node_id
                      - feature
                    properties:
                      node_id:
                        type: string
                        description: >-
                          Pengenal node seperti yang muncul dalam definisi alur
                          kerja sesi (misalnya `feature_ocr`,
                          `feature_liveness`).
                        example: feature_ocr
                      feature:
                        type: string
                        description: >-
                          Tipe fitur dari node. Alias `ID_VERIFICATION`, `POA`,
                          `PHONE`, dan `EMAIL` dinormalisasi di sisi server
                          menjadi `OCR`, `PROOF_OF_ADDRESS`,
                          `PHONE_VERIFICATION`, dan `EMAIL_VERIFICATION`.
                          `KYB_REGISTRY`, `KYB_KEY_PEOPLE`, dan `KYB` lolos
                          validasi skema tetapi selalu ditolak dengan aturan
                          bisnis `400` yang ditunjukkan pada contoh.
                        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: >-
                    Menentukan apakah akan mengirim email kepada pengguna
                    mengenai perubahan tersebut. Memerlukan `email_address`.
                    Untuk `Approved`/`Declined`, pengguna menerima pemberitahuan
                    status; untuk `Resubmitted`, email menyertakan tautan
                    verifikasi dan alasan pengiriman ulang per langkah.
                  default: false
                  example: false
                email_address:
                  type: string
                  format: email
                  description: >-
                    Penerima untuk email notifikasi. **Wajib diisi jika
                    `send_email` bernilai `true`** — mengabaikannya akan
                    mengembalikan `400`.
                  example: user@example.com
                email_language:
                  type: string
                  description: >-
                    Bahasa untuk email notifikasi. Menerima string apa pun pada
                    tingkat skema; kode yang tidak didukung akan beralih ke
                    bahasa Inggris (`en`) secara senyap.
                  default: en
                  example: en
                email_preview_token:
                  type: string
                  writeOnly: true
                  minLength: 1
                  maxLength: 512
                  description: >-
                    Tanda terima opsional dari [Preview Decision
                    Email](/id/sessions-api/preview-decision-email) (untuk
                    `Approved` dan `Declined`) atau [Preview Resubmission
                    Email](/id/sessions-api/preview-resubmission) (untuk
                    `Resubmitted`): berupa `preview_token`-nya. Hanya valid
                    dengan `send_email: true`; tanpanya, permintaan menghasilkan
                    respons `400`. Penerima, bahasa, status sesi, pengirim, dan
                    email (serta, untuk pengiriman ulang, langkah-langkah yang
                    dipilih) harus tetap cocok dengan pratinjau, dan tanda
                    terima kedaluwarsa setelah 15 menit. Jika tidak, permintaan
                    menghasilkan respons `409` sebelum sesi berubah atau email
                    dikirim. Integrasi yang sudah ada dapat mengabaikan kolom
                    ini.
            examples:
              Approve Session:
                summary: Setujui sesi setelah peninjauan manual
                value:
                  new_status: Approved
                  comment: All checks passed manual review
              Decline Session:
                summary: Tolak sesi
                value:
                  new_status: Declined
                  comment: Suspected fraud
              Resubmit Specific Steps:
                summary: Minta pengiriman ulang langkah yang dipilih, dengan email
                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: >-
                  Minta pengiriman ulang (pilih otomatis langkah yang tidak
                  disetujui)
                value:
                  new_status: Resubmitted
              Approve With Previewed Email:
                summary: >-
                  Setujui dan kirim email yang dikembalikan oleh Preview
                  Decision Email
                value:
                  new_status: Approved
                  send_email: true
                  email_address: person@example.com
                  email_language: en
                  email_preview_token: >-
                    eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000
      responses:
        '200':
          description: >-
            Status diperbarui. Respons hanya berisi `session_id`; ambil sesi
            yang diperbarui melalui [Get
            Decision](#get-/v3/session/-sessionId-/decision/). Webhook
            `status.updated` akan terpicu setelah perubahan diterapkan.
            Mengulangi `Approved` atau `Declined` mengembalikan isi respons yang
            sama dan tidak mengubah apa pun.
          content:
            application/json:
              schema:
                type: object
                properties:
                  session_id:
                    type: string
                    format: uuid
                    description: UUID sesi yang diperbarui.
              examples:
                Updated:
                  summary: >-
                    Dikembalikan baik untuk Approved, Declined, maupun
                    Resubmitted
                  value:
                    session_id: 3472fb7c-8f7c-4d1a-9cf4-cf3d74ce1a60
        '400':
          description: >-
            Kesalahan validasi. Kesalahan kolom diterima sebagai `{"<field>":
            ["<message>"]}` (beberapa penolakan aturan bisnis menggunakan nilai
            string sebagai gantinya: `{"nodes_to_resubmit": "<message>"}`),
            kesalahan lintas status sebagai `{"detail": "<message>"}`, dan
            kesalahan status yang sama sebagai larik JSON biasa.
          content:
            application/json:
              examples:
                Wrong Current Status:
                  summary: Sesi tidak berada dalam status yang dapat diperbarui
                  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 adalah status sesi nyata tetapi bukan salah satu
                    dari Approved/Declined/Resubmitted
                  value:
                    new_status:
                      - >-
                        You can only update the status to 'Approved',
                        'Declined', or 'Resubmitted'.
                Missing new_status:
                  summary: Kolom wajib tidak disertakan
                  value:
                    new_status:
                      - This field is required.
                Same Status:
                  summary: Kirim ulang diminta pada sesi yang sudah Dikirim ulang
                  value:
                    - The new status is the same as the current status.
                Email Address Required:
                  summary: send_email bernilai true tanpa email_address
                  value:
                    email_address:
                      - Email address is required when send_email is true.
                Non-resubmittable Feature:
                  summary: Kirim ulang menargetkan pemeriksaan induk 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: Pilihan otomatis tidak menemukan fitur yang belum disetujui
                  value:
                    nodes_to_resubmit: >-
                      No features found that need resubmission. All features are
                      already approved.
                Invalid Feature Choice:
                  summary: Fitur tidak dikenal di 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 bukan nilai StatusChoices yang valid
                  value:
                    new_status:
                      - '"Bogus" is not a valid choice.'
                Preview Receipt Without Email:
                  summary: 'email_preview_token dikirim tanpa send_email: true'
                  value:
                    email_preview_token:
                      - A preview receipt is only valid when the email is sent.
        '401':
          description: Kunci API dengan cakupan terbatas telah kedaluwarsa.
          content:
            application/json:
              examples:
                Expired API Key:
                  summary: Kunci API ber-scope melewati tanggal kedaluwarsanya
                  value:
                    detail: This API key has expired.
        '403':
          description: >-
            Kredensial tidak ada atau izin tidak mencukupi, atau `session_id`
            milik aplikasi lain.
          content:
            application/json:
              examples:
                Invalid Credentials:
                  summary: x-api-key tidak ada atau tidak valid
                  value:
                    detail: >-
                      Authentication credentials were not provided or are
                      invalid.
                Missing Privilege:
                  summary: Kunci API tidak memiliki write:sessions
                  value:
                    detail: You do not have permission to perform this action.
        '404':
          description: >-
            Tidak ada sesi KYC atau KYB dengan `session_id` ini (sesi yang
            dihapus juga mengembalikan `404`).
          content:
            application/json:
              examples:
                Not Found:
                  summary: session_id tidak dikenal
                  value:
                    detail: Not found.
        '409':
          description: >-
            Pratinjau email telah berubah atau kedaluwarsa. Buat pratinjau baru
            sebelum mengonfirmasi; tidak ada perubahan sesi atau pengiriman
            email yang terjadi.
          content:
            application/json:
              examples:
                Preview Changed:
                  summary: Tanda terima tidak lagi cocok, atau lebih lama dari 15 menit
                  value:
                    detail: >-
                      This email preview changed or expired. Preview the message
                      again before confirming.
        '429':
          description: >-
            Pengiriman ulang yang hanya menargetkan fitur khusus backend (AML,
            DATABASE_VALIDATION, IP_ANALYSIS) diulangi dalam jendela cooldown 30
            detik; pengulangan langsung tidak dapat mengubah hasilnya. Tunggu
            dan coba lagi setelah interval yang ditunjukkan dalam `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: >-
        Kunci API aplikasi Anda, dari Developers -> API keys di Business
        Console. Kunci utama memiliki akses penuh. Kunci bernama dapat diberi
        cakupan: none, read, atau write per sumber daya, dibatasi pada beberapa
        alur kerja atau pada sesi yang disetujui, pada daftar alamat IP, dan
        pada tanggal kedaluwarsa. 401 berarti kuncinya salah, dicabut, atau
        kedaluwarsa; 403 berarti tidak ada kunci yang dikirimkan, kunci tidak
        memiliki akses ke sumber daya atau tindakan ini, atau permintaan datang
        dari alamat di luar daftar IP-nya; 404 pada rute sesi berarti sesi
        berada di luar alur kerja atau status kunci tersebut. Kunci tanpa akses
        media menerima URL gambar, video, dan PDF sebagai null, dan kunci tanpa
        izin tulis sesi menerima tautan sesi dan token sebagai null. Lihat
        https://docs.didit.me/console/api-keys.

````

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