didit-passive-liveness

TotalClaw 作者 totalclaw v1.2.0

集成 Didit Passive Liveness 独立 API 以验证用户是否实际存在。 当用户想要检查活跃性、检测欺骗尝试、验证真人时使用 存在、实施反欺骗或使用 Didit 执行被动活体检测。 无需用户交互即可分析单个图像。返回活跃度分数、面部质量、 和亮度指标。检测演示攻击和重复面孔。

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install totalclaw:totalclaw~rosasalberto-didit-passive-liveness
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Atotalclaw~rosasalberto-didit-passive-liveness/file -o rosasalberto-didit-passive-liveness.md
## 概述(中文)

集成 Didit Passive Liveness 独立 API 以验证用户是否实际存在。
当用户想要检查活跃性、检测欺骗尝试、验证真人时使用
存在、实施反欺骗或使用 Didit 执行被动活体检测。
无需用户交互即可分析单个图像。返回活跃度分数、面部质量、
和亮度指标。检测演示攻击和重复面孔。

## 原文

# Didit Passive Liveness API

## Overview

Verifies that a user is physically present by analyzing a single captured image — no explicit movement or interaction required.

**Key constraints:**
- Supported formats: **JPEG, PNG, WebP, TIFF**
- Maximum file size: **5MB**
- Image must contain **exactly one clearly visible face**
- Original real-time photo only (no screenshots or printed photos)

**Accuracy:** 99.9% liveness detection accuracy, <0.1% false acceptance rate (FAR).

**Capabilities:** Liveness scoring, face quality assessment, luminance analysis, age/gender estimation, spoof detection (screen captures, printed copies, masks, deepfakes), duplicate face detection across sessions, blocklist matching.

**Liveness methods:** This standalone endpoint uses `PASSIVE` method (single-frame CNN). Workflow mode also supports `ACTIVE_3D` (action + flash, highest security) and `FLASHING` (3D flash, high security).

**API Reference:** https://docs.didit.me/reference/passive-liveness-api

---

## Authentication

