Most biometric verification tools are either expensive, require a hardware SDK, or lock you into a proprietary platform. FaceID API is a free-tier REST API that adds face liveness detection to any web or mobile app. Here's exactly how it works.
How the session model works
Your API key never appears in frontend code or in a URL.
Your backend
↓ POST /widget-session (X-API-Key: your_secret_key)
FaceID Worker
↓ Returns { session_id, widget_url }
Your frontend
↓ Opens widget_url in an iframe (no key in URL)
User completes liveness
↓ postMessage({ type: 'FACEID_RESULT', result: {...} })
Your frontend
↓ Receives the result — no raw biometric data
Node.js backend
// Step 1: get a session (server-side only — never in the browser)
const session = await fetch('https://face-worker.faceidentity.workers.dev/widget-session', {
method: 'POST',
headers: {
'X-API-Key': process.env.FACEID_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
person_id: user.id, // your user's unique ID
name: user.name, // shown on the success screen
mode: 'authenticate', // 'register' | 'verify' | 'authenticate'
}),
});
const { widget_url } = await session.json();
// send widget_url to your frontend
// Step 2: frontend — open the widget
const iframe = document.createElement('iframe');
iframe.src = widget_url; // session token in the URL, not the API key
iframe.allow = 'camera';
iframe.style.cssText = 'position:fixed;inset:0;width:100%;height:100%;border:none;z-index:9999';
document.body.appendChild(iframe);
// Step 3: receive the result
window.addEventListener('message', (e) => {
if (e.data?.type === 'FACEID_RESULT') {
document.body.removeChild(iframe);
const { action, match, person_id, name } = e.data.result;
// action: 'registered' | 'verified' | 'authenticated'
// match: true | false (for verify/authenticate)
}
});
Python backend
import requests, os
def start_verification(user_id, user_name, mode='authenticate'):
response = requests.post(
'https://face-worker.faceidentity.workers.dev/widget-session',
headers={
'X-API-Key': os.environ['FACEID_API_KEY'],
'Content-Type': 'application/json',
},
json={'person_id': user_id, 'name': user_name, 'mode': mode}
)
return response.json()['widget_url']
Three modes
-
register— first-time enrollment. Returnsaction: 'registered'. -
verify— 1:1 match, requiresperson_id. Returnsmatch: true/false. -
authenticate— 1:N search across your project, noperson_idneeded. Returnsmatch: truewithperson_idandnameif found.
What happens during liveness
The widget runs a 4-direction head challenge (up, down, left, right) plus a mouth-open check. MediaPipe FaceMesh tracks 468 facial landmarks in real time in the browser; face-api.js generates the 128-float descriptor only after every challenge passes. That descriptor — a mathematical representation, not a photo — is the only thing that ever reaches the server.
Get started
faceidentity.site — 200 enrollments/month free, no credit card.
Top comments (0)