DEV Community

Muhammad Yusuf Abubakar
Muhammad Yusuf Abubakar

Posted on

Add Face Liveness Detection to Any App in 10 Lines of Code (Free Tier Available)

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
// 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)
  }
});
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

Three modes

  • register — first-time enrollment. Returns action: 'registered'.
  • verify — 1:1 match, requires person_id. Returns match: true/false.
  • authenticate — 1:N search across your project, no person_id needed. Returns match: true with person_id and name if 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)