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

# Face Search 1:N

> Search faces across all verified users to spot duplicates and blocklisted fraudsters. Free with Didit identity verification, sub-2-second response.

export const AgentPromptAccordion = ({prompt, title = "AI Agent Integration Prompt"}) => {
  const [copied, setCopied] = React.useState(false);
  const handleCopy = e => {
    e.stopPropagation();
    if (!prompt) return;
    navigator.clipboard.writeText(prompt.trim()).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  };
  const agents = ["Claude Code", "Codex", "Cursor", "Devin", "Windsurf", "GitHub Copilot"];
  return <div className="didit-agent-card">
      {}
      <div className="didit-agent-titlebar">
        <div className="didit-agent-dots" aria-hidden="true">
          <span className="didit-agent-dot didit-agent-dot-red"></span>
          <span className="didit-agent-dot didit-agent-dot-yellow"></span>
          <span className="didit-agent-dot didit-agent-dot-green"></span>
        </div>
        <span className="didit-agent-filename">{title}</span>
        <button type="button" className={`didit-agent-copy ${copied ? "didit-agent-copy-copied" : ""}`} onClick={handleCopy} title="Copy prompt to clipboard" aria-label={copied ? "Copied!" : "Copy prompt to clipboard"}>
          {copied ? <>
              <svg width="13" height="13" viewBox="0 0 16 16" fill="none">
                <path d="M3 8.5l3.5 3.5L13 4" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
              <span>Copied</span>
            </> : <>
              <svg width="13" height="13" viewBox="0 0 16 16" fill="none">
                <rect x="5" y="5" width="9" height="9" rx="1.5" stroke="currentColor" strokeWidth="1.5" />
                <path d="M11 5V3.5A1.5 1.5 0 0 0 9.5 2h-6A1.5 1.5 0 0 0 2 3.5v6A1.5 1.5 0 0 0 3.5 11H5" stroke="currentColor" strokeWidth="1.5" />
              </svg>
              <span>Copy</span>
            </>}
        </button>
      </div>

      {}
      <pre className="didit-agent-body"><code>{prompt.trim()}</code></pre>

      {}
      <div className="didit-agent-footer">
        <span className="didit-agent-footer-label">Paste into</span>
        <div className="didit-agent-chips">
          {agents.map(name => <span key={name} className="didit-agent-chip">{name}</span>)}
        </div>
      </div>
    </div>;
};

export const VideoEmbed = ({src, title = "Video", type = "iframe"}) => <div className={type === "iframe" ? "didit-video-embed" : "didit-video-embed didit-video-native"}>
    {type === "iframe" ? <iframe src={src} title={title} style={{
  width: "100%",
  height: "100%",
  border: 0,
  borderRadius: "12px"
}} allow="accelerometer; autoplay; clipboard-write; compute-pressure; encrypted-media; gyroscope; picture-in-picture" allowFullScreen /> : <video controls autoPlay muted loop playsInline src={src} title={title} style={{
  width: "100%",
  height: "auto",
  display: "block",
  borderRadius: "12px"
}} />}
  </div>;

Face Search is a powerful feature that allows you to search for a specific face across all your approved identity verification sessions. This capability helps identify duplicate accounts, prevent fraud, and enhance your security measures.

