Initializing the SDK
Before using any of the modules, you must initialize the SDK. This method needs to be called only once during the SDK lifecycle.
For standard Flutter integrations, you can initialize the SDK with initAmani.
bool initSuccess = await AmaniSDK().initAmani(
server: "https://server.example",
customerToken: "customer_token",
customerIdCardNumber: "customer_id_card_number",
lang: "tr",
useLocation: true,
sharedSecret: "optional shared secret",
apiVersion: AmaniApiVersion.v2,
).catchError((err) {
// TODO: Handle the error.
});
if (initSuccess) {
// Call any of the modules
IdCapture idCaptureModule = AmaniSDK().getIDCapture();
idCaptureModule.setType("XXX_ID_0");
} else {
throw Exception("Failed to initialize AmaniSDK");
}
Android-only Configure Usage
For Android integrations, the SDK can also be initialized with the configure-based flow.
This flow uses:
setConfigure()to configure the Android SDK.startAmaniSDKWithConfigure()to start the SDK session with the profile token and customer information.
setConfigure() and startAmaniSDKWithConfigure() are intended for Android usage.
For iOS and existing standard Flutter integrations, you can continue using initAmani().
The configure-based Android flow is useful when you want to:
- Enable only the dynamic features required by your flow.
- Reduce unnecessary module initialization.
- Improve first-load behavior by avoiding unused SDK modules.
- Prepare your integration for the newer Android SDK initialization approach.
Dynamic Features
Dynamic features are modular Android SDK components that can be initialized depending on your verification flow.
If you do not specify enabledFeatures, all available features may be enabled by default. This can increase the initial load time because unnecessary modules may also be prepared.
For better performance, we recommend enabling only the features required by your use case.
| Feature | Description |
|---|---|
AmaniAndroidDynamicFeature.idCapture | Enables ID document scanning and capture |
AmaniAndroidDynamicFeature.idHologramDetection | Enables hologram detection on the ID document |
AmaniAndroidDynamicFeature.nfcScan | Enables NFC chip reading for supported documents |
AmaniAndroidDynamicFeature.selfieAuto | Enables automatic selfie capture |
AmaniAndroidDynamicFeature.selfiePoseEstimation | Enables selfie liveness detection with pose estimation |
Usecase 1: Android Configure with All Main Features
Use this setup when your Android flow may require ID capture, hologram detection, NFC, selfie capture, and pose estimation.
import 'dart:io' show Platform;
final AmaniSDK _amaniSDK = AmaniSDK();
Future<void> initAmani() async {
if (Platform.isAndroid) {
await _amaniSDK.setConfigure(
server: "https://server.example",
enabledFeatures: const [
AmaniAndroidDynamicFeature.idCapture,
AmaniAndroidDynamicFeature.idHologramDetection,
AmaniAndroidDynamicFeature.nfcScan,
AmaniAndroidDynamicFeature.selfieAuto,
AmaniAndroidDynamicFeature.selfiePoseEstimation,
],
);
final result = await _amaniSDK.startAmaniSDKWithConfigure(
token: "profile_token",
id: "customer_id_card_number",
lang: "tr",
);
print(result.isTokenExpired);
}
}
In this use case:
setConfigure()prepares the Android SDK.enabledFeaturesdefines which dynamic modules should be used.startAmaniSDKWithConfigure()starts the SDK session.- The server URL is provided during the configure step.
- The profile token and customer ID are provided during the session start step.
Usecase 2: Android Configure with Selected Features
If your flow does not require every module, you should enable only the necessary features.
For example, if your flow only requires ID capture and automatic selfie capture:
import 'dart:io' show Platform;
final AmaniSDK _amaniSDK = AmaniSDK();
Future<void> initAmani() async {
if (Platform.isAndroid) {
await _amaniSDK.setConfigure(
server: "https://server.example",
enabledFeatures: const [
AmaniAndroidDynamicFeature.idCapture,
AmaniAndroidDynamicFeature.selfieAuto,
],
);
final result = await _amaniSDK.startAmaniSDKWithConfigure(
token: "profile_token",
id: "customer_id_card_number",
lang: "tr",
);
print(result.isTokenExpired);
}
}
This approach is recommended when your verification flow does not use NFC, hologram detection, or pose estimation.
Full Platform-based Initialization Example
The following example shows how to use the configure-based flow for Android, while keeping the existing initAmani() flow for iOS.
import 'dart:io' show Platform;
class _HomeScreenState extends State<HomeScreen> {
final AmaniSDK _amaniSDK = AmaniSDK();
Future<void> initAmani() async {
if (Platform.isAndroid) {
await _amaniSDK.setConfigure(
server: "https://server.example",
enabledFeatures: const [
AmaniAndroidDynamicFeature.idCapture,
AmaniAndroidDynamicFeature.idHologramDetection,
AmaniAndroidDynamicFeature.nfcScan,
AmaniAndroidDynamicFeature.selfieAuto,
AmaniAndroidDynamicFeature.selfiePoseEstimation,
],
);
final result = await _amaniSDK.startAmaniSDKWithConfigure(
token: "profile_token",
id: "customer_id_card_number",
lang: "tr",
);
print(result.isTokenExpired);
} else {
bool initSuccess = await _amaniSDK.initAmani(
server: "https://server.example",
customerToken: "profile_token",
customerIdCardNumber: "customer_id_card_number",
useLocation: true,
apiVersion: AmaniApiVersion.v2,
lang: "tr",
).catchError((err) {
throw Exception(err);
});
if (initSuccess) {
final customerInfo = await _amaniSDK.getCustomerInfo();
// Get customer id
print(customerInfo.id);
} else {
throw Exception("Failed to initialize AmaniSDK");
}
}
await for (final delegateEvent in _amaniSDK.getDelegateStream()) {
print("Delegate event received");
print(delegateEvent);
}
}
void initState() {
super.initState();
initAmani();
}
}
Optional Configuration Parameters
Depending on your SDK version and integration, the configure-based Android flow can also support additional configuration options.
Shared Secret
sharedSecret is used to sign and validate network requests.
- This value will be provided confidentially by the Amani team.
- If it is not provided, the SDK can still work.
- However, upload requests may be unsigned.
- For production environments, using
sharedSecretis recommended when available.
Upload Source
uploadSource is used to distinguish uploads from different sources.
Common upload source values are:
KYCVIDEOPASSWORD
If not specified, the default upload source is usually KYC.
SSL Pinning
SSL Pinning provides additional network security by validating SSL certificates.
If SSL Pinning is exposed by your Flutter SDK version, it should be configured before calling setConfigure().
If an invalid SSL certificate is provided, the SDK may throw an exception. Always handle SSL Pinning configuration with proper error handling.
Registering the event stream
For getting errors from this SDK, information about the KYC profile, and step results as the steps are updated, listen to the event stream.
// In any async function
// delegateResult is Map<dynamic> consisting of type and data fields
await for (final delegateResult in AmaniSDK().getDelegateStream()) {
// Handle delegateResult
}
Understanding the module system
Each type of document has different modules that you can set the document type and capture with it.
Modules use the same pattern of containing:
startsetTypeupload
Each start method can have different parameters, with subtle differences.
Which Initialization Method Should I Use?
| Use case | Recommended method |
|---|---|
| Standard Flutter integration | initAmani() |
| iOS integration | initAmani() |
| Android integration with dynamic feature control | setConfigure() + startAmaniSDKWithConfigure() |
| Android integration where only selected modules are needed | setConfigure() + startAmaniSDKWithConfigure() |
For most existing integrations, initAmani() is enough.
For Android integrations where you want more control over dynamic features and initialization behavior, use the configure-based flow.