Skip to main content

Overview

Face Search is a 1:N biometric search: Didit takes the largest detected face in your user_image and searches it against your application’s face search index — faces enrolled from verification sessions, saved standalone API calls, direct user-profile face uploads, and your block/allow lists. It is distinct from Face Match, which is 1:1 — Face Match compares a selfie against the portrait on a specific document, while Face Search asks “have we seen this person anywhere before?”. Two behaviors are worth understanding before you parse the report:
  • Only blocklist matches decline. face_search.status is Declined only when a FACE_IN_BLOCKLIST or POSSIBLE_FACE_IN_BLOCKLIST warning fires. Duplicate matches alone return Approved — inspect matches and warnings, not just status.
  • Optional persistence and enrollment. When save_api_request=true (the default), the call is persisted as an API-type session and the searched face is enrolled into your face search index. Faces enrolled by Face Search calls are excluded from future Face Search results, so repeated searches never match each other. Pass save_api_request=false for a one-shot query: nothing is stored and the face is not enrolled.

Where the results appear

Face Search is a standalone API. The search results are returned synchronously, in the POST /v3/face-search/ response only, as a singular face_search object at the top level:
There is no plural face_searches[] array anywhere — the plural-array convention used by id_verifications[], aml_screenings[], and liveness_checks[] on the session decision endpoint does not apply. When save_api_request=true (the default), the call is also persisted as an API-type session:
  • Business Console — the session appears in your sessions list with the search image, matches, and warnings.
  • GET /v3/session/{sessionId}/decision/ — retrievable using the returned request_id as the session id. The persisted data surfaces as a FACE_SEARCH entry in features[] and as a liveness_checks[] item carrying the stored matches (with freshly signed match_image_url values) and warningsnot as a face_search object.
When save_api_request=false, request_id is a transient correlation UUID: the session is never stored, so it cannot be fetched from the Console or the decision endpoint.

Schema

See Face Search in the Data Models reference for the canonical field tables. The shape below reflects what the endpoint actually returns at runtime.
Field notes:
  • matches[] is capped at 5 entries above the similarity floor, ordered by descending similarity (search_type=blocklisted_or_approved ranks blocklisted entries first, then allowlisted, then similarity).
  • source tells you where the matched face was enrolled from: session — a verification session or a saved standalone API call; imported — a face uploaded directly to a user profile; list_entry — a face attached to one of your lists. session_id, session_number, status, and api_service are null for imported and list_entry matches.
  • api_service is the matched session’s standalone API type (uppercase, e.g. PASSIVE_LIVENESS) and null when the matched face came from a regular workflow verification session.
  • user_details comes from the matched session’s document verification. For source: imported matches it is populated from the user profile instead (full_name set, document_type/document_number null); it is null when no identity data exists (for example liveness-only sessions).
  • Warnings use a reduced shape compared with workflow warnings: there is no node_id. The documented response contract (FaceSearchResponseSerializer) declares the five fields risk, additional_data, log_type, short_description, long_description; the runtime payload additionally carries feature, which is always "LIVENESS" here. See Face Search warnings.
  • Same-user matches are not excluded — unlike workflow duplicate detection, the standalone endpoint does not filter out prior sessions with the same vendor_data, so a returning legitimate user matches their own earlier sessions.

Status values

The top-level face_search.status is derived from warnings[]. The match-level status reflects the matched session’s verification outcome and is independent. Note: when the search image contains no detectable face the API returns HTTP 400 with {"error": "No face detected in the image"} before a face_search object is built — there is no Declined status for that case. Insufficient credits return HTTP 403 before any image processing.

Examples

Approved — duplicate match, no blocklist

Declined — blocklist match

When save_api_request=true, match_image_url values are signed, short-lived URLs — re-fetch the session decision endpoint with the returned request_id to get fresh ones. When save_api_request=false, they are internal storage paths and are not directly downloadable. Store only the matched session id, status, and similarity_percentage on your side — do not retain the underlying biometric image.