> ## 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 Tinjauan Sesi: Peninjauan Manual KYC

> Kirim catatan tinjauan manual atau perubahan status ke sesi verifikasi Didit. Tinjauan kepatuhan terprogram dan jejak audit, bayar per panggilan.



Prompt untuk Membuat Peninjauan Sesi
        Salin prompt ke papan klip



      
      

\<pre>

\``Goal: Push a manual decision (Approve / Decline / mark In Review) onto a Didit verification session and write an immutable audit-trail row. Programmatic equivalent of the Console manual-review buttons.

Endpoint: POST https://verification.didit.me/v3/sessions/{session_id}/reviews/
Auth header: x-api-key: YOUR_API_KEY
Content-Type: application/json

Path param:
\- session_id (UUID, REQUIRED) — verification session UUID. Must belong to the same application as the API key (cross-application writes return 404).

Request body:
\- new_status (string, REQUIRED) — one of "Approved" | "Declined" | "In Review". Workflow-internal statuses ("In Progress", "Awaiting User", "Resubmitted", "Expired", "Kyc Expired", "Abandoned", "Not Started") are NOT accepted (400).
\- comment (string, optional, max 10,000 chars) — reviewer rationale. Supports @email mentions which trigger Console notifications.

curl:
curl -s -X POST 'https://verification.didit.me/v3/sessions/8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d/reviews/' \
-H "x-api-key: $DIDIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"new_status": "Approved", "comment": "POA cross-checked against utility bill; matches address on file."}'

Response 201 (compact ReviewSerializer shape — different from the GET response):
\{
"user": "API Client",                       // actor display label
"new_status": "Approved",
"comment": "POA cross-checked...",
"created_at": "2026-04-21T16:42:50.445Z"
}
To fetch the full activity row (uuid, activity_type, previous_status, ...) call GET /v3/sessions/{session_id}/reviews/ afterwards. See /reference/data-models for the full ReviewItem shape.

Side effects:
1\. Inserts a Review row with activity_type=STATUS_UPDATED, actor_type=API_KEY.
2\. Updates Session.status to new_status if it differs from the current status.
3\. Fires the status.updated webhook on configured destinations (see /integration/webhooks).
4\. Notifies previous reviewers and @email-mentioned Console users.
NOT idempotent — every call writes a new audit row. Re-posting the same new_status when it equals the current status is a no-op for Session.status but still writes an audit entry.

Failure modes (envelope {"detail": "..."} unless noted):
\- 400 — { "new_status": ["\\"Expired\\" is not a valid choice."] } (or missing new_status)
\- 401 — missing/invalid `x-api-key` header.
\- 403 — API key valid but wrong app or revoked.
\- 404 — session UUID not found / deleted / wrong app.
\- 429 — rate-limited.

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

\</pre>



      
      

Tempel ke



## OpenAPI

