Core Concepts

Understanding Xident's key concepts will help you build the best verification experience for your users.

Xident ID

A Xident ID is a unique identifier issued to users who complete verification. It enables the "Verify Once, Access Everywhere" model.

How It Works

  1. User visits Site A and completes full verification
  2. User receives a Xident ID (stored in their browser)
  3. User visits Site B (also using Xident)
  4. Site B detects the Xident ID
  5. Instant verification — no camera, no documents
  6. Site B pays the lower Xident ID rate for the returning user

User Control

Users can:

  • View their authorized OAuth apps in the Xident portal
  • Revoke OAuth consent for specific apps
  • Delete their Xident ID entirely

Verification Paths

Xident uses five verification paths, automatically selected based on user context:

User arrives at site
        |
        v
+------------------+       +------------------+
| Has Xident ID?   |--Yes->| Path D: Token    |  (instant, cheapest)
+--------+---------+       +------------------+
         | No
         v
+------------------+       +------------------+
| EU Wallet avail? |--Yes->| Path E: Wallet   |  (mso_mdoc attestation)
+--------+---------+       +------------------+
         | No
         v
+------------------+       +------------------+
| Restricted       |--Yes->| Path C: Document |  (always OCR)
| country?         |       +------------------+
+--------+---------+
         | No
         v
+------------------+       +------------------+
| ML age check     |--Pass>| Path A: ML Fast  |  (client-side, no images sent)
+--------+---------+       +------------------+
         | Fail
         v
+------------------+
| Path B: Document |  (OCR fallback -> Xident account funnel)
+------------------+

Path A: ML Fast

Client-side verification using machine learning. Face images never leave the browser.

  • Liveness Detection: Ensures a real person is present (not a photo/video)
  • Age Threshold Classification: Binary ML classifiers determine if the user is above the required age threshold (+12, +15, +18, +21, +25) via ONNX Runtime in WebAssembly
  • No face data is sent to the server — only a pass/fail result

Path B: Document Fallback

When ML classification fails (approximately 11% false rejection rate for +18), the user falls back to document verification:

  • Document OCR: ID document uploaded and processed server-side
  • Face Match: Document photo matched against liveness frame
  • This is the registration funnel — after the document pain, users are prompted to create a Xident account so they never need to do this again

Path C: Compliance

For restricted countries where ML false positive rates are insufficient for regulatory requirements:

  • Always requires document verification regardless of ML result
  • Ensures compliance with local age verification regulations

Path D: Xident Token

For returning users who already have a Xident ID with a verified age bracket:

  • Instant verification — no camera, no documents
  • Token lookup only, 60-80% cheaper than full verification
  • Same trust level as full verification

Path E: EU Wallet

For users with an EU Digital Identity Wallet that supports age attestation:

  • Uses the W3C Digital Credentials API and OpenID4VP protocol
  • Validates mso_mdoc age attestations against the EU Trusted List
  • Supports cross-device flow via QR code (user scans with wallet app on phone)
  • No face images, no documents — wallet provides a cryptographic age proof
  • See API Reference for the wallet endpoints

Privacy and Compliance

Privacy Architecture

  • ML Fast path: Face images never leave the browser
  • Document path: Document images deleted immediately after OCR
  • Server stores only 512-dimensional face embeddings (not reconstructable to faces)
  • No PII retained — only DOB-derived age bracket
  • Consumers (site owners) receive only pass/fail, never actual age

ARCOM Compliance (Unlinkability)

French Regulatory Compliance

Xident satisfies the French ARCOM unlinkability requirement: age verification does not link users to the platforms they visit. There is no account_connections table — Xident never records which sites a user has verified on. The portal's "Authorized Apps" page shows only OAuth consent grants (for "Login with Xident"), not verification history.

Verification Types

Full Verification

First-time verification with ML processing:

  • Liveness Detection: Ensures a real person is present (not a photo/video)
  • Age Threshold Classification: ML model determines if user is above required age threshold (+12, +15, +18, +21, +25)
  • Document Verification: OCR extraction from ID documents (fallback)

Token Verification

Returning user verification using Xident ID:

  • Instant, no UI required
  • 60-80% cheaper than full verification
  • Same trust level as full verification

EU Wallet Verification

Age attestation via EU Digital Identity Wallet:

  • Cryptographic age proof from government-issued wallet
  • No biometrics required
  • Cross-device flow supported (QR code scan)

Face 2FA

Per-site facial authentication:

  • Users enroll their face for a specific site
  • Subsequent logins verified via face match
  • Separate from Xident ID (site-specific)

Blacklist Check

Fraud detection via face similarity:

  • Check if a face matches any in your blacklist
  • Prevent banned users from creating new accounts
  • Privacy-preserving (no PII shared)

Tokens

A verification flow involves two different tokens — don't confuse them:

  • Init token (xit_…): created by POST /verify/v1/init and carried in the verification URL as ?t=. One-time use, 10-minute expiry. It bootstraps the widget (it never appears in your callback).
  • Result token (xtk_…): returned to your callback URL as ?token= after verification. You pass it to GET /verify/v1/result/{token} to read the outcome. Single-use; its expiry is returned as expires_at in the result response.

Result Token Lifecycle

Verification Complete
        |
        v
+-------------------+
| Result token      | --- xtk_… returned to your callback (see expires_at)
+--------+----------+
         |
         v
+-------------------+
| Backend Verifies  | --- Token consumed
+--------+----------+
         |
         v
+-------------------+
| Token Invalidated | --- Cannot be reused
+-------------------+

Token Properties

  • One-time use: tokens are invalidated after they are consumed
  • Short-lived: the init token expires in 10 minutes; the result token's expiry is returned as expires_at
  • Tamper-proof: opaque, randomly generated, server-validated

Verification Flow States

Status Description
success Verification completed successfully
cancelled User closed the verification window
expired Session timed out
failed Verification could not be completed

API Keys

Xident uses a Stripe-style dual key model. You have two types of API keys:

Secret Key (sk_*) — the one you need

  • Used in backend only (Node.js, Python, PHP, Go)
  • Never expose in client-side code
  • Authenticates the whole flow: POST /verify/v1/init and GET /verify/v1/result/:token
  • Starts with sk_live_ (production) or sk_test_ (sandbox)

Public Key (pk_*) — optional

  • Safe to expose in client-side code; only needed if you embed the widget from the browser yourself instead of redirecting from your backend
  • Can call POST /verify/v1/init and widget-facing endpoints (requirements, liveness, OCR) — but cannot read verification results
  • Starts with pk_live_ (production) or pk_test_ (sandbox)
  • The standard backend integration does not use it

Auth Header

Both key types use the same header:

X-API-Key: pk_live_... or sk_live_...

Environments

Production

  • API Key prefix: pk_live_, sk_live_
  • Real verifications, real billing
  • Requires HTTPS callback URLs

Sandbox (Testing)

  • API Key prefix: pk_test_, sk_test_
  • No real verification, simulated responses
  • Allows localhost callback URLs
  • No charges

Webhooks

Receive real-time notifications for verification events:

Event Description
verification.completed User completed verification
verification.failed Verification failed
token.verified Token was verified by your backend

Configure webhooks in your Dashboard.

Rate Limits

Endpoint Limit
Token verification 100 req/min
SDK initialization 1000 req/min
Wallet endpoints 60 req/min
Webhook delivery 3 retries over 24h

Next Steps