> ## 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 Update Feature Status: Setujui/Tolak Satu Langkah

> Setujui, tolak, atau tandai satu langkah verifikasi Didit (OCR, Liveness, Face Match, AML, POA, Telepon) untuk peninjauan, sekarang atau nanti.



Prompt Pembaruan Status Fitur
        Salin prompt ke papan klip



      
      

\<pre>

\`Approve, decline, or move a SINGLE verification step (feature) of a Didit session to review, now or once the person finishes the flow.

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

Authentication:
x-api-key (client API key) or a user-auth token. Privilege: write:sessions.

Path parameters:
\- session_id (UUID) — KYC or KYB; Didit resolves it against both session types.
\- node_id — the workflow graph node ID of the step (e.g. feature_ocr_1, feature_liveness_1, feature_aml_1). Use the literal "default" for non-graph (single-step) workflows where the step has no node ID.

Request body:
\- new_status (string, required): one of "Approved", "Declined", "In Review". Must differ from the step's current status.
\- comment (string, optional): your reason, saved in the session's activity and returned as the override's reason.
\- feature_type (string, optional): which kind of step to target, for example "LIVENESS", "AML", "FACE_MATCH", "ID_VERIFICATION". Needed when node_id is "default" (non-graph workflows, where steps have no node ID). An unknown value returns 400 { "feature_type": ["Unknown feature_type '...'."] }.
\- defer_until_flow_finishes (boolean, optional, default false): while the person is still in the flow, wait and apply the override when the flow finishes instead of at once.

When the override applies:
\- Omitted or false: it applies at once. If the person is still in the flow it is recorded as forced=true.
\- true while the person is still in the flow (session Not Started, In Progress or Resubmitted, and not finished): it is stored as "pending_until_flow_finishes" and applies when the flow finishes, after the flow reaches its own decision.
\- true after the flow ended: it applies at once.
\- A waiting override is cancelled instead when the person redoes the step before finishing, a newer override on the same step replaces it, the session leaves the flow unfinished (abandoned, expired, decided mid-flow), or you cancel it with POST /v3/session/{session_id}/features/overrides/{override_id}/cancel/.

Which steps this works on:
Every per-step feature record: OCR/ID, Liveness, Face Match, NFC, AML, Proof of Address (POA), Phone, Email, Database Validation, Questionnaire, and the KYB registry / documents / key-people checks.

Difference vs update-status:
\- update-status changes the OVERALL session decision (Approved/Declined/Resubmitted).
\- THIS endpoint changes ONE step's status. A session that already has a decision keeps it. If the session has no decision yet and its workflow is waiting on exactly this step, applying the override completes the step: the workflow moves on and a status node can set the session decision (and fire status.updated).

Not allowed:
\- Standalone API sessions (session_type = API) return 400.

curl example — approve the ID/OCR step:
curl -X PATCH https://verification.didit.me/v3/session/<SESSION_ID>/features/feature_ocr_1/update-status/ \
-H "x-api-key: <API_KEY>" \
-H "Content-Type: application/json" \
-d '{ "new_status": "Approved", "comment": "Document manually verified" }'

Response: { session_id, node_id, feature_type, new_status, override }.
\- node_id is the step's workflow node, or null for a step without a node ("default" in a non-graph workflow).
\- new_status is the step's stored status: the requested one once the override applied, the unchanged one while it waits.
\- override: { id, node_id, feature_type, feature_model, previous_status, new_status, state ("applied" | "pending_until_flow_finishes" | "cancelled"), forced, reason, requested_by { email, name, type }, requested_at, applied_at, cancelled_at, cancel_reason }.

Side effects:
\- Fires a data.updated webhook when the override applies (at once, or when the flow finishes). Nothing is sent while it waits or when it is cancelled.
\- Records the override in the session's activity as FEATURE_OVERRIDE_PENDING, FEATURE_OVERRIDE_APPLIED or FEATURE_OVERRIDE_CANCELLED, with who made it; the request's entry carries your comment. In the decision's reviews array these entries appear with new_status null, and the request's entry has your reason in comment.

Failure modes:
\- 400: new_status invalid or unchanged, unknown feature_type, or the session is a standalone API session.
\- 401: the scoped API key has expired.
\- 403: missing credentials (a wrong, revoked or expired key gets 401), or the caller lacks write:sessions (a scoped key needs decisions write).
\- 404: session not found, or no feature has the given node_id.

Related: list overrides with GET /v3/session/{session_id}/features/overrides/ (see /sessions-api/list-feature-overrides); cancel a waiting one with POST /v3/session/{session_id}/features/overrides/{override_id}/cancel/ (see /sessions-api/cancel-feature-override).

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

\</pre>



      
      

Tempel ke

## Apa yang dilakukan iniSesi verifikasi terdiri dari **fitur** (langkah) individual: ID/OCR, Liveness, Pencocokan Wajah, AML, Bukti Alamat, Telepon, dan sebagainya.
Endpoint ini memungkinkan Anda menetapkan status **satu** dari langkah tersebut menjadi `Approved`, `Declined`, atau `In Review`.Gunakan [update-status](https://docs.didit.me/id/sessions-api/update-status.md) saat Anda ingin menyetujui, menolak, atau membuka kembali seluruh sesi.
Gunakan **endpoint ini** saat Anda hanya ingin mencatat keputusan pada satu langkah, misalnya untuk menandai langkah Pencocokan Wajah sebagai `Declined` dalam alur tinjauan Anda sendiri.Sesi yang sudah memiliki keputusan akan tetap mempertahankannya: hanya langkahnya yang berubah.
Jika sesi belum memiliki keputusan dan alur kerjanya sedang menunggu tepat pada langkah ini, penerapan override akan menyelesaikan langkah tersebut, sama seperti jika langkah itu diselesaikan secara normal.
Alur kerja kemudian berlanjut, langkah-langkah berikutnya dijalankan, dan node status dapat menetapkan keputusan sesi serta memicu webhook `status.updated`.## Menargetkan langkah dengan `node_id`Dalam alur kerja berbasis graf, setiap langkah memiliki `node_id` (misalnya `feature_ocr_1`, `feature_liveness_1`, `feature_aml_1`). Anda dapat menemukannya di [keputusan sesi](https://docs.didit.me/id/sessions-api/retrieve-session.md): setiap fitur dalam keputusan V3 membawa `node_id`-nya.Untuk **alur kerja non-graf (satu langkah)**, fitur yang mendasarinya tidak memiliki node ID. Kirimkan nilai literal `default` sebagai `nodeId` untuk menargetkannya.
Karena tidak ada langkah pada alur kerja semacam itu yang memiliki node ID, kirimkan juga `feature_type` (misalnya `LIVENESS`, `AML`, atau `FACE_MATCH`) untuk menyatakan langkah yang dimaksud.
`feature_type` yang tidak dikenal akan mengembalikan `400`.## Tunggu hingga pengguna akhir menyelesaikan alurSecara default, override langsung diterapkan.
Jika pengguna akhir masih menjalani alur, override itu akan mengubah langkah di bawah alur yang masih berjalan; override kemudian dicatat dengan `forced: true`.Setel `defer_until_flow_finishes: true` untuk menunggu.
Selama sesi berstatus `Not Started`, `In Progress`, atau `Resubmitted` dan pengguna akhir belum menyelesaikan alur, override disimpan sebagai `pending_until_flow_finishes`.
Override diterapkan ketika pengguna akhir menyelesaikan alur, setelah alur mencapai keputusannya sendiri.
Pada sesi yang alurnya sudah berakhir, override langsung diterapkan dalam kedua kasus.Override yang sedang menunggu dibatalkan, bukan diterapkan, ketika:- pengguna akhir mengulang langkah sebelum menyelesaikannya (`check_changed`),
- override yang lebih baru pada langkah yang sama menggantikannya (`replaced`),
- sesi keluar dari alur sebelum selesai: ditinggalkan, kedaluwarsa, atau diputuskan di tengah alur (`session_closed`),
- Anda membatalkannya dengan [Batalkan Override Fitur](https://docs.didit.me/id/sessions-api/cancel-feature-override.md) (`cancelled_by_reviewer`).Objek `override` pada respons memberi tahu Anda apa yang terjadi: `state` bernilai `applied` atau `pending_until_flow_finishes`, dan `applied_at` diisi setelah override diterapkan.
`new_status` pada tingkat atas adalah status tersimpan langkah tersebut, sehingga tetap tidak berubah selama override menunggu.
Gunakan [Daftar Override Fitur](https://docs.didit.me/id/sessions-api/list-feature-overrides.md) untuk melihat setiap override pada sesi dan apakah pengguna akhir masih berada dalam alur.## Dukungan KYC dan KYBBerfungsi sama untuk sesi **Verifikasi Pengguna (KYC)** dan **Verifikasi Bisnis (KYB)**: Didit menemukan `sessionId` di kedua jenis sesi tersebut. Jenis langkah yang didukung mencakup ID/OCR, Liveness, Pencocokan Wajah, NFC, AML, Bukti Alamat, Telepon, Email, Validasi Database, Kuesioner, serta pemeriksaan registri, dokumen, dan pihak kunci KYB.> [!NOTE]
>
> Sesi API mandiri (yang dibuat melalui API verifikasi mandiri, `session_type = API`) tidak dapat diubah status fitur individualnya. Endpoint mengembalikan `400`.## Contoh> [tab] Setujui satu langkah
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/4c5c7f3a-.../features/feature_ocr_1/update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Approved",
>     "comment": "Document manually verified by compliance"
>   }'
> ```> [tab] Tolak langkah Pencocokan Wajah
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/4c5c7f3a-.../features/feature_face_match/update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Declined"
>   }'
> ```> [tab] Alur satu langkah (node default)
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/4c5c7f3a-.../features/default/update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "In Review",
>     "feature_type": "LIVENESS"
>   }'
> ```> [tab] Tunggu hingga pengguna akhir menyelesaikan alur
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/4c5c7f3a-.../features/feature_liveness_1/update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Approved",
>     "comment": "Liveness retried with a reviewer present",
>     "defer_until_flow_finishes": true
>   }'
> ```## Apa yang terjadi setelah pembaruan- **Webhook**: event `data.updated` dipicu ketika override diterapkan, baik langsung maupun saat alur selesai. Tidak ada yang dikirim selama override menunggu atau ketika dibatalkan.
- **Aktivitas**: setiap override dicatat dalam Aktivitas sesi sebagai `FEATURE_OVERRIDE_PENDING`, `FEATURE_OVERRIDE_APPLIED`, atau `FEATURE_OVERRIDE_CANCELLED`, beserta aktornya (kunci API, pengguna, atau sistem ketika override yang menunggu diterapkan). Entri permintaan Anda mencantumkan `comment` sebagai alasannya. Pada larik `reviews` di [keputusan sesi](https://docs.didit.me/id/sessions-api/retrieve-session.md), entri ini muncul dengan `new_status: null`, dan entri permintaan Anda memiliki alasan di `comment`.
- **Keputusan sesi**: sesi yang sudah memiliki keputusan akan tetap mempertahankannya. Untuk mengubah keputusan akhir, panggil [update-status](https://docs.didit.me/id/sessions-api/update-status.md) secara terpisah.## IzinMemerlukan hak akses `write:sessions`, dengan kunci API klien (`x-api-key`) atau header otorisasi pengguna.
Kunci API dengan cakupan terbatas memerlukan akses tulis ke keputusan.## Terkait- [Perbarui status sesi](https://docs.didit.me/id/sessions-api/update-status.md): ubah keputusan sesi secara keseluruhan.
- [Perbarui status hit AML](https://docs.didit.me/id/sessions-api/update-aml-hit-status.md): tinjau kecocokan AML individual.
- [Ambil sesi](https://docs.didit.me/id/sessions-api/retrieve-session.md): ambil keputusan (dan `node_id` setiap fitur).
- [Webhook](https://docs.didit.me/id/integration/webhooks.md): berlangganan `data.updated`.
- [Daftar Override Fitur](https://docs.didit.me/id/sessions-api/list-feature-overrides.md): setiap override pada sesi dan statusnya.
- [Batalkan Override Fitur](https://docs.didit.me/id/sessions-api/cancel-feature-override.md): hentikan override yang menunggu agar tidak diterapkan.


## OpenAPI

````yaml id/openapi-25.json PATCH /v3/session/{sessionId}/features/{nodeId}/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}/features/{nodeId}/update-status/:
    patch:
      tags:
        - Sessions
      summary: Perbarui status fitur (langkah) individual
      description: >-
        Atur status dari satu fitur (langkah) verifikasi dalam suatu sesi.
        Targetkan fitur berdasarkan `nodeId` graf alur kerjanya. Pada alur kerja
        non-graf, yang langkah-langkahnya tidak memiliki node, gunakan `default`
        dan teruskan juga `feature_type` untuk menentukan langkah yang Anda
        maksud.


        Berfungsi untuk sesi Verifikasi Pengguna (KYC) maupun Verifikasi Bisnis
        (KYB) dan setiap jenis langkah: ID/OCR, Liveness, Face Match, NFC, AML,
        Bukti Alamat, Telepon, Email, Validasi Database, Kuesioner, serta
        pemeriksaan registri / dokumen / pihak kunci KYB. Endpoint ini **tidak**
        tersedia untuk sesi API mandiri (`session_type = API`).


        `new_status` harus salah satu dari `Approved`, `Declined`, atau `In
        Review`, dan harus berbeda dari status fitur saat ini.


        **Kapan override berlaku.** Tanpa `defer_until_flow_finishes` (atau
        dengan `false`), override akan langsung diterapkan, seperti biasanya;
        ketika orang tersebut masih berada dalam alur, tindakan ini dicatat
        sebagai `forced`. Dengan `defer_until_flow_finishes: true` saat orang
        tersebut masih berada dalam alur (sesi berstatus `Not Started`, `In
        Progress`, atau `Resubmitted` dan belum selesai), override disimpan
        sebagai `pending_until_flow_finishes` dan berlaku ketika alur selesai,
        setelah alur mencapai keputusannya sendiri. Pada sesi yang alurnya sudah
        berakhir, override akan langsung berlaku dalam kedua kondisi tersebut.
        Override yang sedang menunggu akan dibatalkan jika orang tersebut
        mengulangi langkahnya sebelum selesai, jika override yang lebih baru
        pada pemeriksaan yang sama menggantikannya, jika sesi meninggalkan alur
        dalam keadaan belum selesai (ditinggalkan, kedaluwarsa, atau diputuskan
        di tengah alur), atau ketika Anda membatalkannya dengan `POST
        /v3/session/{sessionId}/features/overrides/{overrideId}/cancel/`.
        Dapatkan daftar override suatu sesi dengan `GET
        /v3/session/{sessionId}/features/overrides/`.


        **Pengaruh pada sesi.** Sesi yang sudah memiliki keputusan akan tetap
        mempertahankannya: hanya pemeriksaannya yang berubah. Ketika sesi belum
        memiliki keputusan dan alur kerjanya sedang menunggu langkah ini secara
        tepat, penerapan override akan menyelesaikan langkah tersebut: alur
        kerja berlanjut, langkah-langkah berikutnya berjalan, dan node status
        dapat menetapkan keputusan sesi serta memicu `status.updated`.


        **Webhook dan aktivitas.** Webhook `data.updated` dipicu ketika override
        diterapkan (langsung, atau ketika alur selesai), tidak pernah saat
        sedang menunggu atau saat dibatalkan. Setiap override dicatat dalam
        aktivitas sesi sebagai `FEATURE_OVERRIDE_PENDING`,
        `FEATURE_OVERRIDE_APPLIED`, atau `FEATURE_OVERRIDE_CANCELLED`, beserta
        pihak yang melakukannya; entri permintaan menyertakan `comment` Anda.


        Lakukan autentikasi dengan kunci API Anda (`x-api-key`) atau header
        otorisasi pengguna yang memuat hak istimewa `write:sessions`; kunci API
        dengan cakupan (scoped) memerlukan akses tulis ke keputusan.
      operationId: patch_v3_session_update_feature_status
      parameters:
        - in: path
          name: sessionId
          required: true
          description: >-
            UUID sesi verifikasi. 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
        - in: path
          name: nodeId
          required: true
          description: >-
            ID node graf alur kerja dari fitur yang akan diperbarui (misalnya
            `feature_ocr_1`). Gunakan nilai harfiah `default` untuk alur kerja
            non-graf (satu langkah) di mana fitur tersebut tidak memiliki ID
            node.
          schema:
            type: string
            example: feature_ocr_1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - new_status
              properties:
                new_status:
                  type: string
                  description: >-
                    Status target untuk fitur ini. Harus berbeda dari nilai saat
                    ini.
                  enum:
                    - Approved
                    - Declined
                    - In Review
                  example: Approved
                comment:
                  type: string
                  description: >-
                    Catatan teks bebas opsional yang dicatat pada jejak
                    peninjauan sesi untuk perubahan fitur ini.
                  example: Document manually verified by compliance.
                feature_type:
                  type: string
                  enum:
                    - ID_VERIFICATION
                    - OCR
                    - OCR_BACK
                    - NFC
                    - LIVENESS
                    - FACE
                    - AGE_ESTIMATION
                    - AGE_VERIFICATION
                    - FACE_SEARCH
                    - FACE_MATCH
                    - IP_ANALYSIS
                    - AML
                    - PHONE
                    - PHONE_VERIFICATION
                    - EMAIL
                    - EMAIL_VERIFICATION
                    - POA
                    - PROOF_OF_ADDRESS
                    - DATABASE_VALIDATION
                    - DATA_VALIDATION
                    - QUESTIONNAIRE
                    - DOCUMENT_AI
                    - KYB_REGISTRY
                    - KYB_DOCUMENTS
                    - KYB_KEY_PEOPLE
                    - BANK_VERIFICATION
                    - GEOLOCATION
                  description: >-
                    Jenis langkah mana yang ditargetkan. Diperlukan pada alur
                    kerja non-graf (`nodeId` = `default`), di mana setiap
                    langkah tidak berbagi node; jika tidak, bersifat opsional.
                    Nilai yang tidak dikenal akan mengembalikan `400`.
                  example: LIVENESS
                defer_until_flow_finishes:
                  type: boolean
                  default: false
                  description: >-
                    Saat orang tersebut masih berada dalam alur, simpan override
                    sebagai `pending_until_flow_finishes` dan terapkan saat alur
                    selesai, alih-alih langsung diterapkan. Jika tidak
                    dicantumkan atau `false`, override langsung diterapkan. Pada
                    sesi yang alurnya sudah berakhir, override langsung
                    diterapkan dalam kondisi apa pun.
                  example: false
            examples:
              Apply Now:
                summary: Setujui langkah ID sekaligus
                value:
                  new_status: Approved
                  comment: Document manually verified by compliance.
              Wait For The Flow:
                summary: >-
                  Setujui langkah liveness setelah orang tersebut menyelesaikan
                  alur
                value:
                  new_status: Approved
                  comment: Liveness retried with a reviewer present.
                  defer_until_flow_finishes: true
              Non-graph Workflow:
                summary: >-
                  Menargetkan langkah liveness dari alur kerja tanpa node
                  (nodeId = default)
                value:
                  new_status: In Review
                  feature_type: LIVENESS
      responses:
        '200':
          description: >-
            Penggantian telah dicatat. `new_status` adalah status pemeriksaan
            yang tersimpan: status yang diminta setelah penggantian diterapkan,
            atau status yang tidak berubah saat menunggu alur selesai.
            `override` menyatakan apa yang terjadi.
          content:
            application/json:
              schema:
                type: object
                properties:
                  session_id:
                    type: string
                    format: uuid
                  node_id:
                    type: string
                    nullable: true
                    description: >-
                      Node alur kerja langkah yang diperbarui, atau `null` untuk
                      langkah tanpa node (jalur `default` dalam alur kerja
                      non-graf).
                    example: feature_ocr_1
                  feature_type:
                    type: string
                    description: >-
                      Nama model dari fitur yang diperbarui (misalnya `KYC`,
                      `Face`, `FaceMatch`, `AML`, `POA`).
                    example: KYC
                  new_status:
                    type: string
                    description: >-
                      Status tersimpan dari pemeriksaan: status yang diminta
                      setelah override diterapkan, atau yang tidak berubah saat
                      override menunggu alur selesai.
                    example: Approved
                  override:
                    $ref: '#/components/schemas/FeatureStatusOverride'
                required:
                  - session_id
                  - node_id
                  - feature_type
                  - new_status
                  - override
              examples:
                Applied:
                  summary: Penggantian segera diterapkan
                  value:
                    session_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                    node_id: feature_ocr_1
                    feature_type: KYC
                    new_status: Approved
                    override:
                      id: 7c9e6679-7425-40de-944b-e07fc1f90ae7
                      node_id: feature_ocr_1
                      feature_type: ''
                      feature_model: KYC
                      previous_status: In Review
                      new_status: Approved
                      state: applied
                      forced: false
                      reason: Document manually verified by compliance.
                      requested_by:
                        email: reviewer@example.com
                        name: Alex Reviewer
                        type: CONSOLE_USER
                      requested_at: '2026-10-13T09:15:00Z'
                      applied_at: '2026-10-13T09:15:00Z'
                      cancelled_at: null
                      cancel_reason: null
                Waiting For The Flow:
                  summary: >-
                    defer_until_flow_finishes saat orang tersebut masih berada
                    dalam alur
                  value:
                    session_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                    node_id: feature_liveness_1
                    feature_type: Face
                    new_status: Declined
                    override:
                      id: 9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3
                      node_id: feature_liveness_1
                      feature_type: ''
                      feature_model: Face
                      previous_status: Declined
                      new_status: Approved
                      state: pending_until_flow_finishes
                      forced: false
                      reason: Liveness retried with a reviewer present.
                      requested_by:
                        email: reviewer@example.com
                        name: Alex Reviewer
                        type: CONSOLE_USER
                      requested_at: '2026-10-13T09:15:00Z'
                      applied_at: null
                      cancelled_at: null
                      cancel_reason: null
        '400':
          description: >-
            Kesalahan validasi. Dikembalikan ketika `new_status` tidak valid
            atau tidak berubah, ketika `feature_type` tidak diketahui, atau
            ketika sesi tersebut adalah sesi API mandiri.
          content:
            application/json:
              examples:
                Same Status:
                  summary: new_status sama dengan status saat ini
                  value:
                    new_status:
                      - The new status is the same as the current status.
                API Session:
                  summary: Status fitur tidak dapat diubah pada sesi API mandiri
                  value:
                    - Cannot change feature status for API sessions.
                Unknown feature_type:
                  summary: feature_type bukan tipe langkah yang dikenal
                  value:
                    feature_type:
                      - Unknown feature_type 'SELFIE'.
        '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.
          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.
                Scoped Key Without Access:
                  summary: Kunci API ber-scope tanpa akses tulis ke keputusan
                  value:
                    detail: This API key has no write access to decisions.
        '404':
          description: >-
            Sesi tidak ditemukan, atau tidak memiliki fitur dengan `nodeId` yang
            diberikan.
          content:
            application/json:
              examples:
                Session Not Found:
                  summary: session_id tidak dikenal
                  value:
                    detail: Session not found.
                Feature Not Found:
                  summary: Tidak ada fitur untuk node_id ini
                  value:
                    detail: >-
                      No feature found with node_id 'feature_ocr_1' in this
                      session.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X PATCH \
              https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/features/feature_ocr_1/update-status/ \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "new_status": "Approved",
                "comment": "Document manually verified by compliance."
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.sessions.update_feature_status(
                "11111111-2222-3333-4444-555555555555",
                "feature_ocr_1",
                new_status="Approved",
                comment="Document manually verified by compliance.",
            )
            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.updateFeatureStatus(
              "11111111-2222-3333-4444-555555555555",
              "feature_ocr_1",
              {
                new_status: "Approved",
                comment: "Document manually verified by compliance.",
              },
            );
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateFeatureStatus(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_ocr_1\", didit.SessionsUpdateFeatureStatusParams{\n\tNewStatus: \"Approved\",\n\tComment:   didit.String(\"Document manually verified by compliance.\"),\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.SessionsUpdateFeatureStatusParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.sessions().updateFeatureStatus("11111111-2222-3333-4444-555555555555",
            "feature_ocr_1", SessionsUpdateFeatureStatusParams.builder()
                    .newStatus(SessionsUpdateFeatureStatusParams.NewStatus.of("Approved"))
                    .comment("Document manually verified by compliance.")
                    .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->updateFeatureStatus('11111111-2222-3333-4444-555555555555',
            'feature_ocr_1', [
                'new_status' => 'Approved',
                'comment' => 'Document manually verified by compliance.',
            ]);

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

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

            result = didit.sessions.update_feature_status(
              "11111111-2222-3333-4444-555555555555",
              "feature_ocr_1",
              new_status: "Approved",
              comment: "Document manually verified by compliance."
            )
            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.UpdateFeatureStatusAsync("11111111-2222-3333-4444-555555555555",
            "feature_ocr_1", new SessionsUpdateFeatureStatusParams

            {
                NewStatus = "Approved",
                Comment = "Document manually verified by compliance.",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    FeatureStatusOverride:
      type: object
      description: >-
        Satu penimpaan status pemeriksaan (fitur) yang dibuat dengan `PATCH
        /v3/session/{sessionId}/features/{nodeId}/update-status/`: apa yang
        diubahnya, apakah sudah diterapkan atau masih menunggu orang tersebut
        menyelesaikan alur, siapa yang meminta dan alasannya.
      required:
        - id
        - node_id
        - feature_type
        - feature_model
        - previous_status
        - new_status
        - state
        - forced
        - reason
        - requested_by
        - requested_at
        - applied_at
        - cancelled_at
        - cancel_reason
      properties:
        id:
          type: string
          format: uuid
          description: Pengenal penimpaan (override). Teruskan ke endpoint pembatalan.
          example: 7c9e6679-7425-40de-944b-e07fc1f90ae7
        node_id:
          type: string
          description: >-
            Node alur kerja yang disebutkan dalam permintaan (`default` untuk
            langkah tanpa node).
          example: feature_ocr_1
        feature_type:
          type: string
          description: >-
            `feature_type` yang diteruskan oleh permintaan, atau string kosong
            jika tidak meneruskan apa pun.
          example: ''
        feature_model:
          type: string
          description: >-
            Jenis pemeriksaan yang ditimpa, misalnya `KYC`, `Face`, `AML`, atau
            `GeolocationCheck`.
          example: KYC
        previous_status:
          type: string
          enum:
            - Not Finished
            - Approved
            - Declined
            - In Review
            - Resub Requested
          description: Status pemeriksaan saat override diminta.
          example: In Review
        new_status:
          type: string
          enum:
            - Approved
            - Declined
            - In Review
          description: Status yang ditetapkan oleh penggantian (override).
          example: Approved
        state:
          type: string
          enum:
            - applied
            - pending_until_flow_finishes
            - cancelled
          description: >-
            `applied`: pemeriksaan memiliki status baru.
            `pending_until_flow_finishes`: penggantian menunggu dan diterapkan
            saat orang tersebut menyelesaikan alur. `cancelled`: penggantian
            menunggu dan tidak pernah diterapkan (lihat `cancel_reason`).
          example: applied
        forced:
          type: boolean
          description: >-
            `true` saat penggantian diterapkan seketika saat orang tersebut
            masih berada dalam alur.
          example: false
        reason:
          type: string
          nullable: true
          description: '`comment` yang dikirim bersama permintaan, atau `null`.'
          example: Document manually verified by compliance.
        requested_by:
          type: object
          nullable: true
          description: Pihak yang meminta override, atau `null` jika tidak diketahui.
          properties:
            email:
              type: string
              format: email
              nullable: true
              description: Email pengguna konsol, atau `null` untuk kunci API dan sistem.
              example: reviewer@example.com
            name:
              type: string
              nullable: true
              description: Nama tampilan pemohon, atau `null`.
              example: Alex Reviewer
            type:
              type: string
              enum:
                - CONSOLE_USER
                - API_KEY
                - SYSTEM
              description: >-
                Pihak yang membuat permintaan: pengguna konsol, kunci API, atau
                Didit sendiri.
              example: CONSOLE_USER
        requested_at:
          type: string
          format: date-time
          description: Waktu pengesampingan diminta.
          example: '2026-10-13T09:15:00Z'
        applied_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            Waktu ketika pemeriksaan beralih ke status baru, atau `null` saat
            masih menunggu atau setelah dibatalkan.
          example: '2026-10-13T09:15:00Z'
        cancelled_at:
          type: string
          format: date-time
          nullable: true
          description: Saat penimpaan yang menunggu dibatalkan, atau `null`.
          example: null
        cancel_reason:
          type: string
          nullable: true
          enum:
            - cancelled_by_reviewer
            - replaced
            - check_changed
            - session_closed
            - null
          description: >-
            Alasan mengapa override yang tertunda tidak pernah diterapkan, atau
            `null`. `cancelled_by_reviewer`: dibatalkan dengan endpoint
            pembatalan. `replaced`: digantikan oleh override yang lebih baru
            pada pemeriksaan yang sama. `check_changed`: pengguna mengulangi
            pemeriksaan sebelum menyelesaikan alur. `session_closed`: sesi
            meninggalkan alur sebelum pengguna menyelesaikannya (ditinggalkan,
            kedaluwarsa, atau diputuskan di tengah alur).
          example: null
  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.