Skip to content

Latest commit

 

History

History
467 lines (393 loc) · 17.3 KB

File metadata and controls

467 lines (393 loc) · 17.3 KB
title Age & Identity Verification
sidebarTitle Overview
icon id-card
description Production-grade age and identity verification with document intelligence, biometric matching, liveness detection, and multi-layer fraud prevention — covering 45 countries
keywords
age verification
identity verification
KYC
age assurance
liveness detection
document verification
KOSA
COPPA
MRZ
PDF417
biometric
face matching

Tuteliq Verification is a production-grade identity and age verification pipeline that combines document intelligence, biometric matching, liveness detection, and multi-layer fraud prevention in a single API call.

Most verification providers give you OCR and a face match. Tuteliq cross-references every data source on the document against every other — MRZ check digits, barcode data, OCR text, front vs. back, document vs. selfie — and flags any inconsistency as potential tampering. This catches forgeries that pass single-layer checks.

Confirm user age via document analysis, biometric estimation, or both. Full identity confirmation with document authentication, face matching, liveness detection, and fraud prevention. 45 countries with algorithmic validation. ICAO 9303 MRZ. PDF417 barcode decoding. 7 cross-referencing layers, recapture detection, LLM-powered authenticity analysis, and IP geolocation checks.

What makes Tuteliq different

Algorithmic check digit validation for CPF, personnummer, Aadhaar, Codice Fiscale, CURP, SSN, and 39 more. Not just format checks — full mathematical verification. MRZ vs. OCR. Barcode vs. OCR. Front vs. back. Document vs. selfie. Declared type vs. detected type. IP vs. document country. OCR confidence gating. Every inconsistency is flagged. Vision model analyzes document layout, security features, fonts, and color consistency against known templates. Detects screen photos, printout recaptures, and digital manipulation.

Tier availability

Feature Minimum Tier Credits
Age Verification (liveness only) Pro ($99/mo) 10 per verification
Age Verification (full) Pro ($99/mo) 20 per verification
Identity Verification Business ($349/mo) 25 per verification

Age Verification

POST /v1/verification/age

Verify a user's age through document analysis, biometric age estimation, or both. Returns a verified age range, confidence score, and detailed document intelligence.

Verification methods

Method How it works Best for
Document Extracts DOB from government ID via OCR, MRZ parsing, and barcode decoding High-assurance age gates, parental consent
Biometric Estimates age from a selfie using vision AI (child/teen/adult classification) Frictionless age checks, onboarding flows
Combined Document + biometric with cross-reference — flags age inconsistencies > 10 years Maximum assurance — verifies the document belongs to the person

Request

```typescript Node.js const result = await tuteliq.verifyAge({ document: fs.createReadStream('id-front.jpg'), // Government-issued ID documentBack: fs.createReadStream('id-back.jpg'), // Optional — enables barcode reading + back cross-ref selfie: fs.createReadStream('selfie.jpg'), // Optional — for biometric estimation method: 'combined', // 'document' | 'biometric' | 'combined' });

console.log(result.verified); // true console.log(result.estimated_age); // 15 console.log(result.age_range); // "13-15" console.log(result.is_minor); // true console.log(result.confidence); // 0.97 console.log(result.document_type); // "passport"


```python Python
result = client.verify_age(
    document=open("id-front.jpg", "rb"),
    document_back=open("id-back.jpg", "rb"),  # Optional
    selfie=open("selfie.jpg", "rb"),
    method="combined",
)

print(result.verified)        # True
print(result.estimated_age)   # 15
print(result.age_range)       # "13-15"
print(result.is_minor)        # True
curl -X POST https://api.tuteliq.ai/v1/verification/age \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "document=@id-front.jpg" \
  -F "document_back=@id-back.jpg" \
  -F "selfie=@selfie.jpg" \
  -F "method=combined"

Response

{
  "verified": true,
  "estimated_age": 15,
  "age_range": "13-15",
  "is_minor": true,
  "confidence": 0.97,
  "method": "combined",
  "document_type": "passport",
  "document_country": "GB",
  "biometric_age": 15,
  "document_age": 15,
  "document": {
    "ocr_confidence": 94,
    "mrz_valid": true,
    "document_number_valid": true,
    "expired": false
  },
  "credits_used": 20
}

Response fields

Field Type Description
verified boolean Whether age verification succeeded
estimated_age integer Best estimate of user's age
age_range string Tuteliq age bracket: under-10, 10-12, 13-15, or 14-17
is_minor boolean Whether the user is under 18
confidence float Confidence score (0.0-1.0)
method string Method used: document, biometric, or combined
document_type string Detected document type
document_country string ISO 3166-1 alpha-2 country code
biometric_age integer Age estimated from selfie (if provided)
document_age integer Age from document DOB (if provided)
document.ocr_confidence integer OCR confidence percentage (0-100)
document.mrz_valid boolean Whether MRZ check digits passed (if MRZ present)
document.document_number_valid boolean Whether document number passed algorithmic validation
document.expired boolean Whether the document has expired
credits_used integer Credits consumed

