iLive Docs

Web integration

Integrate face liveness verification into a web app or backend using the iLive REST API.

Integrate face liveness verification into your web application or backend service using the iLive API. All inference runs on iLive's servers — your app just creates a session, sends the user to verify, and reads back the result.

Architecture overview

Your App                         iLive Platform
┌──────────────┐                ┌──────────────────────────┐
│              │  1. Create     │  REST API                 │
│  Backend     │────session────▶│  /api/v1/managed-session  │
│  (server)    │◀──session_url──│                          │
└──────┬───────┘                └────────────┬─────────────┘
       │                                     │
       │ 2. Redirect user                    │
       │    to session_url                   │
       ▼                                     ▼
┌──────────────┐                ┌──────────────────────────┐
│              │  3. Camera     │  Verification flow        │
│  User's      │────frames────▶│  Face guide + challenges  │
│  Browser     │◀──challenges───│  Verdict + ICAO photo     │
│              │◀──verdict──────│                          │
│              │  4. Redirect   │                          │
│              │────back to─────│  → redirect_url          │
│              │   your app     │                          │
└──────────────┘                └──────────────────────────┘

       │ 5. Fetch result

┌──────────────┐
│  Your App    │ GET /api/v1/session/{id}/result
│  (verify)    │ GET /api/v1/session/{id}/photo
└──────────────┘

Two integration modes

ModeBest forHow it works
Managed session (server-to-server)KYC flows, onboarding, identity verificationYour backend creates a session, gets a URL, redirects the user to it. User completes verification. iLive redirects back and calls your webhook.
Direct session (client-side)Standalone apps, demos, testingYour frontend creates the session directly via the API. No server-side integration needed.

Step 1: Create a session (your backend)

From your server, create a managed session:

curl -X POST https://api.iliveauth.com/api/v1/managed-session \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "redirect_url": "https://your-app.com/verification-complete",
    "webhook_url": "https://your-app.com/api/ilive-webhook",
    "reference_id": "user-12345"
  }'

Response:

{
  "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "session_url": "https://api.iliveauth.com/verify/a1b2c3d4-e5f6-7890-abcd-ef1234567890?token=abc123",
  "token": "abc123",
  "reference_id": "user-12345"
}

Step 2: Redirect the user to the verification URL

Send the user to session_url. They'll see the iLive verification UI.

// Full-page redirect
window.location.href = sessionUrl;
 
// Or open in a popup
window.open(sessionUrl, 'ilive-verify', 'width=500,height=700');

Step 3: User completes verification

The user sees:

  1. Welcome screen with instructions
  2. Camera access request
  3. Face guide overlay (position face in oval)
  4. Liveness challenges (blink, turn head, smile)
  5. "Analyzing..." spinner
  6. Result screen (pass / fail / retry)

After completion, iLive:

  • Redirects the user to your redirect_url with the session ID as a query parameter
  • Calls your webhook_url (if provided) with the result

Step 4: Fetch the result (your backend)

After the user is redirected back, fetch the verification result:

curl https://api.iliveauth.com/api/v1/session/SESSION_ID/result?token=TOKEN

Response:

{
  "status": "completed",
  "verdict": "pass",
  "confidence": 0.87,
  "photo_url": "/api/v1/session/SESSION_ID/photo?token=TOKEN",
  "photo_quality_score": 0.92
}

Step 5: Download the ICAO photo

If the verdict is pass, download the passport-quality photo:

curl -o photo.jpg "https://api.iliveauth.com/api/v1/session/SESSION_ID/photo?token=TOKEN"

Returns a 480×600 JPEG (ICAO-compliant passport photo dimensions).


Integration examples

Full backend examples for creating a session and retrieving the result:

import httpx
 
ILIVE_BASE_URL = "https://api.iliveauth.com"
ILIVE_API_KEY = "your-api-key"
 
async def start_verification(user_id: str, redirect_url: str):
    """Create an iLive managed session and return the verification URL."""
    async with httpx.AsyncClient() as client:
        response = await client.post(
            f"{ILIVE_BASE_URL}/api/v1/managed-session",
            headers={"Authorization": f"Bearer {ILIVE_API_KEY}"},
            json={
                "redirect_url": redirect_url,
                "webhook_url": "https://your-app.com/api/webhooks/ilive",
                "reference_id": user_id,
            },
        )
        response.raise_for_status()
        data = response.json()
 
        save_verification_session(user_id, data["session_id"], data["token"])
 
        return data["session_url"]
 
async def get_verification_result(session_id: str, token: str):
    """Fetch the verification result after the user completes the flow."""
    async with httpx.AsyncClient() as client:
        response = await client.get(
            f"{ILIVE_BASE_URL}/api/v1/session/{session_id}/result",
            params={"token": token},
        )
        response.raise_for_status()
        result = response.json()
 
        if result["verdict"] == "pass":
            photo_response = await client.get(
                f"{ILIVE_BASE_URL}{result['photo_url']}"
            )
            return result, photo_response.content
 
        return result, None

Webhook handler

When you provide a webhook_url, iLive POSTs the result when the session completes:

# FastAPI
@app.post("/api/webhooks/ilive")
async def ilive_webhook(request: Request):
    body = await request.json()
 
    session_id = body["session_id"]
    verdict = body["verdict"]        # "pass", "fail", or "retry"
    confidence = body["confidence"]  # 0.0 - 1.0
    reference_id = body["reference_id"]
 
    if verdict == "pass":
        await mark_user_verified(reference_id)
 
    return {"status": "ok"}

Quick start: direct session (client-side only)

For demos or standalone apps, skip the managed session flow:

<!DOCTYPE html>
<html>
<head>
  <title>Liveness Check</title>