<AgentPromptAccordion
  title="Face Search Integration Prompt"
  prompt={`# Goal
Integrate Didit Face Search (1:N — search a face across your enrolled users + blocklist) into your app.

# Delivery mode
Face Search is a **standalone API**. It runs against the face index your application has enrolled through prior verifications (sessions with save_api_request=true or Passive Liveness with save_api_request=true), faces uploaded to User profiles, your face lists, and any image-free biometric templates the application retained after deleting sessions (opt-in, see /management-api/biometric-templates/overview). There is no separate Face Search workflow feature.

POST https://verification.didit.me/v3/face-search/
multipart/form-data — x-api-key: YOUR_API_KEY

Required: \`user_image\` (jpg/jpeg/png/tiff/webp, max 5 MB; PDFs not accepted). The image must contain at least one detectable face (largest bbox wins when multiple).

Optional: \`search_type\` = "most_similar" (default — dedupe / returning-user) | "blocklisted_or_approved" (blocklist screening).

curl example:
\`\`\`bash
curl -X POST 'https://verification.didit.me/v3/face-search/' \\
-H 'x-api-key: YOUR_API_KEY' \\
-F 'user_image=@./selfie.jpg' \\
-F 'search_type=most_similar' \\
-F 'save_api_request=true' \\
-F 'vendor_data=user-123'
\`\`\`

# Response shape (singular)
Unlike most features, Face Search returns a **singular** \`face_search\` object — not a plural array:
{ request_id, face_search: { status, total_matches, matches: [{ session_id, session_number, similarity_percentage, source, vendor_data, vendor_user_id, biometric_template_id, verification_date, user_details, match_image_url, status, is_blocklisted, is_allowlisted, api_service }], user_image: {entities}, warnings: [...] } }

match.source is "session", "imported", "list_entry", or "retained_template". A retained_template hit comes from an image-free biometric template kept after the source session was deleted: session_id, session_number, status, api_service, match_image_url, and user_details are null; vendor_data and vendor_user_id identify the User; biometric_template_id is the template you can inspect or purge via /v3/biometric-templates/{id}/.

\`status\` is "Declined" only when at least one blocklist match is found. Pure duplicate matches return "Approved" (informational) — apply your own dedupe policy in app logic.

# Warnings
Face Search emits risk codes from the LogWarningChoices.FACEMATCH bucket plus blocklist/duplicate semantics:
FACE_IN_BLOCKLIST, POSSIBLE_FACE_IN_BLOCKLIST, DUPLICATED_FACE, POSSIBLE_DUPLICATED_FACE, MULTIPLE_FACES_DETECTED.
Full catalogue: /core-technology/face-search/warnings-face-search.

# Failure modes to handle
- HTTP 400 — no face detected in user_image. Ask the user to retake.
- HTTP 403 — out of credits.
- status="Declined" with FACE_IN_BLOCKLIST — definitive blocklist hit; reject.
- POSSIBLE_FACE_IN_BLOCKLIST — borderline match below the hard threshold; route to manual review.
- DUPLICATED_FACE — user already verified under a different vendor_data; merge or block according to policy.

# See also
- Canonical schema: /reference/data-models#face-search
- Per-feature report: /core-technology/face-search/report-face-search
- Risk catalogue: /core-technology/face-search/warnings-face-search
- Full integration playbook: /integration/integration-prompt`}
/>

The Academy lesson on reading a verification result reaches face search and block lists at 6:53.

<VideoEmbed src="https://www.youtube.com/embed/7htTWCWsl60?start=413&rel=0&playsinline=1" title="Face search and block lists — Didit Academy" />

<Frame>
  <img src="https://mintcdn.com/didit-0f962782/z6T2GHM4Zh-iSj-K/images/face-search-liveness.png?fit=max&auto=format&n=z6T2GHM4Zh-iSj-K&q=85&s=0cb5738f8ceaae7891cf13631485c400" alt="Didit face search 1:N flow integrated with liveness for duplicate and blocklist detection" width="1953" height="1304" data-path="images/face-search-liveness.png" />
</Frame>

## Automatic Face Search Integration

> Face Search is automatically performed during liveness checks in verification sessions to detect duplicate users and check against blocklisted faces.

### Automatic Duplicate Detection

When a user completes a liveness check during identity verification:

* Their facial biometrics are automatically compared against all previously verified users
* The system identifies potential duplicate accounts based on facial similarity
* Matches are flagged according to your configured similarity thresholds
* You can review and take action on potential duplicate users

### Blocklist Integration

Face Search seamlessly integrates with the [blocklist feature](/management-api/lists/overview):

* During verification, faces are automatically checked against your blocklist
* If a match to a blocklisted face is found, the verification is automatically declined
* This prevents previously identified problematic users from creating new accounts
* Helps maintain the integrity of your verification process

### The selfie taken during document capture

While the user photographs their document, the front camera takes a selfie of them (Silent Capture). Every time the document is evaluated, that selfie goes through the same 1:N search as the liveness selfie:

