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:
dependencies:
verilock_identity: ^1.0.0
Then run:
Two Modes
The SDK provides two distinct clients for different use cases:
| Client | Auth Method | Use Case |
|---|
VerilockIdentityClient | Session token | Hosted verification flow with camera capture UI |
VerilockApiClient | API key | Full 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 Code | Description |
|---|
network_error | No internet connection or DNS failure |
session_expired | Session token has expired (HTTP 410) |
session_completed | Session already has a final decision (HTTP 409) |
api_error | General API error (check statusCode for details) |
parse_error | Response body could not be parsed as JSON |
polling_timeout | pollForResult exceeded the timeout duration |
verification_failed | Verification completed with a decline decision |
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) { /* ... */ },
)
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
},
)
Camera viewfinder with a face oval overlay for selfie capture:
SelfieCaptureWidget(
onCaptured: (File photo) {
// Upload the selfie
},
)
Animated progress indicator shown while verification is in progress:
ProcessingWidget(
status: 'processing', // Updates as polling progresses
)