> ## 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 PDF Riwayat Pengguna: Semua Sesi Pengguna

> Unduh satu PDF yang memuat semua sesi verifikasi pengguna yang dapat dilaporkan, dikelompokkan per vendor_data, untuk audit, SAR, dan ekspor kepatuhan berkala.



Prompt PDF Riwayat Pengguna
        Salin prompt ke papan klip



      
      

\<pre>

\`Goal: download one audit-ready PDF containing the full verification history of a Didit user.

Endpoint: GET https://verification.didit.me/v3/users/{vendor_data}/generate-pdf/
Auth header: x-api-key: YOUR_API_KEY

Path param:
\- vendor_data (string, REQUIRED) - your own identifier for the user, the same value you pass when creating sessions. Free-form string, NOT a UUID. URL-encode it; it cannot contain "/".

curl - save the PDF to disk:
curl --fail 'https://verification.didit.me/v3/users/user-abc-123/generate-pdf/' \
-H 'x-api-key: YOUR_API_KEY' \
\--output user-history.pdf

Response:
\- Body is binary (application/pdf). DO NOT parse as JSON.
\- Content-Disposition: attachment; filename=user_{didit_internal_id}.pdf
\- Content: a cover page (profile summary, feature status, session index) followed by the standard report of every included session, oldest first. Each session report is the same document GET /v3/session/{session_id}/generate-pdf/ returns.
\- Only sessions in "Approved", "Declined", "In Review" or "Kyc Expired" are included, capped at the 20 most recent. The cover states when older sessions were left out.
\- Identical to the Console export at User detail → Actions → Download PDF. White-label logo and privacy-policy URL apply when enabled.
\- Rendering is synchronous and takes a few seconds per session: use a read timeout of at least 120s and stream the body to disk.

Failure modes (envelope {"detail": "..."}):
\- 401 - no credentials supplied.
\- 403 - missing API key (a wrong, revoked or expired key gets 401), a Console user token instead of an API key, OR the user exists but has no session in a reportable status ("This user has no sessions in review, declined, approved or kyc expired to report.").
\- 404 - {"detail": "User not found."} - no user with that vendor_data in the application behind the API key. A key can never export a user of another application.
\- 429 - shares the PDF rate limit with the per-session endpoint (50 requests per minute per credential). Wait Retry-After seconds.

Trailing slash: the canonical route ends with "/". Call it as written above.

When to call:
\- Periodic compliance exports of a customer's whole KYC history.
\- SAR / regulator attachments that must cover every verification of one person.
\- Pulling a user's history into your own back office without a Console login.

Related: GET /v3/session/{session_id}/generate-pdf/ for a single session; GET /v3/sessions/?vendor_data=... for the JSON list of sessions.

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

\</pre>



      
      

Tempel ke

## RingkasanMengembalikan satu PDF berisi riwayat verifikasi lengkap dari [entitas Pengguna](https://docs.didit.me/id/entities/users/overview.md), berdasarkan `vendor_data`.
Dokumen ini sama dengan yang dihasilkan Console melalui **User detail → Actions → Download PDF**, sehingga tim kepatuhan dapat mengotomatisasi ekspor alih-alih mengklik satu per satu untuk setiap pengguna.Laporan berisi:- **Halaman sampul** dengan ringkasan profil (nama, tanggal lahir, negara bagian penerbit, email dan nomor telepon yang disetujui), status terbaru dari setiap fitur, penghitung sesi, dan indeks sesi yang disertakan.
- **Satu laporan sesi lengkap untuk setiap sesi yang disertakan**, diurutkan secara kronologis (yang tertua lebih dulu). Setiap laporan sama dengan yang dikembalikan [Generate PDF](https://docs.didit.me/id/sessions-api/generate-pdf.md) untuk sesi tersebut secara terpisah.## Sesi yang memenuhi syarat dan batasnyaHanya sesi Verifikasi Pengguna (KYC) dengan status `Approved`, `Declined`, `In Review` atau `Kyc Expired` yang disertakan. Sesi dengan status lain (`Not Started`, `In Progress`, `Abandoned`, `Expired`, …) dilewati.Laporan dibatasi pada **20 sesi terbaru** yang memenuhi syarat. Jika pengguna memiliki lebih banyak sesi, 20 sesi terbaru akan disertakan dan halaman sampul menyatakan berapa banyak sesi lama yang tidak disertakan. Gunakan [List sessions](https://docs.didit.me/id/sessions-api/list-sessions.md) dengan filter `vendor_data` jika Anda memerlukan daftar lengkap dalam format JSON.## ResponsIsi respons adalah PDF itu sendiri (`application/pdf`), bukan pembungkus JSON atau URL unduhan. Header `Content-Disposition` berbunyi `attachment; filename=user_<didit_internal_id>.pdf`, dengan `didit_internal_id` adalah pengidentifikasi Didit yang stabil milik pengguna.## White LabelJika kustomisasi White Label diaktifkan pada aplikasi Anda, halaman sampul dan setiap laporan sesi memuat logo dan URL kebijakan privasi Anda, bukan branding Didit, persis seperti endpoint per sesi. Atur di **Console → Customization**.## Cache dan latensiTidak ada yang di-cache: setiap panggilan merender ulang laporan dari data terkini, sehingga laporan yang diminta setelah tinjauan manual mencerminkan keputusan peninjau. Dua panggilan dapat menghasilkan file dengan byte yang berbeda; arsipkan file yang diunduh jika Anda memerlukan salinan yang tidak berubah.Perenderan bersifat sinkron dan mengunduh setiap gambar yang tersimpan dari setiap sesi yang disertakan, sehingga pembuatan laporan untuk pengguna dengan banyak sesi yang berisi banyak media dapat memerlukan waktu puluhan detik. Gunakan batas waktu baca klien yang longgar (disarankan 120 detik) dan alirkan isi respons ke disk. Pembuatan dihentikan pada batas waktu sisi server, bukan berjalan terus sampai klien Anda menyerah: jika batas itu tercapai, laporan tetap mengembalikan PDF yang valid dengan sesi-sesi terbaru, dan halaman sampul menyatakan berapa sesi yang dihilangkan.## Garis miring di akhirRute kanonik diakhiri dengan garis miring (`…/generate-pdf/`). Permintaan tanpa garis miring dilayani langsung dengan respons yang sama: tidak ada redirect `301`, sehingga tidak ada klien yang harus mengikuti redirect dan `curl` tidak memerlukan `-L`. Gunakan URL dengan garis miring seperti pada contoh; itulah bentuk yang ditampilkan dalam spesifikasi OpenAPI dan log Anda.## Error| Status | Kapan | `detail` |
| - | - | - |
| `401` | Tidak ada header `x-api-key` (dan tidak ada token `Authorization: Bearer`). | `You must be authenticated with a valid access token to access this endpoint.` |
| `403` | Kunci API tidak valid atau sudah dicabut, atau token pengguna Console digunakan sebagai pengganti kunci API. | `You do not have permission to perform this action.` |
| `403` | Pengguna ada, tetapi tidak ada sesinya yang berada dalam status yang dapat dilaporkan. | `This user has no sessions in review, declined, approved or kyc expired to report.` |
| `404` | Tidak ada pengguna dengan `vendor_data` ini di aplikasi yang terkait dengan kunci API, termasuk pengguna yang milik aplikasi lain. | `User not found.` |
| `429` | Lebih dari 50 pembuatan PDF per menit dari kredensial yang sama. Kuota ini dibagi dengan [Generate PDF](https://docs.didit.me/id/sessions-api/generate-pdf.md). Tunggu selama `Retry-After` detik. | `Session PDF generation rate limit exceeded. You can make up to 50 requests per minute.` |## Contoh> [tab] curl
>
> ```bash theme={null}
> curl --fail 'https://verification.didit.me/v3/users/user-abc-123/generate-pdf/' \
>   -H 'x-api-key: YOUR_API_KEY' \
>   --output user-history.pdf
> ```> [tab] Python
>
> ```python theme={null}
> import requests
>
> response = requests.get(
>     "https://verification.didit.me/v3/users/user-abc-123/generate-pdf/",
>     headers={"x-api-key": "YOUR_API_KEY"},
>     stream=True,
>     timeout=120,
> )
> response.raise_for_status()
> with open("user-history.pdf", "wb") as fh:
>     for chunk in response.iter_content(chunk_size=8192):
>         fh.write(chunk)
> ```> [tab] JavaScript
>
> ```javascript theme={null}
> import { writeFile } from 'node:fs/promises';
>
> const vendorData = encodeURIComponent('user-abc-123');
> const response = await fetch(
>   `https://verification.didit.me/v3/users/${vendorData}/generate-pdf/`,
>   { headers: { 'x-api-key': process.env.DIDIT_API_KEY } },
> );
> if (!response.ok) throw new Error(`PDF generation failed: HTTP ${response.status}`);
> await writeFile('user-history.pdf', Buffer.from(await response.arrayBuffer()));
> ```## IzinSetiap kunci API aktif dari aplikasi dapat memanggil endpoint ini. Kunci API Didit **terbatas pada aplikasi, bukan pada peran**: [peran dan izin](https://docs.didit.me/id/console/roles-permissions.md) Console (`read:users` dan lainnya) menentukan apa yang dapat dilakukan *seseorang* di Console, dan tidak dievaluasi untuk trafik Management API. Sebuah kunci hanya dapat mengekspor pengguna dari aplikasinya sendiri.## Terkait- [Generate PDF](https://docs.didit.me/id/sessions-api/generate-pdf.md): laporan yang sama untuk satu sesi
- [Riwayat KYC pengguna](https://docs.didit.me/id/entities/users/kyc-history.md): mencantumkan dan memeriksa sesi pengguna dalam format JSON
- [Ekspor PDF & CSV](https://docs.didit.me/id/console/export-pdf-csv.md): sisi Console dari kedua ekspor
- [Ambil pengguna](https://docs.didit.me/id/management-api/users/get.md): profil pengguna dan peta fitur dalam format JSON


## OpenAPI

````yaml id/openapi-25.json GET /v3/users/{vendor_data}/generate-pdf/
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/users/{vendor_data}/generate-pdf/:
    get:
      tags:
        - Users
      summary: Unduh laporan PDF riwayat pengguna lengkap
      description: >-
        Render dan unduh satu PDF siap kepatuhan yang berisi riwayat verifikasi
        lengkap dari pengguna yang diidentifikasi oleh `vendor_data`. Ini adalah
        dokumen yang sama yang dihasilkan Console dari **User detail → Actions →
        Download PDF**, sehingga ekspor kepatuhan berkala tidak lagi memerlukan
        seseorang yang mengeklik di Console.


        **Isi laporan.** Halaman sampul dengan ringkasan profil (nama, tanggal
        lahir, negara bagian penerbit, email dan telepon yang disetujui), status
        terbaru dari setiap fitur, penghitung sesi, dan indeks sesi yang
        disertakan — diikuti oleh laporan standar dari setiap sesi yang
        disertakan, dalam urutan kronologis (paling lama terlebih dahulu).
        Setiap laporan sesi adalah dokumen yang sama yang dikembalikan oleh `GET
        /v3/session/{sessionId}/generate-pdf/` untuk sesi tersebut.


        **Sesi yang memenuhi syarat.** Hanya sesi Verifikasi Pengguna (KYC)
        dalam status `Approved`, `Declined`, `In Review`, atau `Kyc Expired`
        yang disertakan; sesi dalam status lainnya dilewati. Jika pengguna tidak
        memiliki sesi dalam salah satu status tersebut, endpoint akan
        mengembalikan `403` — lihat di bawah.


        **Batas maksimal.** Laporan dibatasi hingga **20 sesi terbaru** yang
        dapat dilaporkan. Jika pengguna memiliki lebih banyak, 20 sesi terbaru
        akan disertakan dan halaman sampul menyatakan berapa banyak sesi lama
        yang ditinggalkan. Gunakan `GET /v3/sessions/?vendor_data=…` untuk
        daftar lengkap dalam format JSON.


        **Branding.** Jika aplikasi Anda memiliki kustomisasi White Label,
        sampul dan setiap laporan sesi akan dirender dengan logo dan URL
        kebijakan privasi Anda; jika tidak, laporan akan menggunakan branding
        Didit. Laporan dirender dalam bahasa Inggris — tidak ada parameter
        bahasa.


        **Tanpa caching.** Setiap panggilan merender ulang PDF dari data saat
        ini, sehingga laporan yang dibuat setelah peninjauan manual mencerminkan
        keputusan peninjau. Dua panggilan untuk pengguna yang sama dapat
        menghasilkan berkas yang berbeda secara byte — arsipkan berkas yang
        diunduh jika Anda memerlukan salinan yang tidak dapat diubah.


        **Latensi.** Rendering bersifat sinkron dan mengunduh setiap gambar
        tersimpan dari setiap sesi yang disertakan, sehingga pengguna dengan
        banyak sesi yang memuat banyak media dapat membutuhkan waktu puluhan
        detik. Gunakan batas waktu pembacaan klien yang cukup longgar
        (disarankan 120 dtk) dan alirkan isi respons ke disk. Pembuatan laporan
        akan berhenti pada alokasi waktu sisi server alih-alih terus berjalan
        sampai klien Anda menyerah: jika alokasi waktu tersebut tercapai,
        respons tetap berupa PDF valid yang berisi sesi-sesi terbaru, dan sampul
        akan menyatakan berapa banyak yang diabaikan.


        **Cakupan.** Pengguna diselesaikan di dalam aplikasi yang memiliki kunci
        API. Kunci tidak akan pernah dapat mengekspor pengguna dari aplikasi
        lain — pengguna tersebut tidak ada baginya dan endpoint akan
        mengembalikan `404`.


        **Garis miring penutup.** Rute kanonikal diakhiri dengan garis miring
        penutup (`…/generate-pdf/`). Permintaan tanpanya akan dilayani langsung
        dengan respons yang sama — tidak ada pengalihan `301`, sehingga klien
        tidak perlu mengikuti pengalihan dan `curl` tidak memerlukan `-L`.
        Gunakan URL bergaris miring seperti pada contoh.
      operationId: get_user_generate_pdf
      parameters:
        - name: vendor_data
          in: path
          required: true
          schema:
            type: string
          description: >-
            Pengidentifikasi unik Anda untuk pengguna — string bentuk bebas
            (BUKAN UUID). Ini adalah nilai yang sama dengan yang Anda teruskan
            sebagai `vendor_data` saat membuat sesi pengguna, dicocokkan persis
            seperti yang dikirim. Lakukan URL encoding pada nilai tersebut;
            nilai yang mengandung `/` tidak dapat dituju oleh rute ini.
          example: user-abc-123
      responses:
        '200':
          description: >-
            Dokumen PDF hasil render, dikembalikan langsung sebagai biner
            `application/pdf` — tidak ada pembungkus JSON dan tidak ada
            pengalihan URL unduhan. Isi dimulai dengan magic bytes `%PDF`.
            Simpan ke file `.pdf` atau alirkan langsung ke pemanggil Anda.
          headers:
            Content-Disposition:
              description: >-
                `attachment; filename=user_{didit_internal_id}.pdf` — file
                diberi nama sesuai ID Didit stabil milik pengguna
                (`didit_internal_id` pada `GET /v3/users/{vendor_data}/`), bukan
                berdasarkan `vendor_data`.
              schema:
                type: string
                example: >-
                  attachment;
                  filename=user_f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418.pdf
            Content-Length:
              description: >-
                Ukuran total PDF dalam byte; badan respons tidak dibagi menjadi
                beberapa chunk.
              schema:
                type: integer
                example: 148213
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        '401':
          description: >-
            Tidak ada kredensial yang diberikan. Permintaan ke jalur
            `/v3/users/*` tanpa header `x-api-key` (atau token `Authorization:
            Bearer`) akan ditolak oleh middleware autentikasi sebelum mencapai
            API.
          content:
            application/json:
              examples:
                Missing credentials:
                  value:
                    detail: >-
                      You must be authenticated with a valid access token to
                      access this endpoint.
        '403':
          description: >-
            Kegagalan otorisasi atau kelayakan. Bedakan keduanya berdasarkan
            string `detail`:


            - `"You do not have permission to perform this action."` — kunci API
            tidak valid atau dicabut, atau permintaan membawa token pengguna
            Console alih-alih kunci API aplikasi.

            - `"This user has no sessions in review, declined, approved or kyc
            expired to report."` — pengguna ada di aplikasi Anda tetapi belum
            ada sesinya yang berada dalam status yang dapat dilaporkan (misalnya
            setiap sesi masih `In Progress`, atau pengguna dibuat melalui `POST
            /v3/users/create/` dan belum pernah diverifikasi). Tunggu webhook
            `status.updated` sebelum meminta laporan.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    example: >-
                      This user has no sessions in review, declined, approved or
                      kyc expired to report.
              examples:
                Invalid credentials:
                  summary: >-
                    Kunci API dicabut atau tidak valid, atau token pengguna
                    Console
                  value:
                    detail: You do not have permission to perform this action.
                No reportable sessions:
                  summary: >-
                    Pengguna ada tetapi tidak memiliki sesi Disetujui / Ditolak
                    / Dalam Peninjauan / KYC Kedaluwarsa
                  value:
                    detail: >-
                      This user has no sessions in review, declined, approved or
                      kyc expired to report.
        '404':
          description: >-
            Tidak ada pengguna dengan `vendor_data` yang diberikan di aplikasi
            di balik kunci API tersebut. Pengguna dari aplikasi lain tidak
            terlihat oleh kunci ini dan mengembalikan `404` yang sama.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    example: User not found.
              examples:
                Unknown user:
                  summary: >-
                    vendor_data tidak cocok dengan pengguna aplikasi ini mana
                    pun
                  value:
                    detail: User not found.
        '429':
          description: >-
            Batas laju terlampaui. Pembuatan PDF memiliki batas khusus sebesar
            **50 permintaan per menit per kredensial** (kunci API, token Bearer,
            atau IP sumber saat tidak terautentikasi), yang dibagi antara
            endpoint ini dan `GET /v3/session/{sessionId}/generate-pdf/`, selain
            batas GET global 600/menit. Tunggu selama `Retry-After` detik (juga
            tercermin dalam header `X-RateLimit-*`), lalu coba lagi. Laporan
            tidak di-cache di sisi server, jadi unduh setiap laporan satu kali
            dan simpan filenya alih-alih mengambilnya kembali.
          headers:
            Retry-After:
              description: >-
                Detik yang harus ditunggu sebelum mencoba lagi mengirimkan
                permintaan.
              schema:
                type: integer
                minimum: 1
                example: 30
            X-RateLimit-Limit:
              description: >-
                Jumlah maksimum pembuatan PDF yang diizinkan dalam jendela saat
                ini (50).
              schema:
                type: integer
                example: 50
            X-RateLimit-Remaining:
              description: Permintaan yang tersisa dalam jendela saat ini.
              schema:
                type: integer
                example: 0
            X-RateLimit-Reset:
              description: Timestamp Unix (detik) saat jendela saat ini direset.
              schema:
                type: integer
                example: 1750000000
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: >-
                      Penjelasan pelanggaran batas laju yang mudah dibaca
                      manusia.
                    example: >-
                      Session PDF generation rate limit exceeded. You can make
                      up to 50 requests per minute.
              examples:
                Throttled:
                  summary: >-
                    Lebih dari 50 pembuatan PDF dalam satu menit dari kredensial
                    yang sama
                  value:
                    detail: >-
                      Session PDF generation rate limit exceeded. You can make
                      up to 50 requests per minute.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |-
            curl --fail \
              'https://verification.didit.me/v3/users/user-abc-123/generate-pdf/' \
              -H 'x-api-key: YOUR_API_KEY' \
              --output user-history.pdf
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            content = client.users.generate_pdf(
                "user-abc-123",
            )
            with open("download.pdf", "wb") as file:
                file.write(content)
        - lang: javascript
          label: Node.js
          source: >-
            import { writeFile } from "node:fs/promises";

            import Didit from "@didit-protocol/sdk-node";


            // Reads DIDIT_API_KEY.

            const didit = new Didit();


            const content = await didit.users.generatePdf("user-abc-123");

            await writeFile("download.pdf", Buffer.from(await
            content.arrayBuffer()));
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Users.GeneratePDF(ctx, \"user-abc-123\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
        - lang: java
          label: Java
          source: |-
            import java.nio.file.Path;
            import me.didit.Didit;

            // Reads DIDIT_API_KEY.
            Didit client = new Didit();

            client.users().generatePdf("user-abc-123")
                    .writeTo(Path.of("download.pdf"));
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;

            // Reads DIDIT_API_KEY.
            $didit = new DiditClient();

            $content = $didit->users->generatePdf('user-abc-123');
            $content->saveTo('download.pdf');
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

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

            content = didit.users.generate_pdf("user-abc-123")
            File.binwrite("download.pdf", content)
        - lang: csharp
          label: .NET
          source: |-
            using System;
            using Didit;

            // Reads DIDIT_API_KEY.
            using var client = new DiditClient();

            var content = await client.Users.GeneratePdfAsync("user-abc-123");
            await content.SaveToAsync("download.pdf");
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.