> ## 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：GDPR 数据擦除

> 通过 Didit 按 vendor_data 批量删除供应商用户，或删除应用中的所有用户。符合 GDPR 和 CCPA 的被遗忘权要求。



批量删除用户提示词
        将提示词复制到剪贴板



      
      

\<pre>

\`Goal: Permanently delete one or many Didit User entities. The matching user records, their tag links, their comment history, and every retained biometric template anchored to them are removed permanently. Verification sessions are NOT removed by this endpoint; delete those separately with POST /v3/sessions/delete/.

Endpoint: POST https://verification.didit.me/v3/users/delete/
Auth header: x-api-key: <DIDIT_API_KEY>
Content-Type: application/json

Request body — provide at least one selector:
\- vendor_data_list: string[] — your own identifiers (case-insensitive after normalisation).
\- didit_internal_id_list: string[] — Didit internal user IDs, the didit_internal_id returned by the create and get endpoints. Can be combined with vendor_data_list; the two are OR'd.
\- delete_all: true — wipe every user in this application. No confirmation, no undo. Takes precedence: when delete_all is true, the two lists are ignored.

\- retain_face_embeddings: boolean, default false — your explicit choice to keep one image-free biometric template of each deleted person for duplicate detection. Everything else about the person is deleted. Requires face_retention_days.
\- face_retention_days: integer 1 to 3650 — how many days that template is kept. Sent without retain_face_embeddings: true it returns 400 on face_retention_days.

This endpoint never narrows delete_all with filters. The Console's filter_* batch params (filter_search, filter_status, filter_country, filter_date_from, filter_date_to, filter_tag, filter_latest_verification_status, filter_risk, filter_has_sessions, filter_has_open_alerts, filter_aml_monitoring, filter_can_sign_in, filter_auth_status, filter_auth_method, filter_auth_mfa_enabled) are NOT supported here. Any of them sent with a value, even false, is rejected with a 400 keyed by that field, and any other unknown filter_* key with "Unknown filter.", so a narrowed intent does not wipe the whole application. Exception: filter_has_approved_sessions and filter_has_declined_sessions are neither rejected nor applied, so with delete_all they still delete every user. Do not send them.

curl:
curl -X POST 'https://verification.didit.me/v3/users/delete/' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"vendor_data_list": ["user-123", "user-456"]}'

Response 200:
\{
"deleted": <int — number of users actually deleted; excludes vendor_data values that didn't match>
}

Biometric templates: unless you set retain_face_embeddings to true, if the application retained image-free biometric templates for these users after session deletion (see /management-api/biometric-templates/overview), Didit purges every one of them before the user is deleted, so the person stops matching in duplicate detection and Face Search. The purge is audited with instruction_source: vendor_user_delete.

Idempotency: re-sending the same list returns deleted: 0 after the first run (unmatched IDs are silently skipped). There is no undo.

Failure modes:
\- 400 — no selector supplied, or a Console-only filter_* param was sent.
No selector: {"vendor_data_list": ["This field is required unless delete_all is true."]}. An unknown filter_* key: {"filter_<name>": ["Unknown filter."]}.
\- 401 — missing/invalid x-api-key.
\- 403 — the API key is revoked or is not valid for this application.
\- 409 — the selection includes a person in a finalized regulatory report. Nothing is deleted. The body has code: in_filed_report and reports[] with uuid, report_number, report_type and case_uuid. Delete the reports, then repeat the request.
\- 409 — code: subject_deletion_in_progress: another request is still deleting one of the selected people. This request deleted nothing; repeat it once that deletion has finished.
\- 429 — rate-limited.
\- 503 — {"detail": "The biometric-template operation could not finish because an external store is unavailable. The operation is retryable."} A retained biometric template could not be purged. No user in the request is deleted; the affected template is already excluded from matching. Repeat the same request.

WARNING — delete_all: true: there is no confirmation step and no undo. Restrict to API keys you intentionally provision for batch maintenance.

When to prefer status change instead:
\- For day-to-day blocking, use PATCH /v3/users/{vendor_data}/update-status/ with {"status": "BLOCKED"} — it keeps the audit trail intact while rejecting future sessions for the same identifier.

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

\</pre>



      
      

粘贴到

## 概览删除一个或多个[用户实体](https://docs.didit.me/zh/entities/users/overview.md)。用户记录会被永久删除。其验证会话不在本端点的覆盖范围内，会保留下来，但与用户的关联会被清除。请使用[删除会话](https://docs.didit.me/zh/sessions-api/delete-session.md)或[批量删除会话](https://docs.didit.me/zh/management-api/sessions/batch-delete.md)删除这些会话。交易同样不在覆盖范围内，请使用[批量删除交易](https://docs.didit.me/zh/management-api/transactions/delete.md)删除。## 适用场景- **被遗忘权**请求（GDPR / CCPA）。
- 在 QA 期间**清理**测试用户。
- 从您自己的平台移除用户时的**取消配置**。## 注意事项- 接受 `vendor_data` 值列表、`didit_internal_id` 值列表，或 `delete_all: true`。两个列表可以组合使用，二者按逻辑或（OR）合并。
- 本端点永远不会用过滤条件收窄 `delete_all`。控制台的 `filter_*` 批量参数会被拒绝并返回 `400`，因此您想收窄的范围不会导致应用中的所有用户被删除。
  例外情况是 `filter_has_approved_sessions` 和 `filter_has_declined_sessions`：它们既不会被拒绝，也不会被应用，因此请勿与 `delete_all` 一同发送。
- 全有或全无：如果无法为您所选的用户完成删除，则其中任何一位都不会被删除，您可以放心地重复发送同一请求。
- 幂等：重复发送同一列表，首次执行后将返回 `deleted: 0`。
- 只返回已删除数量的统计，不返回逐项报告。未匹配到的值会被静默跳过。如果您希望将 `deleted` 与所发送标识符的数量进行比较，请发送去重后的列表，因为重复的标识符只会计算一次。
- 删除操作不会发出任何 Webhook。Webhook 在用户状态和数据变更时触发，而不是在删除时触发，因此需要删除信号的集成必须在自身一侧记录该信号。
- 与用户关联的验证会话不会被本端点删除。它们会保留下来，与用户的关联被清除，因此其证件、人脸和媒体文件只有在您自行删除这些会话后才会被移除。
- `retain_face_embeddings`（布尔值，默认 `false`）和 `face_retention_days`（1 到 3650）是您的明确选择：为每位被删除的人保留一个不含图像的生物特征模板，用于重复检测，保留天数为该值。除此之外，不保留该人的任何其他信息。若两者都不设置，则模板会随用户一并删除。仅设置 `face_retention_days` 而未设置 `retain_face_embeddings: true`，或仅设置 `retain_face_embeddings: true` 而未设置 `face_retention_days`，都会因 `face_retention_days` 返回 `400`。
- 除非您将 `retain_face_embeddings` 设为 `true`，否则与用户关联的已保留[生物特征模板](https://docs.didit.me/zh/management-api/biometric-templates/overview.md)会在删除用户之前被清除。如果某个模板因生物特征存储不可用而无法清除，则调用返回 `503`，请求中的任何用户都不会被删除。重复请求即可完成剩余操作。## 已定稿监管报告中的数据如果任一所选人员属于某个已定稿监管报告所在的案件，整个请求将返回 `409`，且不会删除任何内容。响应使用 `code: in_filed_report`，并列出每份报告，以便您在控制台中打开查看：```json theme={null}
{
  "detail": "A case about this person or company has a filed regulatory report, so it cannot be deleted.",
  "code": "in_filed_report",
  "reports": [
    {
      "uuid": "5ec00000-0000-4000-8000-000000000007",
      "report_number": "SAR-0001",
      "report_type": "SAR",
      "case_uuid": "c1a5e000-0000-4000-8000-000000000001"
    }
  ]
}
```使用[删除报告](https://docs.didit.me/zh/management-api/regulatory-reports/delete.md)删除每份报告，然后重复同一请求。如果另一位所选人员仍在某份报告中，仅将该人从列表中移除是不够的。## 正在进行的删除同一时间，一位人员只能由一个请求删除。如果另一个请求仍在删除所选人员中的某一位，本请求最多等待数秒，然后返回 `409`，`code: subject_deletion_in_progress`，且不删除任何内容：```json theme={null}
{
  "detail": "This person or company is being deleted. Retry after deletion completes.",
  "code": "subject_deletion_in_progress"
}
```待另一项删除完成后，重复同一请求即可。它已删除的人员将不再匹配，因此重复请求只会删除剩余的人员。## 权限应用的任何处于活动状态的 API 密钥都可以调用本端点。Didit 的 API 密钥是**应用级别的，而非角色级别的**。控制台中的[角色和权限](https://docs.didit.me/zh/console/roles-permissions.md)（`delete:users` 等）决定的是*某人*在控制台中能做什么，对管理 API 的请求则不会对其进行评估。因此，请通过控制谁可以读取应用的 API 密钥，来控制谁可以调用本端点。## 相关内容- [数据保留](https://docs.didit.me/zh/console/data-retention.md)
- [审计日志](https://docs.didit.me/zh/console/audit-logs.md)
- [用户操作](https://docs.didit.me/zh/entities/users/operations.md)
- [生物特征模板](https://docs.didit.me/zh/management-api/biometric-templates/overview.md)


## OpenAPI

````yaml zh/openapi-25.json POST /v3/users/delete/
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/delete/:
    post:
      tags:
        - Users
      summary: 批量删除用户
      description: >-
        **永久删除**用户：用户记录将被永久移除。对于日常阻止操作，建议使用 [Update User
        Status](#patch-/v3/users/-vendor_data-/update-status/) 并传入
        `BLOCKED`。可以通过 `vendor_data_list`、`didit_internal_id_list`
        或两者同时使用来选择用户；也可以传递 `delete_all: true`。此 endpoint 绝不会通过过滤器缩小 `delete_all`
        的范围。Console 的人员过滤器将被拒绝并返回 `400`（参见 `400`
        响应），以避免缩小的意图变成全面清除。两个例外情况：`filter_has_approved_sessions` 和
        `filter_has_declined_sessions` 不会被拒绝也不会被应用，因此在传入 `delete_all: true`
        时它们仍会删除所有用户；请勿发送它们。


        **生物特征模板：**除非您将 `retain_face_embeddings` 设置为
        `true`，否则在删除会话后为这些用户保留的所有无图像生物特征模板（参见
        `/v3/biometric-templates/`）都会在用户被删除前清除，从而使该人员不再匹配重复检测和人脸搜索。若传入
        `retain_face_embeddings: true` 和
        `face_retention_days`，您可以选择为每人保留一份无图像的生物特征模板达相应天数，而该人员的其他信息均不保留。如果由于生物特征存储库不可用而导致模板无法清除，该调用将返回
        `503`，请求中的任何用户都不会被删除，重试请求即可完成该操作。


        **已归档的监管报告：**如果选定的数据包含在已定稿的监管报告中，整个请求将被拒绝并返回 `409`，且不会删除任何内容。响应体使用
        `code: in_filed_report`，并通过 `uuid`、`report_number`、`report_type` 和
        `case_uuid` 列出每份报告。请先删除这些报告，然后重试请求。
      operationId: batch_delete_users
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: >-
                提供 `vendor_data_list`、`didit_internal_id_list` 或 `delete_all:
                true`。两个列表可以组合使用，相互之间为“或”（OR）逻辑。当 `delete_all` 为 `true`
                时，其优先级最高，两个列表都会被忽略。
              properties:
                vendor_data_list:
                  type: array
                  items:
                    type: string
                  description: 您要删除的自身标识符，完全按照发送的内容进行匹配。
                didit_internal_id_list:
                  type: array
                  items:
                    type: string
                    format: uuid
                  description: 要删除的 Didit 内部用户 ID，即创建和获取 endpoint 返回的 `didit_internal_id`。
                delete_all:
                  type: boolean
                  default: false
                  description: 若为 `true`，则删除该应用中的所有用户。
                retain_face_embeddings:
                  type: boolean
                  default: false
                  description: >-
                    您的明确选择，用于为每个被删除的人员保留一份无图像的生物特征模板以用于重复检测，保留
                    `face_retention_days` 天。该人员的所有其他信息都将被删除。省略此参数或发送
                    `false`，将连同用户一起删除模板。当为 `true` 时，`face_retention_days` 为必填项。
                face_retention_days:
                  type: integer
                  minimum: 1
                  maximum: 3650
                  description: >-
                    当 `retain_face_embeddings` 为 `true`
                    时保留无图像生物特征模板的天数。与该参数配合使用时为必填项；未配置该参数时将被拒绝并在
                    `face_retention_days` 上返回 `400`。
                  example: 365
            examples:
              Specific users:
                summary: 按 vendor_data 删除用户
                value:
                  vendor_data_list:
                    - user-123
                    - user-456
              By Didit internal ID:
                summary: 按 didit_internal_id 删除用户
                value:
                  didit_internal_id_list:
                    - 3f1c0d3e-8f0a-4c2e-9a3d-9b1f5f4a2c11
              All users:
                summary: 清空此应用中的所有用户
                value:
                  delete_all: true
              Keep face templates:
                summary: 删除用户并保留匿名人脸模板 365 天
                value:
                  vendor_data_list:
                    - user-123
                  retain_face_embeddings: true
                  face_retention_days: 365
      responses:
        '200':
          description: 用户已删除。返回实际删除的用户数量。
          content:
            application/json:
              schema:
                type: object
                properties:
                  deleted:
                    type: integer
                    description: 已删除的用户数量（不包括未匹配到任何内容的 vendor_data 值）。
              examples:
                Deleted some:
                  value:
                    deleted: 2
                Nothing matched:
                  value:
                    deleted: 0
        '400':
          description: >-
            验证错误；未删除任何内容。错误以字段名为键。若未提供选择器（两个列表均未提供且 `delete_all` 不为 `true`），响应体为
            `{"vendor_data_list": ["This field is required unless delete_all is
            true."]}`；空列表会被拒绝并在其自身键下返回 `"This list may not be
            empty."`。仅限控制台的过滤器（`filter_search`、`filter_status`、`filter_country`、`filter_date_from`、`filter_date_to`、`filter_tag`、`filter_latest_verification_status`、`filter_risk`、`filter_has_sessions`、`filter_has_open_alerts`、`filter_aml_monitoring`、`filter_can_sign_in`、`filter_auth_status`、`filter_auth_method`
            或 `filter_auth_mfa_enabled`）只要包含值（即使为
            `false`）就会被拒绝，并返回以各对应字段为键的对象。任何其他未知的 `filter_*` 键都会被拒绝并返回 `"Unknown
            filter."`。
          content:
            application/json:
              examples:
                Missing selector:
                  summary: 既未提供 list 也未提供 delete_all
                  value:
                    vendor_data_list:
                      - This field is required unless delete_all is true.
                Console-only filter:
                  value:
                    filter_has_sessions: >-
                      This filter is Console-only and is not supported by this
                      endpoint.
        '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: 无效或已撤销的 API 密钥，或者该密钥无法删除此应用的用户。缺少密钥返回 `403`；错误、已撤销或已过期的密钥返回 `401`。
          content:
            application/json:
              examples:
                Forbidden:
                  value:
                    detail: You do not have permission to perform this action.
        '409':
          description: >-
            未删除任何内容。`code` 说明了原因：所选内容包含已定稿监管报告中的人员时为
            `in_filed_report`，另一个请求仍在删除所选人员之一时为
            `subject_deletion_in_progress`。请在该删除完成后重试请求。
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/InFiledReportError'
                  - $ref: '#/components/schemas/SubjectDeletionInProgressError'
        '429':
          description: 超出速率限制；请退避并在 `Retry-After` 指定的间隔后重试。
          content:
            application/json:
              examples:
                Rate limited:
                  value:
                    detail: Request was throttled. Expected available in 30 seconds.
        '503':
          description: 在保留或清除生物特征模板时，生物特征存储库不可用。未删除任何内容；请重试相同的请求。重试具有幂等性，并最终收敛至单个模板。
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
              examples:
                Retryable:
                  value:
                    detail: >-
                      The biometric-template operation could not finish because
                      an external store is unavailable. The operation is
                      retryable.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X POST 'https://verification.didit.me/v3/users/delete/' \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{"vendor_data_list": ["user-123", "user-456"]}'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.users.batch_delete(
                vendor_data_list=["user-123", "user-456"],
            )
            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.users.batchDelete({
              vendor_data_list: ["user-123", "user-456"],
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.BatchDelete(ctx, didit.UsersBatchDeleteParams{\n\tVendorDataList: didit.Some([]string{\"user-123\", \"user-456\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import java.util.List;

            import me.didit.Didit;

            import me.didit.types.UsersBatchDeleteParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.users().batchDelete(UsersBatchDeleteParams.builder()
                    .vendorDataList(List.of("user-123", "user-456"))
                    .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->users->batchDelete([
                'vendor_data_list' => ['user-123', 'user-456'],
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: >-
            require "didit"


            # Reads DIDIT_API_KEY.

            didit = Didit::Client.new


            result = didit.users.batch_delete(vendor_data_list: ["user-123",
            "user-456"])

            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.Users.BatchDeleteAsync(new
            UsersBatchDeleteParams

            {
                VendorDataList = new string[] { "user-123", "user-456" },
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    InFiledReportError:
      type: object
      description: 由于所选数据包含在已定稿的监管报告中，删除被拒绝。没有任何内容被删除。请删除该报告，然后重试请求。
      required:
        - detail
        - code
      properties:
        detail:
          type: string
        code:
          type: string
          enum:
            - in_filed_report
          description: 因最终监管报告阻止删除的稳定错误代码。
        reports:
          type: array
          items:
            $ref: '#/components/schemas/FiledRegulatoryReport'
          description: 阻止删除个人、企业、案件或会话的报告。
        transactions:
          type: array
          items:
            $ref: '#/components/schemas/FiledReportTransaction'
          description: 阻止删除该交易的交易列表，每笔均附带列出它的报告。
    SubjectDeletionInProgressError:
      type: object
      description: 另一个请求仍在删除此人或企业。本次请求未删除任何内容，可在该删除操作完成后重试；重试将删除届时仍处于选中状态的内容。
      required:
        - detail
        - code
      properties:
        detail:
          type: string
        code:
          type: string
          enum:
            - subject_deletion_in_progress
          description: 因另一请求正在删除该个人或企业而返回的稳定错误代码。
    FiledRegulatoryReport:
      type: object
      description: 已定稿的监管报告，阻止了请求的删除操作。
      required:
        - uuid
        - report_number
        - report_type
        - case_uuid
      properties:
        uuid:
          type: string
          format: uuid
          description: 报告 UUID。
        report_number:
          type: string
          description: 在控制台中显示的报告编号（例如 SAR-0001）。
        report_type:
          type: string
          enum:
            - SAR
            - STR
            - CTR
            - TTR
            - UTR
            - IFT
            - CBR
            - TFR
          description: 监管报告类型。
        case_uuid:
          type: string
          format: uuid
          description: 该报告所属的案件。
    FiledReportTransaction:
      type: object
      description: 因已定稿的监管报告列出而无法删除的交易。
      required:
        - uuid
        - transaction_id
        - reports
      properties:
        uuid:
          type: string
          format: uuid
          description: Didit 交易 UUID。
        transaction_id:
          type: string
          description: 创建交易时提供的交易标识符。
        reports:
          type: array
          items:
            $ref: '#/components/schemas/FiledRegulatoryReport'
          description: 列出此交易的已定稿报告。
  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.