Skip to main content

Requirements

  • Flutter 3.10+
  • Dart 3.0+
  • iOS 13+ / Android API 21+
  • Camera permission (for hosted verification UI)

Installation

Add the SDK to your pubspec.yaml:
pubspec.yaml
dependencies:
  verilock_identity: ^1.0.0
Then run:
flutter pub get

Two Modes

The SDK provides two distinct clients for different use cases:
ClientAuth MethodUse Case
VerilockIdentityClientSession tokenHosted verification flow with camera capture UI
VerilockApiClientAPI keyFull server-side API access (sessions, AML, transactions, wallets)
Never embed your API key in client-side code. Use VerilockIdentityClient with a session token in your mobile app. Use VerilockApiClient only from a backend server or secure environment.

Hosted Verification UI

The hosted flow uses a session token to guide users through document capture, selfie, and submission — all with built-in camera widgets.

Create a session on your backend

First, create a session from your server and pass the token to your Flutter app:
// On your backend -- use VerilockApiClient
final verilock = VerilockApiClient(apiKey: 'qi_live_...');

final session = await verilock.createSession(
  applicantEmail: 'john@example.com',
  redirectUrl: 'https://example.com/callback',
);

// Send session['session_token'] to your Flutter app

Use the pre-built verification screen

The fastest integration — a single widget that handles the entire flow:
import 'package:verilock_identity/verilock_identity.dart';

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (_) => VerilockVerificationScreen(
      sessionToken: 'tok_abc123',
      onComplete: (result) {
        print('Decision: ${result.decision}');
        Navigator.pop(context);
      },
      onError: (error) {
        print('Error: ${error.message}');
      },
    ),
  ),
);

Programmatic hosted flow

For full control, use VerilockIdentityClient directly:
import 'dart:io';
import 'package:verilock_identity/verilock_identity.dart';

final client = VerilockIdentityClient(sessionToken: 'tok_abc123');

// 1. Upload document front
await client.uploadDocument(
  File('path/to/id_front.jpg'),
  side: 'front',
  documentType: 'passport',
);

// 2. Upload document back
await client.uploadDocument(
  File('path/to/id_back.jpg'),
  side: 'back',
);

// 3. Upload selfie
await client.uploadSelfie(File('path/to/selfie.jpg'));

// 4. Submit for verification
await client.submit();

// 5. Poll for result
final result = await client.pollForResult(
  interval: Duration(seconds: 2),
  timeout: Duration(seconds: 120),
  onStatus: (status) => print('Status: $status'),
);

print('Decision: ${result.decision}');
print('Risk score: ${result.riskScore}');

// Clean up
client.dispose();
pollForResult automatically polls getStatus() every 2 seconds until a decision is reached or the timeout expires. You can also call getStatus() manually for custom polling logic.

Server API Client

VerilockApiClient gives you full access to the Verilock API using API key authentication. Use this from your backend or secure server environment.
import 'package:verilock_identity/verilock_identity.dart';

final verilock = VerilockApiClient(apiKey: 'qi_live_...');

Sessions

// Create a session
final session = await verilock.createSession(
  applicantEmail: 'john@example.com',
  externalId: 'user_12345',
  redirectUrl: 'https://example.com/callback',
  metadata: {'plan': 'premium'},
);

// List sessions with filters
final sessions = await verilock.listSessions(
  status: 'completed',
  decision: 'approved',
  perPage: 20,
  page: 1,
);

// Retrieve a single session
final detail = await verilock.getSession('ses_abc123');

AML Screening

// Screen a person against sanctions, PEP, and watchlists
final aml = await verilock.screenAml(
  name: 'John Doe',
  dateOfBirth: '1990-01-15',
  nationality: 'US',
);

// Retrieve result
final result = await verilock.getAmlScreening(aml['id']);

// Submit a decision
await verilock.decideAml(aml['id'], decision: 'clear', notes: 'No matches.');

Transaction Screening

// Screen a single transaction
final tx = await verilock.screenTransaction(
  transactionRef: 'TX-001',
  senderName: 'Alice Smith',
  senderCountry: 'US',
  receiverName: 'Bob Johnson',
  receiverCountry: 'NG',
  amount: 5000,
  currency: 'USD',
  transactionType: 'wire_transfer',
);

// Screen a batch of transactions
final batch = await verilock.screenTransactionBatch([
  {'transaction_ref': 'TX-002', 'sender_name': 'Alice', 'receiver_name': 'Charlie', 'amount': 200, 'currency': 'EUR'},
  {'transaction_ref': 'TX-003', 'sender_name': 'Alice', 'receiver_name': 'Diana', 'amount': 15000, 'currency': 'USD'},
]);

// List transactions with risk filter
final txList = await verilock.listTransactions(riskLevel: 'high', perPage: 50);

Wallet Screening

// Screen a crypto wallet address
final wallet = await verilock.screenWallet(
  address: '0x742d35Cc6634C0532925a3b844Bc9e7595f2bD08',
  network: 'ethereum',
);

// Retrieve result
final walletResult = await verilock.getWalletScreening(wallet['id']);

Credentials

// Create a reusable KYC credential
final credential = await verilock.createCredential(
  sessionId: 'ses_abc123',
  sharedFields: ['full_name', 'date_of_birth', 'document_number'],
  expiresInDays: 365,
);

// Verify a credential token
final verified = await verilock.verifyCredential('cred_token_...');

// Revoke a credential
await verilock.revokeCredential(credential['id']);

Error Handling

All SDK methods throw VerilockIdentityError on failure:
try {
  await client.uploadDocument(File('id.jpg'), side: 'front');
} on VerilockIdentityError catch (e) {
  print('Code: ${e.code}');         // e.g. 'session_expired'
  print('Message: ${e.message}');   // Human-readable description
  print('Status: ${e.statusCode}'); // HTTP status (if applicable)
}
Error CodeDescription
network_errorNo internet connection or DNS failure
session_expiredSession token has expired (HTTP 410)
session_completedSession already has a final decision (HTTP 409)
api_errorGeneral API error (check statusCode for details)
parse_errorResponse body could not be parsed as JSON
polling_timeoutpollForResult exceeded the timeout duration
verification_failedVerification completed with a decline decision

UI Widgets

The SDK includes pre-built widgets you can compose into your own screens.

VerilockVerificationScreen

Full-screen verification flow with all steps (document capture, selfie, processing, result):
VerilockVerificationScreen(
  sessionToken: 'tok_abc123',
  onComplete: (VerificationResult result) { /* ... */ },
  onError: (VerilockIdentityError error) { /* ... */ },
)

DocumentCaptureWidget

Camera viewfinder with a document frame overlay. Captures front or back of an ID:
DocumentCaptureWidget(
  side: 'front', // 'front' or 'back'
  onCaptured: (File photo) {
    // Upload the captured photo
  },
)

SelfieCaptureWidget

Camera viewfinder with a face oval overlay for selfie capture:
SelfieCaptureWidget(
  onCaptured: (File photo) {
    // Upload the selfie
  },
)

ProcessingWidget

Animated progress indicator shown while verification is in progress:
ProcessingWidget(
  status: 'processing', // Updates as polling progresses
)