</head>
<body>
  <button id="startBtn">Verify Identity</button>
  <div id="result"></div>
 
  <script>
    const API_BASE = 'https://api.iliveauth.com';
 
    document.getElementById('startBtn').addEventListener('click', async () => {
      // 1. Create a direct session
      const sessionRes = await fetch(`${API_BASE}/api/v1/session`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({}),
      });
      const session = await sessionRes.json();
 
      // 2. Open the verification UI
      const verifyUrl = `${API_BASE}/verify/${session.session_id}?token=${session.token}`;
      const popup = window.open(verifyUrl, 'ilive', 'width=500,height=700');
 
      // 3. Poll for result (or use webhook)
      const pollResult = async () => {
        const res = await fetch(
          `${API_BASE}/api/v1/session/${session.session_id}/result?token=${session.token}`
        );
        const data = await res.json();
 
        if (data.status === 'completed') {
          document.getElementById('result').innerText =
            `Verdict: ${data.verdict} (${Math.round(data.confidence * 100)}%)`;
          popup?.close();
        } else {
          setTimeout(pollResult, 2000);
        }
      };
 
      setTimeout(pollResult, 5000);
    });
  </script>
</body>
</html>

API reference

POST /api/v1/managed-session

Create a server-managed verification session.

Headers: Authorization: Bearer <API_KEY>

Request:

{
  "redirect_url": "https://your-app.com/done",
  "webhook_url": "https://your-app.com/webhook",
  "reference_id": "user-123"
}

Response:

{
  "session_id": "uuid",
  "session_url": "https://api.iliveauth.com/verify/uuid?token=abc",
  "token": "abc",
  "reference_id": "user-123"
}

POST /api/v1/session

Create a direct session (no API key required).

Request:

{
  "fingerprint_id": "optional-browser-fingerprint",
  "captcha_token": "optional-captcha-token"
}

Response:

{
  "session_id": "uuid",
  "token": "abc",
  "challenge_count": 3,
  "attempt_number": 1,
  "max_attempts": 5
}

GET /api/v1/session/{id}/result?token=TOKEN

Get the verification result.

Response:

{
  "status": "completed",
  "verdict": "pass",
  "confidence": 0.87,
  "photo_url": "/api/v1/session/{id}/photo?token=TOKEN",
  "photo_quality_score": 0.92
}
verdictMeaning
"pass"User is a live person. Confidence ≥ 70%.
"fail"Liveness check failed. Possible spoof or deepfake.
"retry"Inconclusive. Confidence between 45–70%. User should try again.

GET /api/v1/session/{id}/photo?token=TOKEN

Download the ICAO passport photo (480×600 JPEG). Only available when the verdict is pass.

Returns: image/jpeg, or 202 Accepted (still processing).


Passive mode

For a frictionless experience, create a session in passive mode — the user just faces the camera for three seconds with no challenges:

curl -X POST https://api.iliveauth.com/api/v1/managed-session \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "redirect_url": "https://yourapp.com/done",
    "mode": "passive"
  }'

The verification flow is otherwise identical — redirect the user to the session URL. They'll see a brief camera check with no challenges. The verdict webhook uses the same format.

Passive mode uses the same anti-spoof, deepfake, face-consistency, and motion analysis as active mode. The only difference is no interactive challenges, making it faster and lower-friction.

FeatureActive modePassive mode
User interaction3–6 challenges (blink, turn, etc.)Just hold still for 3 seconds
Verification layers5 (including challenges)4 (no challenges)
Best forHigh-security, regulatory complianceLow-friction onboarding, repeat verification
DefaultYesSet mode: "passive"

Face comparison

Compare two faces server-side:

curl -X POST https://api.iliveauth.com/api/v1/compare-faces \
  -F reference=@id_photo.jpg \
  -F probe=@selfie.jpg \
  -F threshold=0.45
 
# Response:
# { "similarity": 0.72, "is_match": true, "threshold": 0.45 }

Compare against a verified liveness session:

curl -X POST https://api.iliveauth.com/api/v1/compare-with-session \
  -F session_id=abc-123-def \
  -F probe=@new_selfie.jpg
 
# Response:
# { "similarity": 0.68, "is_match": true, "threshold": 0.45 }

Security considerations

Always use HTTPS in production. Set a managed-session API key to prevent unauthorized session creation, and ensure redirect_url and webhook_url are HTTPS URLs under your control.

  • Always use HTTPS in production.
  • Set an API key on your managed-session endpoint to prevent unauthorized session creation.
  • Validate redirect_url — the API rejects internal / private IPs to prevent SSRF.
  • Webhook URLs must be HTTPS — HTTP webhook URLs are rejected.
  • Session tokens are single-use — each session gets a unique token for result retrieval.
  • Enable rate limiting in production to prevent abuse.
  • Enable CAPTCHA for public-facing deployments.

WebSocket protocol

For real-time frame processing (used by the built-in frontend):

wss://api.iliveauth.com/ws/{session_id}?token=TOKEN

Client sends: JPEG frame bytes (binary message, max 1.5 MB)

Server sends: JSON messages:

{"type": "face_detected", "data": {"confidence": 0.95, "centered": true}}
{"type": "challenge", "data": {"type": "blink", "index": 0}}
{"type": "challenge_result", "data": {"passed": true}}
{"type": "verdict", "data": {"verdict": "pass", "confidence": 0.87}}

Troubleshooting

502 Bad Gateway: Backend hasn't started yet. Retry in a few seconds.

Camera not working: Browsers require HTTPS (or localhost) for camera access. Serving over plain HTTP will block the camera prompt.

"Session not found" on result fetch: The session may have expired. The default TTL for managed sessions is 30 minutes.

Low confidence scores: Check lighting conditions. Verification performs best with even, front-facing illumination.