* It is compared against your face blocklist and against the users already approved in your application, with the same similarity thresholds and the same precedence as the liveness search.
* A blocklist match raises `FRONT_CAMERA_FACE_IN_BLOCKLIST` (always Declined) or `POSSIBLE_FRONT_CAMERA_FACE_IN_BLOCKLIST` (always Review). A match with an approved user raises `FRONT_CAMERA_DUPLICATED_FACE` or `POSSIBLE_FRONT_CAMERA_DUPLICATED_FACE`, plus `FRONT_CAMERA_DUPLICATED_FACE_NAME_MISMATCH` when that approved user was verified under a different name, and `FRONT_CAMERA_DUPLICATED_FACE_DOCUMENT_MISMATCH` when that user's identity document shows a different date of birth. See [ID verification warnings](/core-technology/id-verification/warnings-id-verification).
* The matches are listed in the session details, in the ID verification card, and returned in `id_verifications[].document_selfie_face_matches` of the [session decision](/sessions-api/retrieve-session). It uses the same entry format as `liveness_checks[].matches`. The field is `null` for older sessions or when the search did not run, and an empty array when it ran and found nothing. `match_image_url` is a presigned URL that expires.
* Only the largest face in the selfie is used, and only when the detector is confident it is a face. One selfie per document is searched: the front-side one, or the back-side one when the front-side selfie holds no clear face.
* The selfie is only compared. Its biometric template is never stored, so later sessions are never matched against it. To ban a person from a session's selfie, add it to your face blocklist from the session page.

The search has its own switch and its own actions on the **ID Verification** step, in the step's **Rules** tab (**Silent Capture Face Search**), or with `document_selfie_face_search_enabled` and the `document_selfie_duplicated_face_*` actions in the [workflow feature config](/management-api/workflows/feature-configs#ocr-/-id-verification). It is on by default; the duplicated-face action defaults to Approve (the warning is still reported) and the name and document cross-checks default to Review, like their liveness counterparts. The search needs the selfie, so it only runs when Silent Capture is on. Turning Face Search off on the Liveness step turns this search off too: that opt-out is a choice about the person's face, so it covers every selfie of the session.

### The document mismatch rule

The **document mismatch** rule (`DUPLICATED_FACE_DOCUMENT_MISMATCH` for the liveness selfie, `FRONT_CAMERA_DUPLICATED_FACE_DOCUMENT_MISMATCH` for Silent Capture) flags a duplicated face only when the matched user's identity document shows a different date of birth.
The same person presenting a different document, for example a passport after an ID card, is not flagged.
A renewed document is not flagged either.
Two sessions that share the same document number from the same country are never flagged.

### Turning automatic Face Search off

Automatic Face Search is on by default for every Liveness step. If your privacy posture calls for it, you can switch it off per workflow from the **Liveness** step's **Rules** tab in the Business Console (Simple and Advanced Mode), or with `face_search_enabled: false` on the `LIVENESS` or `AGE_ESTIMATION` node in the [workflow feature config](/management-api/workflows/feature-configs#liveness).

With the switch off, the liveness selfie is still scored for liveness and compared 1:1 against the document portrait in Face Match, but it never reaches the face index:

