Initializing the SDK
Configure
After completing the installation phase, configure the SDK with the Amani.configure()
method, so you can configure several optional parameters below to enhance security and control upload behavior.
Although the new usage is already active and the documentation is based on it, the older functions are still usable until v4.0.0.
This means you can still use init
instead of configure()
, or initAmani
instead of startSession()
, with the same parameters if needed.
At the moment, both approaches have exactly the same effect — the difference is only in the function names.
⚠️ However, starting from v4.0.0, the situation will change: the old init
functions will be fully deprecated, and using configure()
and startSession()
will become mandatory.
✨ Good news: the only parameter difference between initAmani
and startSession()
is that the Activity context no longer needs to be passed when using startSession()
.
We therefore recommend adopting the new functions now to ensure a smooth transition.
SharedSecret
sharedSecret
is a key used to ensure and validate the security of network requests. (Optional)
- This key will be provided to you confidentially by the Amani team.
- If you do not provide
SharedSecret
, theAmani.configure()
method will still work without issues. However, requests made in the upload methods will be unsigned. - To avoid potential security risks, always use
SharedSecret
where possible.
UploadSource
uploadSource
is used to distinguish uploads from different sources. (Optional) This feature allows you to list and group uploaded data in Amani Studio based on source, or generate different statistics accordingly.
- Available options in the current version are: KYC, VIDEO, PASSWORD.
- If not specified, the default is
UploadSource.KYC
. - You can change the
UploadSource
even after initialization using: - If you need to change UploadSource after configure; You should be use the Amani.sharedInstance().setUploadSource() method before any upload method call.
SSL Pinning
SSL Pinning
provides secure networking by validating SSL certificates. (Optional)
- This configuration is optional, but recommended for enhanced security.
- It must be called before the
Amani.configure()
method. - If the provided certificate is invalid, an
AmaniException
will be thrown. Always wrap the call in atry-catch
block.
Example usage:
try {
//Before Amani.configure(...)
Amani.setSSLPinning(this, R.raw.pinning_cert)
} catch (e: AmaniException) {
// Handle invalid certificate
}
Dynamic Feature
Dynamic Features
are modular components of the SDK that can be downloaded and initialized on demand, instead of being bundled in the base SDK package.
- This approach keeps the SDK lightweight and reduces the initial APK size.
- It provides flexibility to enable or disable specific functionalities based on your app’s requirements.
- Dynamic features are downloaded and initialized the first time they are required. Once fetched, they are cached locally for faster startup in subsequent launches.
- By default, the SDK initializes all dynamic features unless you explicitly configure a subset. Initializing all may slightly increase the SDK initialization time on the first launch, as modules and assets might need to be downloaded.
- With the introduction of the dynamic feature architecture in SDK v3.6.0+, the overall SDK size has been reduced by approximately 30–50% compared to earlier versions.
List of the SDK Dynamic Features
are below;
Feature | Description |
---|---|
ID_CAPTURE | Enables ID document scanning & capture |
ID_HOLOGRAM_DETECTION | Detects holograms on the ID for authenticity check |
NFC_SCAN | Reads chip data from ePassports / eIDs via NFC |
SELFIE_AUTO | Captures selfie automatically for face verification |
SELFIE_POSE_ESTIMATION | Validates liveness via pose/movement detection |
Usecase
Below are grouped examples of different Amani.configure()
use cases, ranging from the most basic setup to the most secure configuration.
⚡ Note on Dynamic Features:
Select only the required dynamic features according to your use case.
If you do not specify, all features will be enabled by default, which may increase the initial load time during login since unnecessary modules could be downloaded.
Usecase 1 (Basic)
Initialize the SDK with only the server parameter.
⚠️ Since sharedSecret
is not provided, the validity/security of the requests will not be activated.
Amani.configure(
context = this,
server = "https://server.example",
enabledFeatures = listOf(
DynamicFeature.ID_CAPTURE, // ID document scanning & capture
DynamicFeature.ID_HOLOGRAM_DETECTION, // Detect holograms for authenticity
DynamicFeature.NFC_SCAN, // Read chip data via NFC
DynamicFeature.SELFIE_AUTO, // Automatic selfie capture
DynamicFeature.SELFIE_POSE_ESTIMATION // Liveness detection via pose
)
)
Usecase 2 (Usecase 1 + SharedSecret)
Configure the SDK with server and sharedSecret.
-
The default UploadSource is KYC if not specified.
-
Using sharedSecret ensures that the requests are signed and secure.
Amani.configure(
context = this,
server = "https://server.example",
sharedSecret = "optional shared secret",
enabledFeatures = listOf(
DynamicFeature.ID_CAPTURE, // ID document scanning & capture
DynamicFeature.ID_HOLOGRAM_DETECTION, // Detect holograms for authenticity
DynamicFeature.NFC_SCAN, // Read chip data via NFC
DynamicFeature.SELFIE_AUTO, // Automatic selfie capture
DynamicFeature.SELFIE_POSE_ESTIMATION // Liveness detection via pose
)
)
Usecase 3 (Usercase2 + UploadSource)
Configure the SDK with server, sharedSecret, and a specific UploadSource.
- Available options: UploadSource.KYC, UploadSource.PASSWORD, UploadSource.VIDEO.
Amani.configure(
context = this,
server = "https://server.example",
sharedSecret = "optional shared secret",
uploadSource = UploadSource.KYC,
enabledFeatures = listOf(
DynamicFeature.ID_CAPTURE, // ID document scanning & capture
DynamicFeature.ID_HOLOGRAM_DETECTION, // Detect holograms for authenticity
DynamicFeature.NFC_SCAN, // Read chip data via NFC
DynamicFeature.SELFIE_AUTO, // Automatic selfie capture
DynamicFeature.SELFIE_POSE_ESTIMATION // Liveness detection via pose
)
)
Usecase 4 (Usecase 3 + SSL Pinning)
This setup includes SSL Pinning, sharedSecret
, and a customized list of Dynamic Features.
SSL Pinning ensures secure networking with certificate validation.
sharedSecret
makes requests signed and validated.
enabledFeatures
allows you to control which dynamic modules are active.
✅ This is the recommended and most secure way to initialize the SDK.
// SSL pinning certification settings
try {
Amani.setSSLPinning(
context = this,
certificate = R.raw.ssl_cert
)
} catch (e: Exception) {
// Invalid certificate
}
// Amani configure with advanced configuration
Amani.configure(
context = this,
server = "https://server.example",
sharedSecret = "optional shared secret",
version = AmaniVersion.V2,
uploadSource = UploadSource.KYC,
enabledFeatures = listOf(
DynamicFeature.ID_CAPTURE, // ID document scanning & capture
DynamicFeature.ID_HOLOGRAM_DETECTION, // Detect holograms for authenticity
DynamicFeature.NFC_SCAN, // Read chip data via NFC
DynamicFeature.SELFIE_AUTO, // Automatic selfie capture
DynamicFeature.SELFIE_POSE_ESTIMATION // Liveness detection via pose
)
)
Start Session
After completing the configure phase, you must start session the Amani.sharedInstance().startSession()
method with a profile token from the server and other necessary information.
So after the application stands up, the startSession() function can be called in the flow of a desired screen, depending on the result of startSession() function other modules will be also available to use. If isSuccess is true as a result of the startSession() request, other modules can be used. Otherwise, you will get an error from the callback result of the current module. It is enough for startSession() to be successful once during the lifecycle. The application must be called again when the life cycle ends and a new life cycle starts. (In cases where the user closes and opens the application)
Use Case
This method starts a new session using the provided parameters.
Optional parameters can be removed safely — if you don’t include them, they will take their default values.
They are not mandatory.
Amani.sharedInstance()
.startSession(
id = "ID_NUMBER",
token = "TOKEN",
lang = "LANGUAGE e.g. tr",
geoLocation = true, // Optional — can be removed
userEmail = "Email address of the end user if known", // Optional — can be removed
userFullName = "Full name of the end user if known", // Optional — can be removed
userPhoneNumber = "Phone number of the end user if known", // Optional — can be removed
birthDate = "Birth date of the end user if known", // Optional — can be removed
expireDate = "Document expire date of the end user if known", // Optional — can be removed
documentNo = "Document number of the end user if known" // Optional — can be removed
callback = { isSuccess: Boolean ->
if (isSuccess) {
// The request is successful, all other modules are ready to use.
} else {
// The request failed, due to error : $errorCode
// Other modules cannot be used until the request is successful.
}
}
)
Event Listeners
You can listen the profileStatus
and stepResult
events for the specific changes.
To do this, you can call the setEventListener
method with AmaniEventCallBack
object.
Amani.sharedInstance().AmaniEvent().setListener(object : AmaniEventCallBack {
override fun onError(type: String?, error: ArrayList<AmaniError?>?) {
//Error happened
}
override fun profileStatus(profileStatus: ProfileStatus) {
//Profile status changed
}
override fun stepsResult(stepsResult: StepsResult?) {
//Steps are changed, you can check the list of steps
}
})
Profile Status
Key | Type | Description |
---|---|---|
amlStatus | boolean | Anti Money Laundering |
risk | Int | Range: 0-4. Shows the risk status of the profile |
status | String | Shows the general status of the profile, such as APPROVED, REJECTED, or PENDING |
profile | String | Returns the UUID of the profile the user is connected to |
Steps Result
Key | Type | Description |
---|---|---|
result | ArrayList of Result | Returns the list of steps in the profile as an array list |
id | String | Returns the unique ID of the step |
title | String | Returns the unique title of the related step (example: Selfie, Identification) NOTE: Title is editable, if you want to manipulate the title cummunicate with Amani Mobile Team. |
status | String | Shows the related step status of the profile, such as APPROVED, REJECTED, or PENDING. |
sortOrder | Int | Ordering number of the related step for purpose of the ordering the related step into UI |
errors | List of Errors | Errors of the related steps happened during the process |
On Error
Key | Type | Description |
---|---|---|
type | String | Current error type as String |
error | ArrayList of AmaniError | Returns the list of the AmaniError |
Types
Error Types | Description |
---|---|
login_error | Current error type as String |
config_error | Errors related with fetching remote config |
selfie_error | Errors related with Selfie upload process |
id_error | Errors related with ID upload process |
signature_error | Errors related with Signature upload process |
customer_error | Errors related with Customer service fetch&po |
socket_error | General socket errors |
nfc_error | Errors related with NFC read |
Errors
Error Code | Error Message |
---|---|
10904 | MRZ result is null/empty |
10404 | Selfie should be taken before upload called |
10809 | Back image could not found |
10808 | Response data is null/empty |
10502 | SSL Pinning Error |
10604 | SSL Certificate Exception |
10500 | Please check your internet connection |
10600 | General exception during upload |
Full Use Case
Configure the SDK in the Application class to ensure it's initialized before any activity starts.
import ai.amani.sdk.Amani
import ai.amani.sdk.DynamicFeature
import ai.amani.sdk.UploadSource
import ai.amani.sdk.model.exception.AmaniException
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
// SSL Pinning (optional)
try {
Amani.setSSLPinning(this, R.raw.ssl_cert)
} catch (e: AmaniException) {
e.printStackTrace()
}
// Configure the SDK
Amani.configure(
context = this,
server = "https://server.example",
sharedSecret = "optional_shared_secret",
uploadSource = UploadSource.KYC,
enabledFeatures = listOf(
DynamicFeature.ID_CAPTURE,
DynamicFeature.ID_HOLOGRAM_DETECTION,
DynamicFeature.NFC_SCAN,
DynamicFeature.SELFIE_AUTO,
DynamicFeature.SELFIE_POSE_ESTIMATION
)
)
}
}
This example demonstrates starting a session when a button is clicked, and setting up listeners in onResume.
import ai.amani.sdk.Amani
import ai.amani.sdk.interfaces.AmaniEventCallBack
import ai.amani.sdk.model.amani_events.error.AmaniError
import ai.amani.sdk.model.amani_events.profile_status.ProfileStatus
import ai.amani.sdk.model.amani_events.steps_result.StepsResult
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Button to start session
val startSessionButton: Button = findViewById(R.id.btnStartSession)
startSessionButton.setOnClickListener {
startAmaniSession()
}
}
private fun startAmaniSession() {
val profileToken = "PROFILE_TOKEN_FROM_SERVER"
Amani.sharedInstance().startSession(
id = "USER_ID",
token = profileToken,
lang = "en",
geoLocation = true,
userEmail = "user@example.com",
userFullName = "John Doe",
userPhoneNumber = "+1234567890",
birthDate = "1990-01-01",
expireDate = "2030-01-01",
documentNo = "ABC123456",
callback = { isSuccess ->
if (isSuccess) {
Toast.makeText(this, "Session started successfully", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "Failed to start session", Toast.LENGTH_SHORT).show()
}
}
)
}
override fun onResume() {
super.onResume()
// Set up event listener
Amani.sharedInstance().AmaniEvent().setListener(object : AmaniEventCallBack {
override fun onError(type: String?, error: ArrayList<AmaniError?>?) {
Log.e("AmaniEvent", "Error type: $type, details: $error")
}
override fun profileStatus(profileStatus: ProfileStatus) {
Log.d("AmaniEvent", "Profile status changed: $profileStatus")
}
override fun stepsResult(stepsResult: StepsResult?) {
Log.d("AmaniEvent", "Steps result updated: $stepsResult")
}
})
}
}