Overview
Face Search is a 1:N biometric search: Didit takes the largest detected face in youruser_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.statusisDeclinedonly when aFACE_IN_BLOCKLISTorPOSSIBLE_FACE_IN_BLOCKLISTwarning fires. Duplicate matches alone returnApproved— inspectmatchesandwarnings, not juststatus. - 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. Passsave_api_request=falsefor 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 thePOST /v3/face-search/ response only, as a singular face_search object at the top level:
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 returnedrequest_idas the session id. The persisted data surfaces as aFACE_SEARCHentry infeatures[]and as aliveness_checks[]item carrying the storedmatches(with freshly signedmatch_image_urlvalues) andwarnings— not as aface_searchobject.
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.matches[]is capped at 5 entries above the similarity floor, ordered by descending similarity (search_type=blocklisted_or_approvedranks blocklisted entries first, then allowlisted, then similarity).sourcetells 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, andapi_servicearenullforimportedandlist_entrymatches.api_serviceis the matched session’s standalone API type (uppercase, e.g.PASSIVE_LIVENESS) andnullwhen the matched face came from a regular workflow verification session.user_detailscomes from the matched session’s document verification. Forsource: importedmatches it is populated from the user profile instead (full_nameset,document_type/document_numbernull); it isnullwhen 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 fieldsrisk,additional_data,log_type,short_description,long_description; the runtime payload additionally carriesfeature, 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-levelface_search.status is derived from warnings[]. The match-level status reflects the matched session’s verification outcome and is independent.
| Value | When it appears |
|---|---|
Approved | No blocklist warning fired. Includes the case where duplicate matches were found — duplicates are informational signals, not declines. |
Declined | A FACE_IN_BLOCKLIST or POSSIBLE_FACE_IN_BLOCKLIST warning fired — the search image matched a face in your face blocklist. |
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
Related
- Face Search warnings — every warning code the search can emit
- Face Search API reference — request parameters and
search_typemodes - Data models — Face Search — canonical schema
- Webhooks —
status.updatedpayloads for persisted sessions
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.