curl --request POST \
--url https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"image": "<string>",
"name": "<string>",
"performDuplicateDetection": true
}
'import requests
url = "https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough"
payload = {
"image": "<string>",
"name": "<string>",
"performDuplicateDetection": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({image: '<string>', name: '<string>', performDuplicateDetection: true})
};
fetch('https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'image' => '<string>',
'name' => '<string>',
'performDuplicateDetection' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough"
payload := strings.NewReader("{\n \"image\": \"<string>\",\n \"name\": \"<string>\",\n \"performDuplicateDetection\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"image\": \"<string>\",\n \"name\": \"<string>\",\n \"performDuplicateDetection\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"image\": \"<string>\",\n \"name\": \"<string>\",\n \"performDuplicateDetection\": true\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "No matches found.",
"data": {
"duplicateDetection": {
"hasMatches": false,
"enrolled": true,
"matches": []
}
},
"verificationStatus": "VERIFIED",
"verificationStatusCode": 3,
"transactionId": "a2f1c0de-8b4a-4c1d-9e2f-1a3b5c7d9e0f",
"verificationType": "biometrics_detection",
"metadata": {
"customerReference": "CUST-10294"
},
"createdAt": "2026-09-15T04:21:08Z"
}Biometrics Detection
Screen a face against your duplicate watchlist and biometric blacklists in one call, without liveness or Trust Validation.
curl --request POST \
--url https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"image": "<string>",
"name": "<string>",
"performDuplicateDetection": true
}
'import requests
url = "https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough"
payload = {
"image": "<string>",
"name": "<string>",
"performDuplicateDetection": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({image: '<string>', name: '<string>', performDuplicateDetection: true})
};
fetch('https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'image' => '<string>',
'name' => '<string>',
'performDuplicateDetection' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough"
payload := strings.NewReader("{\n \"image\": \"<string>\",\n \"name\": \"<string>\",\n \"performDuplicateDetection\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"image\": \"<string>\",\n \"name\": \"<string>\",\n \"performDuplicateDetection\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"image\": \"<string>\",\n \"name\": \"<string>\",\n \"performDuplicateDetection\": true\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "No matches found.",
"data": {
"duplicateDetection": {
"hasMatches": false,
"enrolled": true,
"matches": []
}
},
"verificationStatus": "VERIFIED",
"verificationStatusCode": 3,
"transactionId": "a2f1c0de-8b4a-4c1d-9e2f-1a3b5c7d9e0f",
"verificationType": "biometrics_detection",
"metadata": {
"customerReference": "CUST-10294"
},
"createdAt": "2026-09-15T04:21:08Z"
}transactionId you can store; there is no Trust Flow, no Trust Validation, and no combined IDmeta outcome beyond the statuses below.
For liveness plus optional duplicate and blacklist screening on the same selfie, use Biometrics Verification instead.
Before you call
performDuplicateDetection is true, the submitted face is enrolled into your company’s duplicate watchlist as a side effect. That enrolment is what allows later calls to match it. Enable duplicate detection only when you intend to add this face to the watchlist under name.Authentication and plan
Same as other/api/v3 Stateless Verification API endpoints: Bearer token (Authorization: Bearer <token>) or HMAC headers (X-HMAC-SIGNATURE, X-TIMESTAMP, X-USER-ID). See Introduction — Authentication.
Your company must hold the biometrics_detection plan. Without it, the API returns HTTP 403 before any screening runs.
Verification status
| Status | Code | When |
|---|---|---|
VERIFIED | 3 | Screening ran and matched nobody. |
REVIEW_NEEDED | 2 | Duplicate detection, blacklist detection, or both found matches. |
FAILED | 6 | Screening could not run (unreadable image, no face, engine unreachable, and similar). |
REJECTED. A duplicate or blacklist hit is a finding for you to act on; IDmeta does not decide whether the subject should be blocked.Interpret data
Request flags control which keys appear in data. Duplicate-only requests omit blacklistDetection entirely — not null, not an empty object.
When a requested check completes, read hasMatches as a boolean. When it could not run, hasMatches is null with an error string. null is not a clean screen — treat it as an unknown outcome and do not approve on that basis alone.
Duplicate matches always include transactionId (the earlier biometrics detection call that enrolled the matched face). Blacklist matches always include blacklistFaceUploadId. Other fields inside each match object come from the face-identity engine (similarity scores, names, and so on).
Billing
A completed screening is billed whether or not it found matches. Validation errors, unresolvable blacklists, unreadable images, and engine failures release the credit reservation and are not charged.Examples
Replace{environment-subdomain}, {your_api_token}, and HMAC headers with your values.
1. Duplicate detection only, clean (VERIFIED)
curl -X POST "https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough" \
-H "Authorization: Bearer {your_api_token}" \
-H "Content-Type: application/json" \
-d '{
"image": "data:image/jpeg;base64,/9j/4AAQ...",
"name": "Applicant 88421",
"performDuplicateDetection": true,
"performBlacklistDetection": false
}'
{
"success": true,
"message": "No matches found.",
"data": {
"duplicateDetection": {
"hasMatches": false,
"enrolled": true,
"matches": []
}
},
"verificationStatus": "VERIFIED",
"verificationStatusCode": 3,
"transactionId": "a2f1c0de-8b4a-4c1d-9e2f-1a3b5c7d9e0f",
"verificationType": "biometrics_detection",
"metadata": null,
"createdAt": "2026-09-15T04:21:08Z"
}
2. Duplicate and blacklist, duplicate hit (REVIEW_NEEDED)
curl -X POST "https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough" \
-H "Authorization: Bearer {your_api_token}" \
-H "Content-Type: application/json" \
-d '{
"image": "data:image/jpeg;base64,/9j/4AAQ...",
"name": "Applicant 88421",
"performDuplicateDetection": true,
"performBlacklistDetection": true,
"blacklistIds": ["6f1c2a90-8d3b-4f2e-9c11-7ab5d0e34f89"]
}'
{
"success": true,
"message": "Matches found.",
"data": {
"duplicateDetection": {
"hasMatches": true,
"enrolled": true,
"matches": [
{
"name": "Prior applicant",
"similarity_score": 97.2,
"transactionId": "c0a8012e-5f44-4d2a-9b71-0e8f3a6c1d54"
}
]
},
"blacklistDetection": {
"hasMatches": false,
"blacklists": [
{
"blacklistId": "6f1c2a90-8d3b-4f2e-9c11-7ab5d0e34f89",
"blacklistName": "Known fraud ring",
"hasMatches": false,
"matches": []
}
]
}
},
"verificationStatus": "REVIEW_NEEDED",
"verificationStatusCode": 2,
"transactionId": "b3e4f5a6-7c8d-4e9f-a0b1-2c3d4e5f6a7b",
"verificationType": "biometrics_detection",
"metadata": null,
"createdAt": "2026-09-15T04:22:41Z"
}
3. Blacklist hit on one of two lists (REVIEW_NEEDED)
curl -X POST "https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough" \
-H "Authorization: Bearer {your_api_token}" \
-H "Content-Type: application/json" \
-d '{
"image": "data:image/jpeg;base64,/9j/4AAQ...",
"name": "Screening only",
"performDuplicateDetection": false,
"performBlacklistDetection": true,
"blacklistIds": [
"6f1c2a90-8d3b-4f2e-9c11-7ab5d0e34f89",
"a1b2c3d4-e5f6-7890-abcd-ef1234567890"
]
}'
{
"success": true,
"message": "Matches found.",
"data": {
"blacklistDetection": {
"hasMatches": true,
"blacklists": [
{
"blacklistId": "6f1c2a90-8d3b-4f2e-9c11-7ab5d0e34f89",
"blacklistName": "Known fraud ring",
"hasMatches": true,
"matches": [
{
"name": "Blocked subject",
"similarity_score": 94.8,
"blacklistFaceUploadId": "d4e5f6a7-8b9c-4d0e-a1b2-3c4d5e6f7a8b"
}
]
},
{
"blacklistId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"blacklistName": "Partner deny list",
"hasMatches": false,
"matches": []
}
]
}
},
"verificationStatus": "REVIEW_NEEDED",
"verificationStatusCode": 2,
"transactionId": "c4d5e6f7-8a9b-4c0d-b1c2-3d4e5f6a7b8c",
"verificationType": "biometrics_detection",
"metadata": null,
"createdAt": "2026-09-15T04:24:15Z"
}
4. Unknown blacklist id (404 BLACKLIST_NOT_FOUND)
curl -X POST "https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough" \
-H "Authorization: Bearer {your_api_token}" \
-H "Content-Type: application/json" \
-d '{
"image": "data:image/jpeg;base64,/9j/4AAQ...",
"name": "Applicant 88421",
"performDuplicateDetection": false,
"performBlacklistDetection": true,
"blacklistIds": ["00000000-0000-4000-8000-000000000000"]
}'
{
"success": false,
"code": "BLACKLIST_NOT_FOUND",
"message": "No active blacklist was found for the supplied blacklistIds.",
"verificationStatus": "FAILED",
"verificationStatusCode": 6,
"transactionId": "a2f1c0de-8b4a-4c1d-9e2f-1a3b5c7d9e0f",
"verificationType": "biometrics_detection",
"metadata": null,
"createdAt": "2026-09-15T04:21:08Z"
}
5. Engine unreachable (FAILED, hasMatches: null)
curl -X POST "https://{environment-subdomain}.idmetagroup.com/api/v3/verifications/biometrics-detection-passthrough" \
-H "Authorization: Bearer {your_api_token}" \
-H "Content-Type: application/json" \
-d '{
"image": "data:image/jpeg;base64,/9j/4AAQ...",
"name": "Applicant 88421",
"performDuplicateDetection": true,
"performBlacklistDetection": false
}'
{
"success": false,
"message": "Failed to process biometrics detection",
"data": {
"duplicateDetection": {
"hasMatches": null,
"error": "Face identity service unavailable."
}
},
"verificationStatus": "FAILED",
"verificationStatusCode": 6,
"transactionId": "a2f1c0de-8b4a-4c1d-9e2f-1a3b5c7d9e0f",
"verificationType": "biometrics_detection",
"metadata": null,
"createdAt": "2026-09-15T04:21:08Z"
}
502. Responses that include a top-level code omit data entirely; this failure has no code and returns per-check errors in data instead.Authorizations
Use your API token as a Bearer token in the Authorization header, or HMAC signature headers (X-HMAC-SIGNATURE, X-TIMESTAMP, X-USER-ID) as for other v3 endpoints.
Headers
"Bearer {your_api_token}"
Body
Base64 data URI (data:image/jpeg;base64,...) or a multipart file when posting multipart/form-data. Bare base64 without the data: prefix is rejected.
Label for enrolment into the duplicate watchlist. Reported on future duplicate matches.
255When true, screens against the duplicate watchlist and enrols this face. Required; not defaulted.
When true, screens against the blacklists in blacklistIds. Does not enrol into blacklists.
UUID strings of active biometric blacklists. Required in practice when performBlacklistDetection is true. Unresolvable ids yield HTTP 404 BLACKLIST_NOT_FOUND.
Free-form data echoed unchanged on the response.
Response
Screening completed. Clean and match outcomes use HTTP 200. Match findings set verificationStatus to REVIEW_NEEDED; a clean screen sets VERIFIED.
true
Only keys for checks requested on the call are present.
Show child attributes
Show child attributes
Never REJECTED. VERIFIED = no matches; REVIEW_NEEDED = at least one match; FAILED only when returned on error paths with screening failure.
VERIFIED, REVIEW_NEEDED, FAILED 3 = Verified, 2 = Review Needed, 6 = Failed.
3, 2, 6 Correlate this call in your systems. Duplicate matches reference earlier enrolment transaction ids.
"biometrics_detection"