````yaml id/openapi-25.json POST /v3/sessions/{session_id}/reviews/
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/sessions/{session_id}/reviews/:
    post:
      tags:
        - Sessions
      summary: Tambahkan catatan peninjauan ke jejak audit sesi
      description: >-
        Tambahkan catatan ke umpan peninjauan / aktivitas sesi Verifikasi
        Pengguna (KYC). **Endpoint ini hanya mencatat entri — tidak pernah
        mengubah sesi.** `status` sesi dibiarkan tidak berubah, tidak ada
        validasi transisi status yang dijalankan, dan tidak ada webhook yang
        dipicu. Untuk benar-benar menyetujui, menolak, atau membuka kembali sesi
        (yang juga menulis entri `STATUS_UPDATED` yang diatribusikan penuh ke
        umpan ini), gunakan `PATCH /v3/session/{session_id}/update-status/`
        sebagai gantinya.


        Kedua kolom body bersifat opsional dan objek JSON kosong diterima.
        `new_status` disimpan murni sebagai label pada entri dan menerima salah
        satu dari sepuluh nilai status sesi (peka huruf besar-kecil). Sebutan
        `@email` di dalam `comment` hanya disimpan sebagai teks biasa — sebutan
        tersebut tidak memicu notifikasi pada endpoint ini, dan
        `mentioned_emails` pada entri tetap kosong.


        Catatan tentang atribusi: entri yang dibuat di sini tidak membawa
        informasi pelaku. Di dalam umpan, entri menampilkan `actor_display:
        "Unknown"`, `actor_type: "CONSOLE_USER"`, dan `activity_type:
        "STATUS_UPDATED"` (default penyimpanan), dan kolom `user` pada body
        `201` bernilai `"Unknown"`.
      operationId: create_session_review
      parameters:
        - name: Content-Type
          in: header
          required: false
          description: Atur ke `application/json` saat mengirimkan isi JSON.
          schema:
            type: string
            example: application/json
        - name: session_id
          in: path
          required: true
          description: >-
            UUID dari sesi Verifikasi Pengguna (KYC). Harus dimiliki oleh
            aplikasi yang sama dengan kunci API — UUID lintas aplikasi, sesi
            yang dihapus, dan ID sesi Verifikasi Bisnis (KYB) semuanya
            mengembalikan `404`.
          schema:
            type: string
            format: uuid
            example: 8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                new_status:
                  type: string
                  nullable: true
                  enum:
                    - Not Started
                    - In Progress
                    - Approved
                    - Declined
                    - In Review
                    - Expired
                    - Abandoned
                    - Kyc Expired
                    - Resubmitted
                    - Awaiting User
                  description: >-
                    Label status opsional untuk dicatat pada entri. Menerima
                    nilai status sesi apa pun, peka huruf besar/kecil
                    (`"approved"` ditolak dengan `400`). Mencatat status di sini
                    **tidak** mengubah status sesi yang sebenarnya — gunakan
                    endpoint update-status untuk itu.
                  example: In Review
                comment:
                  type: string
                  nullable: true
                  description: >-
                    Catatan teks bebas opsional (tidak ada batas panjang yang
                    diberlakukan). Disimpan apa adanya; sebutan `@email` tidak
                    diproses pada endpoint ini.
                  example: Flagging for manual document re-check.
            examples:
              NoteWithStatusLabel:
                summary: Catatan yang memuat label status (status sesi tidak berubah)
                value:
                  new_status: In Review
                  comment: Flagging for manual document re-check.
              CommentOnly:
                summary: Catatan biasa tanpa label status
                value:
                  comment: Customer emailed an updated utility bill; awaiting upload.
      responses:
        '201':
          description: >-
            Entri dicatat pada jejak audit sesi. Sesi itu sendiri tidak berubah
            — `status`-nya tetap memiliki nilai sebelumnya dan tidak ada webhook
            yang dikirim. Entri baru juga muncul di bagian atas `GET …/reviews/`
            (dengan `actor_display: "Unknown"`).
          content:
            application/json:
              schema:
                type: object
                properties:
                  user:
                    type: string
                    description: >-
                      Nama tampilan penulis entri. Selalu `"Unknown"` untuk
                      entri yang dibuat melalui endpoint ini, karena tidak
                      mencatat atribusi pelaku.
                    example: Unknown
                  new_status:
                    type: string
                    nullable: true
                    enum:
                      - Not Started
                      - In Progress
                      - Approved
                      - Declined
                      - In Review
                      - Expired
                      - Abandoned
                      - Kyc Expired
                      - Resubmitted
                      - Awaiting User
                    description: >-
                      Label status yang dicatat pada entri, atau `null` jika
                      tidak ada yang dikirim. Status sesi yang sebenarnya tidak
                      terpengaruh.
                    example: In Review
                  comment:
                    type: string
                    nullable: true
                    description: >-
                      Catatan yang terekam pada entri, atau `null` jika tidak
                      ada yang dikirim.
                    example: Flagging for manual document re-check.
                  created_at:
                    type: string
                    format: date-time
                    description: Waktu ketika entri ditulis, ISO 8601 UTC.
                    example: '2026-06-12T00:18:44.466537Z'
              examples:
                NoteWithStatusLabel:
                  summary: Catatan dengan label status
                  value:
                    user: Unknown
                    new_status: In Review
                    comment: Flagging for manual document re-check.
                    created_at: '2026-06-12T00:18:44.466537Z'
                CommentOnly:
                  summary: Catatan biasa
                  value:
                    user: Unknown
                    new_status: null
                    comment: Note without status.
                    created_at: '2026-06-12T00:18:44.504157Z'
        '400':
          description: >-
            Kesalahan validasi, dikembalikan sebagai peta pesan per kolom.
            Penyebab umumnya adalah nilai `new_status` yang bukan salah satu
            dari sepuluh status yang diizinkan — pemeriksaan ini peka huruf
            besar-kecil.
          content:
            application/json:
              schema:
                type: object
                properties:
                  new_status:
                    type: array
                    items:
                      type: string
                    example:
                      - '"approved" is not a valid choice.'
              examples:
                InvalidStatusChoice:
                  summary: Nilai status huruf kecil / tidak dikenal
                  value:
                    new_status:
                      - '"approved" is not a valid choice.'
        '403':
          description: >-
            `x-api-key` tidak ada, salah format, kedaluwarsa, atau dicabut.
            Autentikasi diperiksa sebelum pencarian sesi, sehingga kunci yang
            tidak ada mengembalikan `403` meskipun UUID sesi tidak ada.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    example: You do not have permission to perform this action.
              examples:
                InvalidKey:
                  summary: Header x-api-key tidak ada atau tidak valid
                  value:
                    detail: You do not have permission to perform this action.
        '404':
          description: >-
            Tidak ada sesi Verifikasi Pengguna (KYC) dengan UUID ini yang
            terlihat oleh aplikasi Anda: UUID tidak ada, sesi telah dihapus,
            atau sesi tersebut milik aplikasi lain. ID sesi Verifikasi Bisnis
            (KYB) juga mengembalikan `404` di sini — feed ulasan hanya dapat
            diakses untuk sesi KYC.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    example: Session not found.
              examples:
                NotFound:
                  summary: UUID sesi tidak dikenal, telah dihapus, atau lintas aplikasi
                  value:
                    detail: Session not found.
        '429':
          description: >-
            Batas laju terlampaui. Periksa header respons `Retry-After` dan
            `X-RateLimit-*`. Lihat [Pembatasan
            laju](/id/integration/rate-limiting).
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: >-
            # Records an audit-trail note only -- the session's status does NOT
            change.

            curl -s -X POST
            https://verification.didit.me/v3/sessions/8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d/reviews/
            \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "new_status": "In Review",
                "comment": "Flagging for manual document re-check."
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.sessions.reviews.create(
                "8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d",
                new_status="In Review",
                comment="Flagging for manual document re-check.",
            )
            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.reviews.create("8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d",
            {
              new_status: "In Review",
              comment: "Flagging for manual document re-check.",
            });

            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Reviews.Create(ctx, \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", didit.SessionsReviewsCreateParams{\n\tNewStatus: didit.Some(didit.SessionsReviewsCreateParamsNewStatus(\"In Review\")),\n\tComment:   didit.String(\"Flagging for manual document re-check.\"),\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.SessionsReviewsCreateParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.sessions().reviews().create("8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d",
            SessionsReviewsCreateParams.builder()
                    .newStatus(SessionsReviewsCreateParams.NewStatus.of("In Review"))
                    .comment("Flagging for manual document re-check.")
                    .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->reviews->create('8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d',
            [
                'new_status' => 'In Review',
                'comment' => 'Flagging for manual document re-check.',
            ]);

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

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

            result = didit.sessions.reviews.create(
              "8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d",
              new_status: "In Review",
              comment: "Flagging for manual document re-check."
            )
            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.Reviews.CreateAsync("8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d",
            new SessionsReviewsCreateParams

            {
                NewStatus = new SessionsReviewsCreateParamsNewStatus("In Review"),
                Comment = "Flagging for manual document re-check.",
            });

            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.