Skip to main content
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.

Age Verification

Confirm user age via document analysis, biometric estimation, or both.

Identity Verification

Full identity confirmation with document authentication, face matching, liveness detection, and fraud prevention.

Document Checks

45 countries with algorithmic validation. ICAO 9303 MRZ. PDF417 barcode decoding.

Fraud Prevention

7 cross-referencing layers, recapture detection, LLM-powered authenticity analysis, and IP geolocation checks.

What makes Tuteliq different

45-Country Document Validation

Algorithmic check digit validation for CPF, personnummer, Aadhaar, Codice Fiscale, CURP, SSN, and 39 more. Not just format checks — full mathematical verification.

7-Layer Cross-Referencing

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.

AI-Powered Authenticity

Vision model analyzes document layout, security features, fonts, and color consistency against known templates. Detects screen photos, printout recaptures, and digital manipulation.

Tier availability

FeatureMinimum TierCredits
Age Verification (liveness only)Pro ($99/mo)10 per verification
Age Verification (full)Pro ($99/mo)20 per verification
Identity VerificationBusiness ($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

MethodHow it worksBest for
DocumentExtracts DOB from government ID via OCR, MRZ parsing, and barcode decodingHigh-assurance age gates, parental consent
BiometricEstimates age from a selfie using vision AI (child/teen/adult classification)Frictionless age checks, onboarding flows
CombinedDocument + biometric with cross-reference — flags age inconsistencies > 10 yearsMaximum assurance — verifies the document belongs to the person

Request

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"

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

FieldTypeDescription
verifiedbooleanWhether age verification succeeded
estimated_ageintegerBest estimate of user’s age
age_rangestringTuteliq age bracket: under-10, 10-12, 13-15, or 14-17
is_minorbooleanWhether the user is under 18
confidencefloatConfidence score (0.0-1.0)
methodstringMethod used: document, biometric, or combined
document_typestringDetected document type
document_countrystringISO 3166-1 alpha-2 country code
biometric_ageintegerAge estimated from selfie (if provided)
document_ageintegerAge from document DOB (if provided)
document.ocr_confidenceintegerOCR confidence percentage (0-100)
document.mrz_validbooleanWhether MRZ check digits passed (if MRZ present)
document.document_number_validbooleanWhether document number passed algorithmic validation
document.expiredbooleanWhether the document has expired
credits_usedintegerCredits 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 TypeCoverage
PassportAll ICAO-compliant passports worldwide (MRZ validated)
National ID cardAll countries with MRZ-equipped cards + 45 countries with document number validation
Driver’s licenseAll countries via OCR + US/Canada via PDF417 barcode
Residence permitVia 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:
CheckWhat it does
Document number validationAlgorithmic check digit verification for 45 countries (CPF, personnummer, Aadhaar, CURP, SSN, etc.)
MRZ validationICAO 9303 check digits on document number, DOB, expiry, and composite — catches any MRZ tampering
Document authenticityAI vision analysis of layout, security features, fonts, colors, and photo integration
Recapture detectionDetects photos of screens (moire patterns), printouts, and photo-of-photo attacks
Face matching128-dimensional descriptor comparison between document photo and live selfie
Liveness detectionVisual analysis: landmark motion, texture analysis, depth cues, cross-frame consistency
MRZ/OCR cross-referencingCompares name, DOB, and document number between MRZ and printed text — flags mismatches as tampering
Front/back cross-referencingCompares extracted data between document front and back sides
Barcode cross-referencingCompares PDF417 barcode data against OCR and MRZ (US/CA licenses)
Document type consistencyValidates declared type matches MRZ-detected type (passport vs. ID card)
IP geolocation checkFlags geographic inconsistency between document country and request origin
OCR confidence gatingFlags low-confidence extractions as unreliable
Document expiryChecks expiry from labels, MRZ, and barcodes
Age consistencyCross-checks document age against selfie age estimate (flags > 10 year discrepancy)

Request

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"

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

FieldTypeDescription
verifiedbooleanAll checks passed
match_scorefloatFace match score (0.0-1.0)
liveness_passedbooleanLiveness check passed
document_authenticatedbooleanDocument passed authenticity checks
estimated_ageintegerAge from document DOB
is_minorbooleanUnder 18
confidencefloatOverall confidence (0.0-1.0)
document_typestringDetected document type
document_countrystringISO 3166-1 alpha-2 country code
flagsarrayWarning flags (e.g., low_ocr_confidence, geographic_inconsistency)
checksobjectIndividual check results — see below
failure_reasonsarrayHuman-readable reasons for failure (empty if verified)
credits_usedintegerCredits consumed

Checks object

FieldTypeDescription
mrz_validboolean | nullMRZ check digits valid (null if no MRZ)
mrz_fieldsobject | nullParsed MRZ fields with check-digit-validated data
document_number_validboolean | nullDocument number passed algorithmic validation
document_expiredbooleanDocument expiry check
face_matchbooleanFace on document matches selfie
livenessbooleanLiveness detection passed
recapturestring"none", "screen", "printout", or "photo_of_photo"
authenticityobjectAI-powered document authenticity analysis
barcodeobject | nullPDF417/barcode data (US/CA licenses)
cross_references_passedbooleanAll cross-referencing checks passed

Verification outcomes

StatusMeaningExamples
verifiedAll checks passedValid document, face match, liveness passed
failedHard failure — definitive fraud signalLiveness failed, face mismatch, recapture detected
needs_reviewSoft failure — human review recommendedLow 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
});
// 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:
CodeHTTPDescription
VRF_9001400Document image is required
VRF_9002400Document image is unreadable or too low quality
VRF_9003400Unsupported document type
VRF_9004400Selfie image is required for liveness check
VRF_9005400Face not detected in selfie
VRF_9006400Liveness check failed
VRF_9007500Verification service error (safe to retry)
VRF_9008403Age verification not available on your plan (requires Pro)
VRF_9009403Identity verification not available on your plan (requires Business)
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;
    }
  }
}

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 page for data handling details.

Next steps

Document Checks

Deep dive into 45-country document validation, MRZ parsing, and barcode reading.

Liveness Detection

How visual liveness analysis prevents spoofing attacks.

Fraud Prevention

Multi-layer cross-referencing, recapture detection, and authenticity analysis.