All requests require `x-api-key` header. Get your key from [Didit Business Console](https://business.didit.me) → API & Webhooks.

---

## Endpoint

```
POST https://verification.didit.me/v3/passive-liveness/
```

### Headers

| Header | Value | Required |
|---|---|---|
| `x-api-key` | Your API key | **Yes** |
| `Content-Type` | `multipart/form-data` | **Yes** |

### Request Parameters (multipart/form-data)

| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| `user_image` | file | **Yes** | — | JPEG/PNG/WebP/TIFF, max 5MB | User's face image |
| `face_liveness_score_decline_threshold` | integer | No | — | 0-100 | Scores below this = Declined |
| `rotate_image` | boolean | No | — | — | Try rotations to find upright face |
| `save_api_request` | boolean | No | `true` | — | Save in Business Console |
| `vendor_data` | string | No | — | — | Your identifier for session tracking |

### Example

```python
import requests

response = requests.post(
    "https://verification.didit.me/v3/passive-liveness/",
    headers={"x-api-key": "YOUR_API_KEY"},
    files={"user_image": ("selfie.jpg", open("selfie.jpg", "rb"), "image/jpeg")},
    data={"face_liveness_score_decline_threshold": "80"},
)
```

```typescript
const formData = new FormData();
formData.append("user_image", selfieFile);
formData.append("face_liveness_score_decline_threshold", "80");

const response = await fetch("https://verification.didit.me/v3/passive-liveness/", {
  method: "POST",
  headers: { "x-api-key": "YOUR_API_KEY" },
  body: formData,
});
```

### Response (200 OK)

```json
{
  "request_id": "a1b2c3d4-...",
  "liveness": {
    "status": "Approved",
    "method": "PASSIVE",
    "score": 95,
    "user_image": {
      "entities": [
        {"age": 22.16, "bbox": [156, 234, 679, 898], "confidence": 0.717, "gender": "male"}
      ],
      "best_angle": 0
    },
    "warnings": [],
    "face_quality": 85.0,
    "face_luminance": 50.0
  },
  "created_at": "2025-05-01T13:11:07.977806Z"
}
```

### Status Values & Handling

| Status | Meaning | Action |
|---|---|---|
| `"Approved"` | User is physically present | Proceed with your flow |
| `"Declined"` | Liveness check failed | Check `warnings`. May be a spoof or poor image quality |

### Error Responses

| Code | Meaning | Action |
|---|---|---|
| `400` | Invalid request | Check file format, size, parameters |
| `401` | Invalid API key | Verify `x-api-key` header |
| `403` | Insufficient credits | Top up at business.didit.me |

---

## Response Field Reference

| Field | Type | Description |
|---|---|---|
| `status` | string | `"Approved"` or `"Declined"` |
| `method` | string | Always `"PASSIVE"` for this endpoint |
| `score` | integer | 0-100 liveness confidence (higher = more likely real). `null` if no face |
| `face_quality` | float | 0-100 face image quality score. `null` if no face |
| `face_luminance` | float | Face luminance value. `null` if no face |
| `entities[].age` | float | Estimated age |
| `entities[].bbox` | array | Face bounding box `[x1, y1, x2, y2]` |
| `entities[].confidence` | float | Face detection confidence (0-1) |
| `entities[].gender` | string | `"male"` or `"female"` |
| `warnings` | array | `{risk, log_type, short_description, long_description}` |

---

## Warning Tags

### Auto-Decline (always)

| Tag | Description |
|---|---|
| `NO_FACE_DETECTED` | No face detected in image |
| `LIVENESS_FACE_ATTACK` | Potential spoofing attempt (printed photo, screen, mask) |
| `FACE_IN_BLOCKLIST` | Face matches a blocklisted entry |
| `POSSIBLE_FACE_IN_BLOCKLIST` | Possible blocklist match detected |

### Configurable (Decline / Review / Approve)

| Tag | Description | Notes |
|---|---|---|
| `LOW_LIVENESS_SCORE` | Score below threshold | Configurable review + decline thresholds |
| `DUPLICATED_FACE` | Matches another approved session | — |
| `POSSIBLE_DUPLICATED_FACE` | May match another user | Configurable similarity threshold |
| `MULTIPLE_FACES_DETECTED` | Multiple faces (largest used for scoring) | Passive only |
| `LOW_FACE_QUALITY` | Image quality below threshold | Passive only |
| `LOW_FACE_LUMINANCE` | Image too dark | Passive only |
| `HIGH_FACE_LUMINANCE` | Image too bright/overexposed | Passive only |

---

## Common Workflows

### Basic Liveness Check

```
1. Capture user selfie
2. POST /v3/passive-liveness/ → {"user_image": selfie}
3. If "Approved" → user is real, proceed
   If "Declined" → check warnings:
     - NO_FACE_DETECTED → ask user to retake with face clearly visible
     - LOW_FACE_QUALITY → ask for better lighting/positioning
     - LIVENESS_FACE_ATTACK → flag as potential fraud
```

### Liveness + Face Match (combined)

```
1. POST /v3/passive-liveness/ → verify user is real
2. If Approved → POST /v3/face-match/ → compare selfie to ID photo
3. Both Approved → identity verified
```

---

## Utility Scripts

```bash
export DIDIT_API_KEY="your_api_key"

python scripts/check_liveness.py selfie.jpg
python scripts/check_liveness.py selfie.jpg --threshold 80
```

---

## 中文说明

# Didit Passive Liveness API(Didit 被动活体检测 API)

## 概述

通过分析单张采集的图像来验证用户是否实际在场——无需明确的动作或交互。

**关键约束:**
- 支持的格式:**JPEG、PNG、WebP、TIFF**
- 最大文件大小:**5MB**
- 图像必须**恰好包含一张清晰可见的人脸**
- 仅限原始实时照片(不接受截图或打印照片)

**准确率:** 99.9% 的活体检测准确率,误接受率(FAR)< 0.1%。

**功能:** 活体评分、人脸质量评估、亮度分析、年龄/性别估计、欺骗检测(屏幕截图、打印副本、面具、深度伪造)、跨会话重复人脸检测、阻止列表匹配。

**活体检测方法:** 该独立端点使用 `PASSIVE` 方法(单帧 CNN)。工作流模式还支持 `ACTIVE_3D`(动作 + 闪光,最高安全级别)和 `FLASHING`(3D 闪光,高安全级别)。

**API 参考:** https://docs.didit.me/reference/passive-liveness-api

---

## 认证

所有请求都需要 `x-api-key` 请求头。从 [Didit Business Console](https://business.didit.me) → API & Webhooks 获取你的密钥。

---

## 端点

```
POST https://verification.didit.me/v3/passive-liveness/
```

### 请求头

| Header | Value | Required |
|---|---|---|
| `x-api-key` | 你的 API 密钥 | **Yes** |
| `Content-Type` | `multipart/form-data` | **Yes** |

### 请求参数(multipart/form-data)

| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| `user_image` | file | **Yes** | — | JPEG/PNG/WebP/TIFF,最大 5MB | 用户的人脸图像 |
| `face_liveness_score_decline_threshold` | integer | No | — | 0-100 | 分数低于此值 = 拒绝 |
| `rotate_image` | boolean | No | — | — | 尝试旋转以找到正向人脸 |
| `save_api_request` | boolean | No | `true` | — | 保存在 Business Console 中 |
| `vendor_data` | string | No | — | — | 用于会话跟踪的标识符 |

### 示例

```python
import requests

response = requests.post(
    "https://verification.didit.me/v3/passive-liveness/",
    headers={"x-api-key": "YOUR_API_KEY"},
    files={"user_image": ("selfie.jpg", open("selfie.jpg", "rb"), "image/jpeg")},
    data={"face_liveness_score_decline_threshold": "80"},
)
```

```typescript
const formData = new FormData();
formData.append("user_image", selfieFile);
formData.append("face_liveness_score_decline_threshold", "80")