How the SDK works
Enrol a face once, verify it on the device with no network. What happens on the phone, what's stored, and how the sandbox differs from production.
The FacePing SDK does two things: enrol a face (turn one photo into a face template) and verify a face (check that the person in front of the camera matches a template). Verification always runs on the device, with no network.
The three calls#
| Call | What it does |
|---|---|
EnrolAsync(id, photo) |
Finds the face, checks it's a real person and good enough to match later, and stores a face template under your id. The photo itself is discarded. |
VerifyLiveAsync(id, camera) |
Watches the camera, matches the face to id, and asks the person to turn their head to prove they're really there. Returns Match or a reason it didn't. |
VerifyAsync(id, photo) |
The same match from a single photo, with a passive liveness check only. Use it for tests and back-office tools, not at an unattended entrance or kiosk. |
The id is yours: a ticket number, member number or employee ID. FacePing never needs a name.
What a result tells you#
var result = await faceping.VerifyLiveAsync("TKT-104823", Camera);
switch (result.Outcome)
{
case VerifyOutcome.Match: // let them in
case VerifyOutcome.NoMatch: // a different person: send to staff
case VerifyOutcome.NotEnrolled: // no face stored for this id: use your normal entry
case VerifyOutcome.LivenessFailed: // a photo or screen held up: send to staff
case VerifyOutcome.ChallengeFailed:// turned the wrong way or not at all: try again or staff
case VerifyOutcome.NoFace: // nobody in view
case VerifyOutcome.Expired: // the stored faces have passed their deletion date
break;
}
Every result also has Similarity (0 to 1), LivenessScore (0 to 1), Elapsed and IsSandbox.
Liveness#
Every frame gets a passive check that it's a real face, not a photo or a screen. VerifyLiveAsync adds an active check: after the first match, the person turns their head left or right (chosen at random), then looks back for a second match. Any failed liveness check ends the attempt; there's no retrying until a lucky frame passes. The camera view shows the prompts for you.
Where faces are stored#
On the device, face templates are kept in an encrypted store: AES-256-GCM, with the key in the platform's secure storage (Keychain on iOS, Keystore on Android). Templates are numbers, not photos; they can't be turned back into a picture of the person.
| Sandbox | Production | |
|---|---|---|
| Faces come from | EnrolAsync on the device |
Your FacePing group or event, synced to the device |
| Kept on the device | Up to 25, each for 24 hours | Until your retention date or the device is revoked |
| Network needed | Once, to activate the sandbox key | To sync new faces; verification is offline |
Sandbox and production#
The sandbox is for building and testing. Use a fp_test_ key in UseFacePing. It needs a connection once, the first time the app runs, to activate the key; after that it works offline for 30 days. Results have IsSandbox = true.
Production faces are enrolled with consent through your server, the FacePing widget or the dashboard, and each device syncs an encrypted copy of the faces it needs. Your verify code doesn't change. See Going to production.
Limits#
- One face per photo when enrolling; the largest face is used when verifying.
- Faces should be at least 60 pixels across. The camera view guides people closer if they're too far away.
- Release builds check a face in under 0.3 seconds on a mid-range phone. Debug builds are several times slower.