curl -X POST 'https://verification.didit.me/v3/passive-liveness/' \
-H 'x-api-key: YOUR_API_KEY' \
-F 'user_image=@./selfie.jpg' \
-F 'face_liveness_score_decline_threshold=30' \
-F 'save_api_request=true' \
-F 'vendor_data=user-123'from didit import Didit
# Reads DIDIT_API_KEY.
client = Didit()
result = client.passive_liveness.check(
user_image=open("user_image.jpg", "rb"),
face_liveness_score_decline_threshold=30.0,
rotate_image=False,
save_api_request=True,
vendor_data="user-123",
metadata={"flow": "withdrawal"},
)
print(result)import Didit, { fileFromPath } from "@didit-protocol/sdk-node";
// Reads DIDIT_API_KEY.
const didit = new Didit();
const result = await didit.passiveLiveness.check({
user_image: await fileFromPath("user_image.jpg"),
face_liveness_score_decline_threshold: 30.0,
rotate_image: false,
save_api_request: true,
vendor_data: "user-123",
metadata: { flow: "withdrawal" },
});
console.log(result);ctx := context.Background()
// Reads DIDIT_API_KEY.
client := didit.NewClient()
result, err := client.PassiveLiveness.Check(ctx, didit.PassiveLivenessCheckParams{
UserImage: didit.FileFromPath("user_image.jpg"),
FaceLivenessScoreDeclineThreshold: didit.Float(30.0),
RotateImage: didit.Bool(false),
SaveAPIRequest: didit.Bool(true),
VendorData: didit.String("user-123"),
Metadata: didit.Some(map[string]any{"flow": "withdrawal"}),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)import java.nio.file.Path;
import java.util.Map;
import me.didit.Didit;
import me.didit.types.PassiveLivenessCheckParams;
// Reads DIDIT_API_KEY.
Didit client = new Didit();
var result = client.passiveLiveness().check(PassiveLivenessCheckParams.builder()
.userImage(Path.of("user_image.jpg"))
.faceLivenessScoreDeclineThreshold(30.0)
.rotateImage(false)
.saveApiRequest(true)
.vendorData("user-123")
.metadata(Map.of("flow", "withdrawal"))
.build());
System.out.println(result);<?php
require 'vendor/autoload.php';
use Didit\DiditClient;
use Didit\File;
// Reads DIDIT_API_KEY.
$didit = new DiditClient();
$result = $didit->passiveLiveness->check([
'user_image' => File::fromPath('user_image.jpg'),
'face_liveness_score_decline_threshold' => 30.0,
'rotate_image' => false,
'save_api_request' => true,
'vendor_data' => 'user-123',
'metadata' => ['flow' => 'withdrawal'],
]);
print_r($result->toArray());require "didit"
# Reads DIDIT_API_KEY.
didit = Didit::Client.new
result = didit.passive_liveness.check(
user_image: Pathname("user_image.jpg"),
face_liveness_score_decline_threshold: 30.0,
rotate_image: false,
save_api_request: true,
vendor_data: "user-123",
metadata: { flow: "withdrawal" }
)
puts result.to_husing System;
using System.Collections.Generic;
using System.Text.Json;
using Didit;
// Reads DIDIT_API_KEY.
using var client = new DiditClient();
var result = await client.PassiveLiveness.CheckAsync(new PassiveLivenessCheckParams
{
UserImage = FileUpload.FromPath("user_image.jpg"),
FaceLivenessScoreDeclineThreshold = 30.0,
RotateImage = false,
SaveApiRequest = true,
VendorData = "user-123",
Metadata = new Dictionary<string, object> { ["flow"] = "withdrawal" },
});
Console.WriteLine(JsonSerializer.Serialize(result));Passive Liveness API: Deepfake Detection
Detect masks, prints, replays, and deepfakes from a single image. Fully passive, sub-2s inference, pay-per-use pricing, no monthly minimums.
curl -X POST 'https://verification.didit.me/v3/passive-liveness/' \
-H 'x-api-key: YOUR_API_KEY' \
-F 'user_image=@./selfie.jpg' \
-F 'face_liveness_score_decline_threshold=30' \
-F 'save_api_request=true' \
-F 'vendor_data=user-123'from didit import Didit
# Reads DIDIT_API_KEY.
client = Didit()
result = client.passive_liveness.check(
user_image=open("user_image.jpg", "rb"),
face_liveness_score_decline_threshold=30.0,
rotate_image=False,
save_api_request=True,
vendor_data="user-123",
metadata={"flow": "withdrawal"},
)
print(result)import Didit, { fileFromPath } from "@didit-protocol/sdk-node";
// Reads DIDIT_API_KEY.
const didit = new Didit();
const result = await didit.passiveLiveness.check({
user_image: await fileFromPath("user_image.jpg"),
face_liveness_score_decline_threshold: 30.0,
rotate_image: false,
save_api_request: true,
vendor_data: "user-123",
metadata: { flow: "withdrawal" },
});
console.log(result);ctx := context.Background()
// Reads DIDIT_API_KEY.
client := didit.NewClient()
result, err := client.PassiveLiveness.Check(ctx, didit.PassiveLivenessCheckParams{
UserImage: didit.FileFromPath("user_image.jpg"),
FaceLivenessScoreDeclineThreshold: didit.Float(30.0),
RotateImage: didit.Bool(false),
SaveAPIRequest: didit.Bool(true),
VendorData: didit.String("user-123"),
Metadata: didit.Some(map[string]any{"flow": "withdrawal"}),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)import java.nio.file.Path;
import java.util.Map;
import me.didit.Didit;
import me.didit.types.PassiveLivenessCheckParams;
// Reads DIDIT_API_KEY.
Didit client = new Didit();
var result = client.passiveLiveness().check(PassiveLivenessCheckParams.builder()
.userImage(Path.of("user_image.jpg"))
.faceLivenessScoreDeclineThreshold(30.0)
.rotateImage(false)
.saveApiRequest(true)
.vendorData("user-123")
.metadata(Map.of("flow", "withdrawal"))
.build());
System.out.println(result);<?php
require 'vendor/autoload.php';
use Didit\DiditClient;
use Didit\File;
// Reads DIDIT_API_KEY.
$didit = new DiditClient();
$result = $didit->passiveLiveness->check([
'user_image' => File::fromPath('user_image.jpg'),
'face_liveness_score_decline_threshold' => 30.0,
'rotate_image' => false,
'save_api_request' => true,
'vendor_data' => 'user-123',
'metadata' => ['flow' => 'withdrawal'],
]);
print_r($result->toArray());require "didit"
# Reads DIDIT_API_KEY.
didit = Didit::Client.new
result = didit.passive_liveness.check(
user_image: Pathname("user_image.jpg"),
face_liveness_score_decline_threshold: 30.0,
rotate_image: false,
save_api_request: true,
vendor_data: "user-123",
metadata: { flow: "withdrawal" }
)
puts result.to_husing System;
using System.Collections.Generic;
using System.Text.Json;
using Didit;
// Reads DIDIT_API_KEY.
using var client = new DiditClient();
var result = await client.PassiveLiveness.CheckAsync(new PassiveLivenessCheckParams
{
UserImage = FileUpload.FromPath("user_image.jpg"),
FaceLivenessScoreDeclineThreshold = 30.0,
RotateImage = false,
SaveApiRequest = true,
VendorData = "user-123",
Metadata = new Dictionary<string, object> { ["flow"] = "withdrawal" },
});
Console.WriteLine(JsonSerializer.Serialize(result));Authorizations
Your application's API key, from Developers -> API keys in the Business Console. The primary key has full access. A named key can be scoped: none, read or write per resource, limited to some workflows or to approved sessions, to a list of IP addresses, and to an expiry date. 401 means the key is wrong, revoked or expired; 403 means no key was sent, the key has no access to this resource or action, or the request came from an address outside its IP list; 404 on a session route means the session is outside the key's workflows or statuses. A key without media access receives image, video and PDF URLs as null, and a key without sessions write receives session links and tokens as null. See https://docs.didit.me/console/api-keys.
Body
Front-facing face image (e.g. a selfie). Allowed extensions: tiff, jpg, jpeg, png, webp. Maximum upload size: 5 MB (larger files are rejected with 400). Images are automatically compressed to ~0.5 MB before processing, so very high resolutions do not improve accuracy. The image should contain a single subject — when several faces are present, the largest one is evaluated and a MULTIPLE_FACES_DETECTED warning is added.
Liveness score threshold (0–100). A computed score at or below this value emits a LOW_LIVENESS_SCORE warning and sets status to Declined. Default 30; raise it for a stricter anti-spoofing posture. Values outside 0–100 return 400.
0 <= x <= 10030
When true (default), persists the call as an API-type session, stores the face images, emits a status.updated webhook, and enrolls the detected face into your face search index. When false, the call is one-shot — nothing is stored and the face is not enrolled. Blocklist and duplicate screening run either way.
true
Response
Passive liveness completed. liveness.score is the model's 0–100 confidence that the image shows a live person; status is Approved unless an error-severity warning fired. A spoofed or blocklisted face still returns 200 — inspect liveness.status and liveness.warnings, not just the HTTP code. When save_api_request=true, request_id is the persisted session id.