* No search runs, so the session gets no duplicate, blocklist or allowlist verdict and its `liveness_checks[].matches` stays empty. The **Duplicated face**, **name mismatch**, **document mismatch** and cross-organization face rules have nothing to act on and are hidden in the Console.
* No biometric template is stored for the selfie, so later sessions cannot be matched against this one and there is nothing for [biometric-template retention](/console/data-retention#biometric-template-retention) to keep after the session is deleted.
* The selfie is not used to resolve a shared biometric person for cross-organization checks.
* The selfie taken during document capture is not searched either (no `FRONT_CAMERA_*` blocklist or duplicate risk): the opt-out covers every selfie of the session. The ID Verification step's own switch (see above) can also turn that search off on its own.

**Which step the switch belongs to.** The switch sits on the step that captures the selfie, so a **Liveness** or **Age Estimation** step answers for itself. A **Face Match** step has none of its own: when a user retakes the selfie there - after you ask them to resubmit that step, for example - the retake follows the Liveness step's setting, so an opt-out keeps the new selfie out of the index too. If your workflow branches into more than one Liveness step, the setting that applies is the one on the branch the session actually went through, and the cross-organization face read follows that same step.

Existing workflows keep today's behavior until you opt out. The change applies to sessions started after the workflow is saved; templates stored by earlier sessions stay in the index until those sessions are deleted or purged. The switch does not affect the standalone [Face Search API](/standalone-apis/face-search), which you call explicitly.

<Warning>
  Your face blocklist is enforced during verification by the same 1:N search. With Face Search off on the Liveness step, a blocklisted person is caught neither at that step nor by the selfie taken during document capture; with Silent Capture Face Search off on the ID Verification step, not by that selfie.
</Warning>

### API Access

Face Search functionality is also available through our [API](/standalone-apis/face-search), allowing you to:

* Programmatically submit face searches
* Integrate face matching capabilities into your own applications
* Build custom fraud detection workflows
* Create automated systems for duplicate detection

## Key Features

* **High Accuracy**: Advanced biometric algorithms provide reliable match results
* **Configurable Thresholds**: Customize match sensitivity based on your risk tolerance
* **Comprehensive Scanning**: Search across all your verified users
* **Rapid Results**: Process searches quickly even with large user databases
* **Privacy-Focused**: Matching uses numeric face templates scoped to your application; the index never leaves your tenant

### Configurable Thresholds

You can customize search sensitivity by setting different thresholds for similarity scores:

<Note>
  These thresholds can be adjusted based on your risk tolerance and security requirements.
</Note>

## How It Works

<Steps>
  <Step title="Face Extraction" icon="face-viewfinder">
    When a search is initiated, the system processes the reference image:

    | Process | Description |
    | - | - |
    | **Feature extraction** | Isolates facial features from the reference image |
    | **Normalization** | Standardizes facial data for consistent comparison |
    | **Quality validation** | Checks image quality and facial clarity |
    | **Vector encoding** | Creates a mathematical vector representation of the face |
  </Step>

  <Step title="Comparison Algorithm" icon="magnifying-glass">
    The system searches across your entire database of verified sessions:

    * Compares the reference facial vector against **every face enrolled in your application**: session faces, faces uploaded to User profiles, your face lists, and any retained biometric templates
    * Employs advanced neural network architecture optimized for speed and accuracy
    * Supports two search modes: **most similar** (ranked list) and **blocklisted or approved** (status-filtered)
    * Processes large databases rapidly using optimized indexing
  </Step>

  <Step title="Similarity Scoring" icon="percent">
    For each comparison, a similarity percentage is generated:

    | Score Range | Interpretation |
    | :-: | - |
    | **90%+** | Strong match — very likely the same person |
    | **70–89%** | Possible match — may require manual review |
    | **Below 70%** | Likely different individuals |

    Your configured match thresholds determine which results are flagged.
  </Step>

  <Step title="Results Delivery" icon="file-export">
    The system returns a comprehensive result set:

    * **Ranked list** of potential matches sorted by similarity score
    * **Match details** including session ID, verification date, and vendor data
    * **Similarity percentage** for each match
    * **Match images** available for visual review
    * **Blocklist status** indicating if the matched face is blocklisted
  </Step>
</Steps>

## Deleted sessions and retained biometric templates

Deleting a session deletes its face embedding by default, so the person drops out of the index and can verify again without a duplicate flag. Applications that delete sessions soon after approval but still need to catch repeat sign-ups can enable [biometric-template retention](/console/data-retention#biometric-template-retention). Didit then keeps one image-free biometric template anchored to the User after the session is deleted, and that template takes part in Face Search and automatic duplicate detection exactly like a live session face.

A hit on a retained template is reported with `source: "retained_template"`, the owning User's `vendor_user_id` and `vendor_data`, and a `biometric_template_id`. It carries no session id, match image, identity details, or session status, because the session that produced the face no longer exists. Retained templates are never blocklisted; face blocklist entries keep their own independent biometric entry.

The template stays until its scheduled expiry, User deletion, a privacy-erasure request, or an explicit purge through the [Biometric Templates API](/management-api/biometric-templates/overview) or **Lists → Biometric templates** in the Console.

## Similarity Percentage

The similarity percentage is the core metric used to determine potential matches:

* **High percentage (typically 90% and above)**: Indicates a strong likelihood that the faces belong to the same person.
* **Medium percentage (70-89%)**: Suggests possible matches that may require further review.
* **Low percentage (below 70%)**: Likely indicates different individuals.

The exact threshold for what constitutes a "match" can be configured based on your security requirements. Increasing the threshold reduces false positives but may increase false negatives.

## Use Cases

* **Fraud Prevention**: Identify users attempting to create multiple accounts
* **Enhanced KYC**: Add an additional layer of verification to your KYC process
* **Regulatory Compliance**: Meet requirements for detecting duplicate accounts
* **Access Control**: Verify user authenticity for high-security areas
* **Law Enforcement**: Assist authorized agencies in identifying persons of interest


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