Age extraction sources

DOB is extracted from multiple sources and cross-referenced. Priority order:

  1. MRZ (Machine Readable Zone) — Most reliable. ICAO 9303 check digit validated.
  2. PDF417 barcode — US/Canadian driver's licenses. AAMVA-encoded structured data.
  3. OCR labels — Text patterns like "Date of Birth:", "DOB:", date formats.
  4. Selfie estimation — Vision AI age bracket classification (fallback).

When multiple sources disagree, the verification flags the inconsistency.

Supported documents

Document Type Coverage
Passport All ICAO-compliant passports worldwide (MRZ validated)
National ID card All countries with MRZ-equipped cards + 45 countries with document number validation
Driver's license All countries via OCR + US/Canada via PDF417 barcode
Residence permit Via OCR text extraction

Documents must be a clear, well-lit photo in JPEG or PNG format. Maximum file size: 10MB.


Identity Verification

POST /v1/verification/identity

Full identity verification combining document authentication, face matching, liveness detection, and multi-layer fraud prevention.

What it checks

Every identity verification runs all of these checks automatically:

Check What it does
Document number validation Algorithmic check digit verification for 45 countries (CPF, personnummer, Aadhaar, CURP, SSN, etc.)
MRZ validation ICAO 9303 check digits on document number, DOB, expiry, and composite — catches any MRZ tampering
Document authenticity AI vision analysis of layout, security features, fonts, colors, and photo integration
Recapture detection Detects photos of screens (moire patterns), printouts, and photo-of-photo attacks
Face matching 128-dimensional descriptor comparison between document photo and live selfie
Liveness detection Visual analysis: landmark motion, texture analysis, depth cues, cross-frame consistency
MRZ/OCR cross-referencing Compares name, DOB, and document number between MRZ and printed text — flags mismatches as tampering
Front/back cross-referencing Compares extracted data between document front and back sides
Barcode cross-referencing Compares PDF417 barcode data against OCR and MRZ (US/CA licenses)
Document type consistency Validates declared type matches MRZ-detected type (passport vs. ID card)
IP geolocation check Flags geographic inconsistency between document country and request origin
OCR confidence gating Flags low-confidence extractions as unreliable
Document expiry Checks expiry from labels, MRZ, and barcodes
Age consistency Cross-checks document age against selfie age estimate (flags > 10 year discrepancy)

Request

```typescript Node.js const result = await tuteliq.verifyIdentity({ document: fs.createReadStream('id-front.jpg'), documentBack: fs.createReadStream('id-back.jpg'), // Optional — enables barcode + back cross-ref selfie: fs.createReadStream('selfie.jpg'), documentType: 'passport', // Optional — enables type consistency check });

console.log(result.verified); // true console.log(result.match_score); // 0.98 console.log(result.liveness_passed); // true console.log(result.document_authenticated); // true console.log(result.checks.mrz_valid); // true console.log(result.checks.recapture); // "none"


```python Python
result = client.verify_identity(
    document=open("id-front.jpg", "rb"),
    document_back=open("id-back.jpg", "rb"),
    selfie=open("selfie.jpg", "rb"),
    document_type="passport",
)

print(result.verified)                # True
print(result.match_score)             # 0.98
print(result.checks.mrz_valid)        # True
print(result.checks.recapture)        # "none"
curl -X POST https://api.tuteliq.ai/v1/verification/identity \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "document=@id-front.jpg" \
  -F "document_back=@id-back.jpg" \
  -F "selfie=@selfie.jpg" \
  -F "document_type=passport"

Response

{
  "verified": true,
  "match_score": 0.98,
  "liveness_passed": true,
  "document_authenticated": true,
  "estimated_age": 34,
  "is_minor": false,
  "confidence": 0.99,
  "document_type": "passport",
  "document_country": "GB",
  "flags": [],
  "checks": {
    "mrz_valid": true,
    "mrz_fields": {
      "document_number": "L898902C3",
      "nationality": "GBR",
      "date_of_birth": "1990-06-15",
      "expiry_date": "2030-01-01",
      "surname": "SMITH",
      "given_names": "JOHN WILLIAM"
    },
    "document_number_valid": true,
    "document_expired": false,
    "face_match": true,
    "liveness": true,
    "recapture": "none",
    "authenticity": {
      "is_authentic": true,
      "confidence": 0.94,
      "security_features": ["hologram", "microprint", "guilloche_pattern"],
      "anomalies": []
    },
    "barcode": {
      "format": "PDF417",
      "has_aamva": true,
      "first_name": "JOHN",
      "last_name": "SMITH",
      "date_of_birth": "1990-06-15",
      "state": "CA"
    },
    "cross_references_passed": true
  },
  "failure_reasons": [],
  "credits_used": 25
}

