Global Coverage

Support for 190+ countries and 6,000+ document types.

Fast Results

Most verifications complete in under 60 seconds.

Fraud Prevention

AI-powered document fraud and liveness detection.

Verification Methods

Document Verification

Verify government-issued IDs like passports, driver's licenses, and national ID cards.

Passports (190+ countries)Driver's licensesNational ID cardsResidence permits

Selfie Matching

Compare a live selfie against the photo on the identity document.

Face matchingLiveness detectionSpoof preventionGlasses/mask detection

Biometric Verification

Use device biometrics to confirm the user is physically present.

Face ID / Touch IDAndroid biometricsMulti-factor confirmation

Implementation

1. Create a Verification Session

Start by creating a verification session and redirecting the user to complete verification:

// Create an identity verification session
const session = await affirmid.identity.create({
  userId: 'user_123',

  // What to verify
  checks: ['document', 'selfie', 'liveness'],

  // Accepted document types (optional)
  acceptedDocuments: ['passport', 'drivers_license'],

  // Redirect URL after completion
  redirectUrl: 'https://yourapp.com/verification-complete',

  // Optional metadata
  metadata: {
    reason: 'account_recovery',
    transactionId: 'txn_abc123'
  }
});

// Redirect user to verification flow
res.redirect(session.url);
// Or return URL for client-side redirect
res.json({ verificationUrl: session.url });

2. Handle the Verification Result

When the user completes verification, you'll receive a webhook or can poll for results:

// Webhook handler for verification results
app.post('/webhooks/identity', async (req, res) => {
  const { sessionId, status, result } = req.body;

  if (status === 'completed') {
    console.log(result);
    // {
    //   verified: true,
    //   document: {
    //     type: 'passport',
    //     country: 'US',
    //     firstName: 'John',
    //     lastName: 'Doe',
    //     dateOfBirth: '1990-01-15',
    //     expirationDate: '2030-05-20',
    //     documentNumber: 'XXX...XXX' // Partially masked
    //   },
    //   selfie: {
    //     matched: true,
    //     confidence: 0.98,
    //     livenessConfidence: 0.99
    //   },
    //   riskSignals: []
    // }

    // Update user verification status
    await updateUserVerification(result.userId, result);
  }

  res.sendStatus(200);
});

3. Polling for Results

Alternatively, poll for verification results:

// Poll for verification result
const result = await affirmid.identity.waitForResult(session.id, {
  timeout: 300000  // 5 minute timeout
});

switch (result.status) {
  case 'verified':
    // User successfully verified
    break;
  case 'failed':
    // Verification failed - check result.failureReasons
    break;
  case 'expired':
    // User didn't complete in time
    break;
  case 'abandoned':
    // User closed the verification flow
    break;
}

Common Use Cases

Use CaseDescription
Account RecoveryVerify identity before resetting credentials or recovering accounts
High-Value TransactionsConfirm identity for large transfers or sensitive operations
Regulatory ComplianceMeet KYC/AML requirements for financial services
Age VerificationConfirm users meet minimum age requirements
New Account OnboardingVerify identity during account creation

Data Handling & Privacy

What We Store

  • Verification result (pass/fail)
  • Document type and country
  • Verification timestamp
  • Risk signals detected

What We Don't Store

  • Document images (deleted after processing)
  • Selfie images (deleted after matching)
  • Full document numbers
  • Biometric templates

GDPR & Privacy Compliant

AffirmID is fully GDPR compliant. Users can request deletion of their verification data at any time. Document images are processed in real-time and deleted immediately after verification.

Handling Verification Failures

const result = await affirmid.identity.get(sessionId);

if (!result.verified) {
  // Check failure reasons
  result.failureReasons.forEach(reason => {
    switch (reason.code) {
      case 'document_expired':
        // ID document has expired
        break;
      case 'document_unreadable':
        // Poor image quality
        break;
      case 'selfie_mismatch':
        // Face doesn't match document
        break;
      case 'liveness_failed':
        // Potential spoofing detected
        break;
      case 'document_fraud':
        // Suspected fraudulent document
        break;
    }
  });

  // Offer to retry or contact support
  return res.json({
    verified: false,
    message: 'Verification unsuccessful',
    canRetry: result.retriesRemaining > 0
  });
}

Continue Learning