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

# Passive Liveness API：深度伪造检测

> Didit 可通过单张图片检测面具、打印照片、重放攻击和深度伪造。完全被动、推理耗时低于 2 秒、按次计费，无月度最低消费。



## OpenAPI

````yaml zh/openapi-25.json POST /v3/passive-liveness/
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/passive-liveness/:
    post:
      tags:
        - Standalone APIs
      summary: 静默活体检测
      description: >-
        从单张人脸图像中检测呈现攻击（打印照片、屏幕重放、面具、深度伪造）。无需视频、动作或用户交互。


        **工作原理。** 图像由生物识别模型进行分析；评估检测到的最大人脸并计算活体 `score`（0–100）。当触发任何 `error`
        严重级别的警告时，`status` 为 `Declined`：

        - `NO_FACE_DETECTED`：活体模型未找到人脸，

        - `LOW_LIVENESS_SCORE`：分数达到或低于
        `face_liveness_score_decline_threshold`（默认 `30`），

        - `LIVENESS_FACE_ATTACK`：模型检测到呈现攻击，

        - `FACE_IN_BLOCKLIST` / `POSSIBLE_FACE_IN_BLOCKLIST`：该人脸与您的人脸黑名单中的条目匹配。


        `MULTIPLE_FACES_DETECTED` 是 `warning` 严重级别的信号（不会拒绝），而 `DUPLICATED_FACE`
        / `POSSIBLE_DUPLICATED_FACE` 是 `information`
        严重级别的信号，表示同一张人脸已出现在另一个已通过的会话中（它们绝不会拒绝）。`face_quality` 和
        `face_luminance`（0–100，可为 null）描述采集质量。


        **黑名单和重复筛查。** 在**每次**调用时运行（无论是否包含
        `save_api_request`），通过将检测到的人脸与您应用的人脸搜索索引进行比对。具有相同 `vendor_data`
        的先前人脸将从整个索引搜索中排除，因此为同一用户重新运行活体检测不会触发 `DUPLICATED_FACE`，并且源自具有调用方自身
        `vendor_data` 会话的黑名单人脸也不会被标记（对相同 `vendor_data` 的人脸绕过 `FACE_IN_BLOCKLIST`
        筛查）。


        **计费。** 每个 `200` 响应消耗一个 Passive Liveness API
        额度（从您的套餐额度或充值余额中扣除）。余额不足将在进行任何图像处理之前返回 `403`。


        **会话持久化和人脸录入（`save_api_request`，默认 `true`）。** 当为 `true` 时，该调用将持久化为 API
        类型的会话（Business Console，通过返回的 `request_id` 调用的 `GET
        /v3/session/{sessionId}/decision/`，`status.updated`
        Webhook），存储参考图像和人脸裁剪图，并将检测到的人脸**录入您的人脸搜索索引**，以便后续的人脸搜索调用和重复检查可以与其匹配。当为
        `false` 时，该调用为单次调用：不存储任何内容，且不录入人脸（黑名单/重复筛查仍会运行）。


        **沙盒。** 沙盒 API 密钥跳过所有处理和计费：在请求验证之后（格式错误的输入仍返回 `400`），endpoint 返回一个静态的
        `Approved` 模拟 payload，不持久化会话，且不消耗额度。


        **认证。** 在 `x-api-key` 请求头中发送您应用的 API 密钥。缺少凭据或凭据无效将返回 `403`（`{"detail":
        "You do not have permission to perform this action."}`），此 API 绝不会返回
        `401`。


        **速率限制。** 在所有 POST/PATCH/DELETE endpoint 间共享每个 API 密钥 300
        次请求/分钟的写入预算；超出将返回 `429`。
      operationId: post_v3passive-liveness
      parameters: []
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - user_image
              properties:
                user_image:
                  type: string
                  format: binary
                  description: >-
                    正面人脸图像（例如自拍照）。允许的文件扩展名：`tiff`、`jpg`、`jpeg`、`png`、`webp`。最大上传大小：**5
                    MB**（超出限制的文件将被拒绝并返回 `400`）。图像在处理前会自动压缩至约 0.5
                    MB，因此极高的分辨率并不会提高准确度。图像应仅包含一个拍摄主体。若存在多张人脸，将评估最大的人脸并添加
                    `MULTIPLE_FACES_DETECTED` 警告。
                face_liveness_score_decline_threshold:
                  type: number
                  format: float
                  default: 30
                  minimum: 0
                  maximum: 100
                  description: >-
                    活体评分阈值（0–100）。计算得出的分数**达到或低于**此值将发出 `LOW_LIVENESS_SCORE`
                    警告，并将 `status` 设为 `Declined`。默认值为 `30`；调高此值可实施更严格的防欺骗攻击策略。超出
                    0–100 范围的值将返回 `400`。
                  example: 30
                rotate_image:
                  type: boolean
                  default: false
                  description: >-
                    为 `true` 时，服务会尝试按 90 度旋转输入内容的各个方向，并使用人脸检测效果最佳的方向。在缺少 EXIF
                    方向信息时非常有用。会增加延迟。
                  example: false
                save_api_request:
                  type: boolean
                  default: true
                  description: >-
                    为 `true`（默认）时，将此次调用持久化为 API 类型会话，存储人脸图像，发出 `status.updated`
                    Webhook，并将检测到的人脸录入到您的人脸搜索索引中。为 `false`
                    时，该调用为单次执行，不存储任何内容，也不录入人脸。黑名单和重复筛查在两种情况下都会运行。
                  example: true
                vendor_data:
                  type: string
                  description: >-
                    可选的不透明标识符（您的用户 ID、邮箱、UUID
                    等），存储在持久化会话中并予以回显。还用于在重复人脸检查中排除具有相同 `vendor_data`
                    的先前会话，从而避免在重新验证同一用户时触发 `DUPLICATED_FACE`。
                  example: user-123
                metadata:
                  type: object
                  additionalProperties: true
                  description: >-
                    与会话一同存储（当 `save_api_request=true` 时）并原样返回的可选 JSON 对象。在
                    multipart 请求中，请将其作为 JSON 编码的字符串字段发送，它将被解析为对象。
                  example:
                    flow: withdrawal
            example:
              user_image: (binary JPEG/PNG selfie)
              face_liveness_score_decline_threshold: 30
              rotate_image: false
              save_api_request: true
              vendor_data: user-123
              metadata:
                flow: withdrawal
      responses:
        '200':
          description: >-
            静默活体检测已完成。`liveness.score` 是模型对图像显示为活人的置信度（0–100）；除非触发了 `error`
            严重级别的警告，否则 `status` 为 `Approved`。欺骗攻击或处于黑名单的人脸仍会返回 `200`，请检查
            `liveness.status` 和 `liveness.warnings`，而不仅仅是 HTTP 状态码。当
            `save_api_request=true` 时，`request_id` 为持久化的会话 ID。
          content:
            application/json:
              examples:
                Approved:
                  summary: 活体面部 — 无警告
                  value:
                    request_id: a1b2c3d4-e5f6-7890-1234-567890abcdef
                    liveness:
                      status: Approved
                      method: PASSIVE
                      score: 95
                      user_image:
                        entities:
                          - bbox:
                              - 661
                              - 728
                              - 1688
                              - 2188
                            confidence: 0.732973
                            age: 26.91
                            gender: male
                            race: null
                        best_angle: 0
                      warnings: []
                      face_quality: 84.21
                      face_luminance: 50.33
                    vendor_data: user-123
                    metadata: null
                    created_at: '2026-06-12T01:04:42.763237+00:00'
                Declined - presentation attack:
                  summary: 模型标记了欺骗攻击（打印件、重放、面具等）
                  value:
                    request_id: f1c8c9b2-d3e4-4f5a-9b8c-7d6e5f4a3b2c
                    liveness:
                      status: Declined
                      method: PASSIVE
                      score: 12.5
                      user_image:
                        entities:
                          - bbox:
                              - 100
                              - 120
                              - 420
                              - 540
                            confidence: 0.81
                            age: 30.1
                            gender: female
                            race: null
                        best_angle: 0
                      warnings:
                        - risk: LOW_LIVENESS_SCORE
                          feature: LIVENESS
                          additional_data: null
                          log_type: error
                          short_description: Low liveness score
                          long_description: >-
                            The liveness check resulted in a low score,
                            indicating potential use of non-live facial
                            representations or poor-quality biometric data.
                        - risk: LIVENESS_FACE_ATTACK
                          feature: LIVENESS
                          additional_data: null
                          log_type: error
                          short_description: Liveness Face Attack
                          long_description: >-
                            The system detected a potential attempt to bypass
                            the liveness check.
                      face_quality: 72.4
                      face_luminance: 48.2
                    vendor_data: user-123
                    metadata: null
                    created_at: '2026-06-12T01:04:42.763237+00:00'
                Declined - face on blocklist:
                  summary: 活体面部，但命中了黑名单条目
                  value:
                    request_id: 0b54a1de-22aa-4e0f-9c84-5a2b1f3c4d5e
                    liveness:
                      status: Declined
                      method: PASSIVE
                      score: 93.75
                      user_image:
                        entities:
                          - bbox:
                              - 40
                              - 40
                              - 100
                              - 100
                            confidence: 0.722082
                            age: 27
                            gender: male
                            race: null
                        best_angle: 0
                      warnings:
                        - risk: FACE_IN_BLOCKLIST
                          feature: LIVENESS
                          additional_data:
                            blocklisted_session_id: 882c42d5-8a4d-4d20-8080-a22f57822c86
                            blocklisted_session_number: 3242
                            api_service: null
                          log_type: error
                          short_description: Face in blocklist
                          long_description: >-
                            The system identified a face in the blocklist, which
                            means the face is not allowed to be verified.
                      face_quality: null
                      face_luminance: null
                    vendor_data: user-123
                    metadata: null
                    created_at: '2026-06-12T01:04:42.763237+00:00'
              schema:
                type: object
                properties:
                  request_id:
                    type: string
                    format: uuid
                    description: >-
                      当 `save_api_request=true` 时持久化的会话 ID（可用于 `GET
                      /v3/session/{sessionId}/decision/`）；否则为一个临时的关联 UUID。
                  liveness:
                    type: object
                    properties:
                      status:
                        type: string
                        enum:
                          - Approved
                          - Declined
                        description: >-
                          当触发了至少一个 `error` 严重级别的警告（无人脸、低分、呈现攻击或命中黑名单）时为
                          `Declined`；否则为 `Approved`。`warning`/`information`
                          项（多张人脸、重复项）本身绝不会导致拒绝。
                      method:
                        type: string
                        enum:
                          - PASSIVE
                        description: 对于此 endpoint 始终为 `PASSIVE`。
                      score:
                        type: number
                        format: float
                        nullable: true
                        minimum: 0
                        maximum: 100
                        description: >-
                          活体置信度（0–100，保留两位小数），表示图像描绘的是活体真人而非欺骗攻击的置信度。当模型未返回置信度时为
                          `null`。
                        example: 95
                      user_image:
                        type: object
                        description: 已提交图像的人脸检测结果。
                        properties:
                          entities:
                            type: array
                            items:
                              type: object
                              properties:
                                bbox:
                                  type: array
                                  items:
                                    type: integer
                                  minItems: 4
                                  maxItems: 4
                                  description: >-
                                    检测到的人脸边界框，表示为处理后图像中的 `[x_min, y_min, x_max,
                                    y_max]` 像素坐标。
                                  example:
                                    - 661
                                    - 728
                                    - 1688
                                    - 2188
                                confidence:
                                  type: number
                                  format: float
                                  minimum: 0
                                  maximum: 1
                                  description: 人脸检测置信度（0–1）。
                                  example: 0.732973
                                age:
                                  type: number
                                  format: float
                                  description: 检测到的人脸的模型估算年龄（以岁为单位）。仅供参考，不影响活体检测决策。
                                  example: 26.91
                                gender:
                                  type: string
                                  description: 模型预测的检测人脸性别（`male` 或 `female`）。仅供参考。
                                  example: male
                                race:
                                  type: string
                                  nullable: true
                                  description: 保留字段 — 在此 endpoint 的响应中始终为 `null`。
                                  example: null
                            description: 每张检测到的人脸对应一个条目。以最大的人脸为准进行评估。
                          best_angle:
                            type: integer
                            nullable: true
                            description: >-
                              产生最佳人脸检测结果的旋转角度（度）；仅当 `rotate_image=true`
                              纠正了方向时才为非零值。
                            example: 0
                      warnings:
                        type: array
                        description: >-
                          风险信号。`error`
                          严重级别（拒绝）：`NO_FACE_DETECTED`、`LOW_LIVENESS_SCORE`（分数低于或等于阈值）、`LIVENESS_FACE_ATTACK`、`FACE_IN_BLOCKLIST`、`POSSIBLE_FACE_IN_BLOCKLIST`。`warning`
                          严重级别（审核，不拒绝）：`MULTIPLE_FACES_DETECTED`。`information`
                          严重级别（不拒绝）：`DUPLICATED_FACE`、`POSSIBLE_DUPLICATED_FACE`（同一张人脸已出现在另一个已通过的会话中）。
                        items:
                          type: object
                          properties:
                            risk:
                              type: string
                              enum:
                                - NO_FACE_DETECTED
                                - LOW_LIVENESS_SCORE
                                - LIVENESS_FACE_ATTACK
                                - MULTIPLE_FACES_DETECTED
                                - FACE_IN_BLOCKLIST
                                - POSSIBLE_FACE_IN_BLOCKLIST
                                - DUPLICATED_FACE
                                - POSSIBLE_DUPLICATED_FACE
                              description: 机器可读的风险代码。
                            feature:
                              type: string
                              enum:
                                - LIVENESS
                              description: 引发该警告的功能。在此 endpoint 上始终为 `LIVENESS`。
                            additional_data:
                              type: object
                              nullable: true
                              additionalProperties: true
                              description: >-
                                大多数警告为 `null`。黑名单命中会携带 `{blocklisted_session_id,
                                blocklisted_session_number,
                                api_service}`；重复命中会携带指向匹配会话的
                                `{duplicated_session_id,
                                duplicated_session_number, api_service}`。
                            log_type:
                              type: string
                              enum:
                                - error
                                - warning
                                - information
                              description: >-
                                严重程度。`error` 警告会导致 `status` 变为
                                `Declined`；`warning` 和 `information`
                                条目仅供参考，本身绝不会导致拒绝。
                            short_description:
                              type: string
                              description: 易于阅读的单行风险摘要。
                            long_description:
                              type: string
                              description: 风险的便于人类阅读的说明。
                      face_quality:
                        type: number
                        format: float
                        nullable: true
                        minimum: 0
                        maximum: 100
                        description: 检测到人脸的采集质量分数，已归一化至 0–100。当模型无法生成可靠值时为 `null`。
                        example: 84.21
                      face_luminance:
                        type: number
                        format: float
                        nullable: true
                        minimum: 0
                        maximum: 100
                        description: 检测到的人脸亮度，归一化为 0–100。不可用时为 `null`。
                        example: 50.33
                  vendor_data:
                    type: string
                    nullable: true
                    description: 您发送的 `vendor_data` 回显，或 `null`。
                  metadata:
                    type: object
                    nullable: true
                    additionalProperties: true
                    description: 您发送的 `metadata` 对象回显，或 `null`。
                  created_at:
                    type: string
                    format: date-time
                    description: >-
                      响应生成时的 ISO 8601 时间戳（UTC），例如
                      `2026-06-12T01:04:42.763237+00:00`。
        '400':
          description: >-
            验证错误。当 `user_image` 缺失、超过 5 MB、扩展名不受支持、服务端图像解码失败，或选项超出范围时返回。字段错误使用
            DRF 的 `{field: [messages]}` 响应格式；图像解码失败使用 `{"error": ...}`。
          content:
            application/json:
              examples:
                Missing image:
                  summary: 表单数据中未包含 `user_image`
                  value:
                    user_image:
                      - No file was submitted.
                Invalid image format:
                  summary: 扩展名允许，但图像内容无法解码
                  value:
                    error: Invalid user image format.
                    code: invalid_image
                Unsupported file extension:
                  summary: 文件扩展名不在 tiff/jpg/jpeg/png/webp 范围内
                  value:
                    user_image:
                      - >-
                        File extension “txt” is not allowed. Allowed extensions
                        are: tiff, jpg, jpeg, png, webp.
                File too large:
                  summary: 上传内容超过 5 MB 限制
                  value:
                    user_image:
                      - File size should not exceed 5 MB
        '403':
          description: >-
            权限被拒绝。当缺少 `x-api-key` 请求头，或调用组织的余额无法覆盖此次调用时返回；错误、已撤销或已过期的密钥返回
            `401`。缺少密钥时返回 `403` 及 `{"detail": ...}`；错误、已撤销或已过期的密钥返回
            `401`。额度不足时会在进行任何图像处理之前返回 `403` 及 `{"error": ...}`。
          content:
            application/json:
              examples:
                Missing or invalid API key:
                  summary: 缺少 `x-api-key` 请求头，或者密钥无效/已被吊销
                  value:
                    detail: You do not have permission to perform this action.
                Not enough credits:
                  summary: 组织余额不足以支付本次调用
                  value:
                    error: >-
                      You don't have enough credits to perform this request.
                      Please top up at https://business.didit.me
        '429':
          description: >-
            超出速率限制。POST/PATCH/DELETE endpoint 每个 API 密钥每分钟共享 300
            次写入请求的额度（交易创建和事件摄入具有单独的 600 次额度）。响应包含
            `X-RateLimit-Limit`、`X-RateLimit-Remaining`、`X-RateLimit-Reset` 和
            `Retry-After` 响应头。
          content:
            application/json:
              examples:
                Write rate limit exceeded:
                  summary: 当前分钟内的写入请求超过 300 次
                  value:
                    detail: >-
                      Write request rate limit exceeded. You can make up to 300
                      requests per minute.
              schema:
                type: object
                properties:
                  detail:
                    type: string
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |-
            curl -X POST 'https://verification.didit.me/v3/passive-liveness/' \
              -H 'x-api-key: YOUR_API_KEY' \
              -F 'user_image=@./selfie.jpg' \
              -F 'face_liveness_score_decline_threshold=30' \
              -F 'save_api_request=true' \
              -F 'vendor_data=user-123'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.passive_liveness.check(
                user_image=open("user_image.jpg", "rb"),
                face_liveness_score_decline_threshold=30.0,
                rotate_image=False,
                save_api_request=True,
                vendor_data="user-123",
                metadata={"flow": "withdrawal"},
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit, { fileFromPath } from "@didit-protocol/sdk-node";

            // Reads DIDIT_API_KEY.
            const didit = new Didit();

            const result = await didit.passiveLiveness.check({
              user_image: await fileFromPath("user_image.jpg"),
              face_liveness_score_decline_threshold: 30.0,
              rotate_image: false,
              save_api_request: true,
              vendor_data: "user-123",
              metadata: { flow: "withdrawal" },
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.PassiveLiveness.Check(ctx, didit.PassiveLivenessCheckParams{\n\tUserImage:                         didit.FileFromPath(\"user_image.jpg\"),\n\tFaceLivenessScoreDeclineThreshold: didit.Float(30.0),\n\tRotateImage:                       didit.Bool(false),\n\tSaveAPIRequest:                    didit.Bool(true),\n\tVendorData:                        didit.String(\"user-123\"),\n\tMetadata:                          didit.Some(map[string]any{\"flow\": \"withdrawal\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import java.nio.file.Path;

            import java.util.Map;

            import me.didit.Didit;

            import me.didit.types.PassiveLivenessCheckParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.passiveLiveness().check(PassiveLivenessCheckParams.builder()
                    .userImage(Path.of("user_image.jpg"))
                    .faceLivenessScoreDeclineThreshold(30.0)
                    .rotateImage(false)
                    .saveApiRequest(true)
                    .vendorData("user-123")
                    .metadata(Map.of("flow", "withdrawal"))
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;
            use Didit\File;

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

            $result = $didit->passiveLiveness->check([
                'user_image' => File::fromPath('user_image.jpg'),
                'face_liveness_score_decline_threshold' => 30.0,
                'rotate_image' => false,
                'save_api_request' => true,
                'vendor_data' => 'user-123',
                'metadata' => ['flow' => 'withdrawal'],
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

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

            result = didit.passive_liveness.check(
              user_image: Pathname("user_image.jpg"),
              face_liveness_score_decline_threshold: 30.0,
              rotate_image: false,
              save_api_request: true,
              vendor_data: "user-123",
              metadata: { flow: "withdrawal" }
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Collections.Generic;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await client.PassiveLiveness.CheckAsync(new
            PassiveLivenessCheckParams

            {
                UserImage = FileUpload.FromPath("user_image.jpg"),
                FaceLivenessScoreDeclineThreshold = 30.0,
                RotateImage = false,
                SaveApiRequest = true,
                VendorData = "user-123",
                Metadata = new Dictionary<string, object> { ["flow"] = "withdrawal" },
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
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.