didit-face-match

Coding Agents & IDEs
v1.3.0
Benign

Integrate Didit Face Match standalone API to compare two facial images.

502 downloads502 installsby @rosasalberto

Setup & Installation

Install command

clawhub install rosasalberto/didit-face-match

If the CLI is not installed:

Install command

npx clawhub@latest install rosasalberto/didit-face-match

Or install with OpenClaw CLI:

Install command

openclaw skills install rosasalberto/didit-face-match

or paste the repo link into your assistant's chat

Install command

https://github.com/openclaw/skills/tree/main/skills/rosasalberto/didit-face-match

What This Skill Does

Compares two facial images using the Didit Face Match API and returns a similarity score from 0 to 100. Supports JPEG, PNG, WebP, and TIFF formats up to 5MB per image. Also returns estimated age, gender, and face bounding boxes alongside the match result.

Handles image rotation automatically and returns structured metadata including age and gender estimates alongside the match score, reducing manual preprocessing steps.

When to Use It

  • Selfie-to-ID document verification during user onboarding
  • Confirming a returning user matches their registered profile photo
  • Checking if two submitted photos show the same person
  • Biometric access confirmation for a secure area or service
  • KYC face check for financial or legal account opening
View original SKILL.md file
# Didit Face Match API

## Overview

Compares two facial images to determine if they belong to the same person. Returns a similarity score (0-100).

**Key constraints:**
- Supported formats: **JPEG, PNG, WebP, TIFF**
- Maximum file size: **5MB** per image
- If multiple faces in an image, the **largest face** is used for comparison
- Both `user_image` and `ref_image` are **required**

**Capabilities:** Similarity scoring, age estimation, gender detection, face bounding boxes, configurable decline threshold, optional image rotation for non-upright faces.

**API Reference:** https://docs.didit.me/standalone-apis/face-match
**Feature Guide:** https://docs.didit.me/core-technology/face-match/overview

---

## Authentication

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

## Getting Started (No Account Yet?)

If you don't have a Didit API key, create one in 2 API calls:

1. **Register:** `POST https://apx.didit.me/auth/v2/programmatic/register/` with `{"email": "you@gmail.com", "password": "MyStr0ng!Pass"}`
2. **Check email** for a 6-character OTP code
3. **Verify:** `POST https://apx.didit.me/auth/v2/programmatic/verify-email/` with `{"email": "you@gmail.com", "code": "A3K9F2"}` → response includes `api_key`

**To add credits:** `GET /v3/billing/balance/` to check, `POST /v3/billing/top-up/` with `{"amount_in_dollars": 50}` for a Stripe checkout link.

See the **didit-verification-management** skill for full platform management (workflows, sessions, users, billing).

---

## Endpoint

```
POST https://verification.didit.me/v3/face-match/
```

### 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 to verify |
| `ref_image` | file | **Yes** | — | Same as above | Reference image to compare against |
| `face_match_score_decline_threshold` | integer | No | `30` | 0-100 | Scores below this = Declined |
| `rotate_image` | boolean | No | `false` | — | Try 0/90/180/270 degree rotations to find upright face |
| `save_api_request` | boolean | No | `true` | — | Save in Business Console Manual Checks |
| `vendor_data` | string | No | — | — | Your identifier for session tracking |

### Example

```python
import requests

response = requests.post(
    "https://verification.didit.me/v3/face-match/",
    headers={"x-api-key": "YOUR_API_KEY"},
    files={
        "user_image": ("selfie.jpg", open("selfie.jpg", "rb"), "image/jpeg"),
        "ref_image": ("id_photo.jpg", open("id_photo.jpg", "rb"), "image/jpeg"),
    },
    data={"face_match_score_decline_threshold": "50"},
)
```

```typescript
const formData = new FormData();
formData.append("user_image", selfieFile);
formData.append("ref_image", referenceFile);
formData.append("face_match_score_decline_threshold", "50");

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

### Response (200 OK)

```json
{
  "request_id": "a1b2c3d4-...",
  "face_match": {
    "status": "Approved",
    "score": 80,
    "user_image": {
      "entities": [
        {"age": 27.63, "bbox": [40, 40, 100, 100], "confidence": 0.717, "gender": "male"}
      ],
      "best_angle": 0
    },
    "ref_image": {
      "entities": [
        {"age": 22.16, "bbox": [156, 234, 679, 898], "confidence": 0.717, "gender": "male"}
      ],
      "best_angle": 0
    },
    "warnings": []
  },
  "created_at": "2025-05-01T13:11:07.977806Z"
}
```

### Status Values & Handling

| Status | Meaning | Action |
|---|---|---|
| `"Approved"` | Score >= threshold | Faces match — proceed |
| `"Declined"` | Score < threshold or no face | Check `warnings` for details. May need better image |
| `"In Review"` | Needs manual review | Wait for review or retrieve via session API |

### 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"`, `"Declined"`, `"In Review"` |
| `score` | integer | 0-100 similarity score (higher = more similar). `null` if no face found |
| `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"` |
| `best_angle` | integer | Best rotation angle for the face |
| `warnings` | array | `{risk, log_type, short_description, long_description}` |

---

## Warning Tags

| Tag | Description | Auto-Decline |
|---|---|---|
| `NO_REFERENCE_IMAGE` | Reference or face image missing | Yes |
| `NO_FACE_DETECTED` | No face detected in one or both images | Yes |
| `LOW_FACE_MATCH_SIMILARITY` | Score below threshold — potential identity mismatch | Configurable |

> **Security best practice:** Only store the status and score. Minimize biometric image data on your servers. Image URLs (in workflow mode) expire after 60 minutes.

---

## Score Interpretation

| Score Range | Interpretation | Action |
|---|---|---|
| 90-100 | Very high confidence — same person | Auto-approve |
| 70-89 | High confidence — likely same person | Approve (default threshold 30) |
| 50-69 | Moderate — possible match | Consider manual review |
| 30-49 | Low — likely different people | Declined at default threshold |
| 0-29 | Very low — different people | Declined |

---

## Utility Scripts

```bash
export DIDIT_API_KEY="your_api_key"

python scripts/match_faces.py selfie.jpg id_photo.jpg
python scripts/match_faces.py selfie.jpg id_photo.jpg --threshold 50 --rotate
```

Example Workflow

Here's how your AI assistant might use this skill in practice.

INPUT

User asks: Selfie-to-ID document verification during user onboarding

AGENT
  1. 1Selfie-to-ID document verification during user onboarding
  2. 2Confirming a returning user matches their registered profile photo
  3. 3Checking if two submitted photos show the same person
  4. 4Biometric access confirmation for a secure area or service
  5. 5KYC face check for financial or legal account opening
OUTPUT
Integrate Didit Face Match standalone API to compare two facial images.

Share this skill

Security Audits

VirusTotalBenign
OpenClawBenign
View full report

These signals reflect official OpenClaw status values. A Suspicious status means the skill should be used with extra caution.

Details

LanguageMarkdown
Last updatedMar 3, 2026