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

# 用户历史 PDF API：用户的全部会话

> 下载一份 Didit 生成的 PDF，汇总某位用户所有可报告的验证会话，按 vendor_data 索引，用于审计、SAR 及定期合规导出。



用户历史 PDF 提示词
        将提示词复制到剪贴板



      
      

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



      
      

粘贴到

## 概述返回一个 PDF 文件，包含某个[用户实体](https://docs.didit.me/zh/entities/users/overview.md)的完整验证历史，以 `vendor_data` 作为键。
它与 Console 中 **User detail → Actions → Download PDF** 生成的文档相同，因此合规团队可以自动导出，而无需为每位用户逐个点击。该报告包含：- **封面页**，包括资料摘要（姓名、出生日期、签发州/省、已通过的邮箱和电话）、每项功能的最新状态、会话计数，以及所含会话的索引。
- **每个所含会话各对应一份完整的会话报告**，按时间顺序排列（最早的在前）。每份报告都与 [生成 PDF](https://docs.didit.me/zh/sessions-api/generate-pdf.md) 为该会话单独返回的报告相同。## 符合条件的会话与上限仅包含状态为 `Approved`、`Declined`、`In Review` 或 `Kyc Expired` 的用户验证（KYC）会话。其他任何状态（`Not Started`、`In Progress`、`Abandoned`、`Expired` 等）的会话都会被跳过。报告最多包含 **最近的 20 个** 可报告会话。如果用户的会话超过 20 个，则包含最新的 20 个，封面页会注明省略了多少个较早的会话。如需以 JSON 格式获取完整列表，请使用按 `vendor_data` 过滤的 [列出会话](https://docs.didit.me/zh/sessions-api/list-sessions.md)。## 响应响应体即为 PDF 本身（`application/pdf`），而不是 JSON 包装或下载链接。`Content-Disposition` 响应头为 `attachment; filename=user_<didit_internal_id>.pdf`，其中 `didit_internal_id` 是用户稳定的 Didit 标识符。## 白标在您的应用中启用白标定制后，封面页和每份会话报告都会显示您的 Logo 和隐私政策 URL，而不是 Didit 品牌标识，与单会话接口的行为完全一致。请在 **Console → Customization** 中进行配置。## 缓存与延迟不做任何缓存：每次调用都会根据当前数据重新生成报告，因此在人工审核之后请求的报告会反映审核员的决定。两次调用可能生成字节内容不同的文件；如需不可变副本，请归档下载的文件。渲染是同步进行的，并会下载所含每个会话中存储的全部图片，因此对于媒体文件较多会话的用户，可能需要数十秒。请设置较长的客户端读取超时（建议 120 秒），并将响应体流式写入磁盘。生成过程会受服务端时间预算限制，而不会一直运行到客户端放弃等待为止：若达到该预算，报告仍会返回有效的 PDF，包含最近的会话，封面页会注明省略了多少个会话。## 结尾斜杠规范路由以斜杠结尾（`…/generate-pdf/`）。不带斜杠的请求会直接返回相同的响应：不存在 `301` 重定向，因此任何客户端都无需跟随重定向，`curl` 也无需 `-L` 参数。请使用示例中带斜杠的 URL；这也是 OpenAPI 规范和您的日志中所显示的形式。## 错误| 状态码 | 触发条件 | `detail` |
| - | - | - |
| `401` | 缺少 `x-api-key` 请求头（且没有 `Authorization: Bearer` 令牌）。 | `You must be authenticated with a valid access token to access this endpoint.` |
| `403` | API 密钥无效或已被吊销，或使用了 Console 用户令牌而非 API 密钥。 | `You do not have permission to perform this action.` |
| `403` | 用户存在，但其没有任何会话处于可报告的状态。 | `This user has no sessions in review, declined, approved or kyc expired to report.` |
| `404` | 在该 API 密钥所属应用中没有此 `vendor_data` 对应的用户，包括属于其他应用的用户。 | `User not found.` |
| `429` | 同一凭证每分钟生成 PDF 次数超过 50 次。该配额与 [生成 PDF](https://docs.didit.me/zh/sessions-api/generate-pdf.md) 共享。请等待 `Retry-After` 秒。 | `Session PDF generation rate limit exceeded. You can make up to 50 requests per minute.` |## 示例> [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()));
> ```## 权限该应用下任何处于活动状态的 API 密钥均可调用此接口。Didit 的 API 密钥是**按应用限定，而非按角色限定**的：Console 中的[角色与权限](https://docs.didit.me/zh/console/roles-permissions.md)（`read:users` 等）决定的是*用户本人*可以在 Console 中执行哪些操作，对 Management API 的请求不会进行这些权限校验。密钥只能导出其所属应用中的用户。## 相关内容- [生成 PDF](https://docs.didit.me/zh/sessions-api/generate-pdf.md)：针对单个会话的相同报告
- [用户 KYC 历史记录](https://docs.didit.me/zh/entities/users/kyc-history.md)：以 JSON 格式列出和查看用户的会话
- [导出 PDF 与 CSV](https://docs.didit.me/zh/console/export-pdf-csv.md)：这两种导出在 Console 中的操作入口
- [获取用户](https://docs.didit.me/zh/management-api/users/get.md)：以 JSON 格式获取用户资料和功能映射


## OpenAPI

````yaml zh/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。使用 x-api-key 请求头进行身份验证。
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/users/{vendor_data}/generate-pdf/:
    get:
      tags:
        - Users
      summary: 下载完整的用户历史记录 PDF 报告
      description: >-
        渲染并下载一份符合合规要求的 PDF，其中包含通过 `vendor_data` 标识的用户的完整验证历史记录。这与 Console 中通过
        **User detail → Actions → Download PDF** 生成的文件相同，因此定期的合规导出不再需要专人在
        Console 中手动点击。


        **报告包含的内容。**
        包含个人资料摘要的封面（姓名、出生日期、签发国家/地区、已通过的邮箱和电话）、每项功能的最新状态、会话计数器以及所包含会话的索引，随后按时间顺序（从最早开始）附上每个所包含会话的标准报告。每个会话报告与针对该会话调用
        `GET /v3/session/{sessionId}/generate-pdf/` 返回的文件相同。


        **符合条件的会话。** 仅包含处于 `Approved`、`Declined`、`In Review` 或 `Kyc Expired`
        状态的用户验证（KYC）会话；任何处于其他状态的会话都会被跳过。如果用户没有任何处于上述状态之一的会话，该 endpoint 将返回
        `403`（见下文）。


        **上限。** 报告最多包含**最近 20 个**可报告会话。当用户拥有的会话超过此数量时，将包含最新的 20
        个，并在封面上说明遗漏了多少较早的会话。使用 `GET /v3/sessions/?vendor_data=…` 获取完整的 JSON 列表。


        **品牌定制。** 如果您的应用启用了白标定制，封面和每个会话报告都将使用您的 Logo 和隐私政策 URL 进行渲染；否则将带有 Didit
        品牌标识。报告以英文渲染，没有语言参数。


        **无缓存。** 每次调用都会根据当前数据重新渲染
        PDF，因此在人工审核后生成的报告会反映审核员的决策。针对同一用户的两次调用可能会生成字节不同的文件。如果您需要不可变的副本，请对下载的文件进行归档。


        **延迟。**
        渲染过程是同步的，并且会下载所包含每个会话的所有已存储图片，因此对于包含较多富媒体会话的用户，可能需要数十秒。建议设置宽松的客户端读取超时时间（推荐
        120 秒）并将响应体流式传输到磁盘。生成过程受服务端时间预算限制，而不会一直运行到客户端放弃：如果达到该预算，响应仍然是包含最近会话的有效
        PDF，且封面会说明省略了多少次会话。


        **作用域。** 用户在拥有该 API 密钥的应用内解析。密钥绝不能导出另一个应用的用户；对该密钥而言，该用户不存在，且该 endpoint
        将返回 `404`。


        **末尾斜杠。** 规范路由以末尾斜杠（`…/generate-pdf/`）结尾。不带斜杠的请求将直接以相同响应提供服务；不存在 `301`
        重定向，因此客户端无需跟随重定向，`curl` 也不需要 `-L`。请按照示例使用带斜杠的 URL。
      operationId: get_user_generate_pdf
      parameters:
        - name: vendor_data
          in: path
          required: true
          schema:
            type: string
          description: >-
            您对该用户的唯一标识符，为自由格式字符串（非 UUID）。该值与您在创建该用户会话时作为 `vendor_data`
            传入的值相同，按发送的内容精确匹配。请对其进行 URL 编码；包含 `/` 的值无法由此路由寻址。
          example: user-abc-123
      responses:
        '200':
          description: >-
            渲染生成的 PDF 文档，直接以二进制 `application/pdf` 形式返回，没有 JSON 包装，也没有下载 URL
            重定向。正文以 `%PDF` 魔数开头。可将其保存为 `.pdf` 文件或直接流式传输给您的调用方。
          headers:
            Content-Disposition:
              description: >-
                `attachment; filename=user_{didit_internal_id}.pdf`：文件以用户稳定的
                Didit 标识符（`GET /v3/users/{vendor_data}/` 上的
                `didit_internal_id`）命名，而非以 `vendor_data` 命名。
              schema:
                type: string
                example: >-
                  attachment;
                  filename=user_f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418.pdf
            Content-Length:
              description: PDF 的总大小（以字节为单位）；正文未分块。
              schema:
                type: integer
                example: 148213
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        '401':
          description: >-
            未提供凭证。对 `/v3/users/*` 路径的请求如果不包含 `x-api-key` 请求头（或 `Authorization:
            Bearer` token），将在到达 API 之前被身份验证中间件拒绝。
          content:
            application/json:
              examples:
                Missing credentials:
                  value:
                    detail: >-
                      You must be authenticated with a valid access token to
                      access this endpoint.
        '403':
          description: >-
            授权或资格失败。可通过 `detail` 字符串区分这两者：


            - `"You do not have permission to perform this action."` — API
            密钥无效或已撤销，或者请求携带了控制台用户 token 而非应用 API 密钥。

            - `"This user has no sessions in review, declined, approved or kyc
            expired to report."` — 该用户存在于您的应用中，但其会话均未处于可生成报告的状态（例如所有会话仍为 `In
            Progress`，或者该用户是通过 `POST /v3/users/create/` 创建且从未进行过验证）。请等待
            `status.updated` Webhook 触发后再请求报告。
          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: 已撤销或无效的 API 密钥，或 Console 用户 token
                  value:
                    detail: You do not have permission to perform this action.
                No reportable sessions:
                  summary: 用户存在，但没有已通过 / 已拒绝 / 审核中 / KYC 已过期会话
                  value:
                    detail: >-
                      This user has no sessions in review, declined, approved or
                      kyc expired to report.
        '404':
          description: 该 API 密钥关联的应用中不存在具有所提供 `vendor_data` 的用户。其他应用的用户对该密钥不可见，并同样返回 `404`。
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    example: User not found.
              examples:
                Unknown user:
                  summary: vendor_data 与该应用的任何用户均不匹配
                  value:
                    detail: User not found.
        '429':
          description: >-
            超出速率限制。除全局 600 次/分钟的 GET 限制外，PDF 生成还具有**每个凭证每分钟 50 次请求**的专属限制（API
            密钥、Bearer token，或未认证时的源 IP），由本 endpoint 与 `GET
            /v3/session/{sessionId}/generate-pdf/` 共享。请等待 `Retry-After` 秒（也会反映在
            `X-RateLimit-*` 响应头中），然后重试。报告不会在服务端缓存，因此请下载每份报告一次并保存文件，而不是重复获取。
          headers:
            Retry-After:
              description: 重试请求前需等待的秒数。
              schema:
                type: integer
                minimum: 1
                example: 30
            X-RateLimit-Limit:
              description: 当前时间窗口内允许的最大 PDF 生成次数（50）。
              schema:
                type: integer
                example: 50
            X-RateLimit-Remaining:
              description: 当前时间窗口内剩余的请求数。
              schema:
                type: integer
                example: 0
            X-RateLimit-Reset:
              description: 当前窗口重置的 Unix 时间戳（秒）。
              schema:
                type: integer
                example: 1750000000
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: 超出速率限制的便于人类阅读的说明。
                    example: >-
                      Session PDF generation rate limit exceeded. You can make
                      up to 50 requests per minute.
              examples:
                Throttled:
                  summary: 同一凭证在一分钟内生成的 PDF 超过 50 份
                  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: >-
        您的应用 API 密钥，可在 Business Console 的“开发者 -> API
        密钥”中获取。主密钥拥有完整访问权限。指定名称的密钥可设置作用域：针对每个资源设为无权限、只读或读写，限定于特定工作流或已通过的会话、限定于
        IP 地址列表，以及设置到期日期。401 表示密钥错误、已撤销或已过期；403 表示未发送密钥、密钥无权访问该资源或操作，或请求来自其 IP
        列表之外的地址；在会话路由上返回 404 表示该会话不在该密钥允许的工作流或状态范围内。没有媒体访问权限的密钥获取到的图片、视频和 PDF
        URL 将为 null；没有会话写入权限的密钥获取到的会话链接和 token 将为 null。请参阅
        https://docs.didit.me/console/api-keys。

````

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