Response fields

Field Type Description
verified boolean All checks passed
match_score float Face match score (0.0-1.0)
liveness_passed boolean Liveness check passed
document_authenticated boolean Document passed authenticity checks
estimated_age integer Age from document DOB
is_minor boolean Under 18
confidence float Overall confidence (0.0-1.0)
document_type string Detected document type
document_country string ISO 3166-1 alpha-2 country code
flags array Warning flags (e.g., low_ocr_confidence, geographic_inconsistency)
checks object Individual check results — see below
failure_reasons array Human-readable reasons for failure (empty if verified)
credits_used integer Credits consumed

Checks object

Field Type Description
mrz_valid boolean | null MRZ check digits valid (null if no MRZ)
mrz_fields object | null Parsed MRZ fields with check-digit-validated data
document_number_valid boolean | null Document number passed algorithmic validation
document_expired boolean Document expiry check
face_match boolean Face on document matches selfie
liveness boolean Liveness detection passed
recapture string "none", "screen", "printout", or "photo_of_photo"
authenticity object AI-powered document authenticity analysis
barcode object | null PDF417/barcode data (US/CA licenses)
cross_references_passed boolean All cross-referencing checks passed

Verification outcomes

Status Meaning Examples
verified All checks passed Valid document, face match, liveness passed
failed Hard failure — definitive fraud signal Liveness failed, face mismatch, recapture detected
needs_review Soft failure — human review recommended Low OCR confidence, document expired, name mismatch between MRZ and printed text

Integration patterns

Age gate on sign-up

// 1. Verify age during sign-up
const verification = await tuteliq.verifyAge({
  selfie: selfieStream,
  method: 'biometric',
});

// 2. Store the verified age group
const ageGroup = verification.age_range;  // "13-15"

// 3. Use verified age group in all safety calls
const safety = await tuteliq.detectUnsafe({
  text: messageContent,
  ageGroup: ageGroup,  // Properly calibrated risk scoring
});

Parental consent flow (COPPA)

// 1. Verify child's age
const childAge = await tuteliq.verifyAge({
  selfie: childSelfieStream,
  method: 'biometric',
});

if (childAge.estimated_age < 13) {
  // 2. Verify parent's identity
  const parent = await tuteliq.verifyIdentity({
    document: parentIdStream,
    selfie: parentSelfieStream,
  });

  if (parent.verified && !parent.is_minor) {
    await grantParentalConsent(childUserId, parent);
  }
}

Moderator/admin verification

const identity = await tuteliq.verifyIdentity({
  document: documentStream,
  selfie: selfieStream,
});

if (identity.verified && !identity.is_minor) {
  await grantModeratorRole(userId);
}

Error handling

Verification errors use the VRF_9xxx code range:

Code HTTP Description
VRF_9001 400 Document image is required
VRF_9002 400 Document image is unreadable or too low quality
VRF_9003 400 Unsupported document type
VRF_9004 400 Selfie image is required for liveness check
VRF_9005 400 Face not detected in selfie
VRF_9006 400 Liveness check failed
VRF_9007 500 Verification service error (safe to retry)
VRF_9008 403 Age verification not available on your plan (requires Pro)
VRF_9009 403 Identity verification not available on your plan (requires Business)
```typescript Node.js try { const result = await tuteliq.verifyIdentity({ document: documentStream, selfie: selfieStream, }); } catch (error) { if (error instanceof TuteliqError) { switch (error.code) { case 'VRF_9002': // Ask user to retake photo with better lighting break; case 'VRF_9006': // Liveness failed — possible spoofing attempt break; } } } ```
from tuteliq import TuteliqError

try:
    result = client.verify_identity(
        document=open("id.jpg", "rb"),
        selfie=open("selfie.jpg", "rb"),
    )
except TuteliqError as e:
    if e.code == "VRF_9002":
        pass  # Ask user to retake photo
    elif e.code == "VRF_9006":
        pass  # Liveness failed

Data handling

Verification involves sensitive personal data. Tuteliq processes documents and selfies in real time and does **not** store images or extracted PII after the verification is complete. Only the verification result (age range, pass/fail) is retained. See the [GDPR](/gdpr) page for data handling details.

Next steps

Deep dive into 45-country document validation, MRZ parsing, and barcode reading. How visual liveness analysis prevents spoofing attacks. Multi-layer cross-referencing, recapture detection, and authenticity analysis.