This page catalogs the data returned by the plugin's APIs and modules, plus the typed error strings you may receive.
How results and errors are delivered
Every plugin call takes a success callback and an error callback:
cordova.exec(successCallback, errorCallback, "Cplugin", "methodName", [args]);
The success callback receives either a session-level result object or an aggregated result object containing per-module result payloads keyed by name. The error callback receives a typed error string.
The two sections below document both:
- API results: the shape of the success callback payload for each API method, and the error strings its error callback may deliver.
- Module result objects: the shape of the per-module payload that each module contributes to the aggregated result of
startOnboarding()andstartOnboardingSection().
User cancellation
User cancellation is not a successful completion. When the user cancels a section or flow, the error callback fires with "userCancelled" on both platforms. When the system ends the flow, such as when it destroys the SDK screen in the background, the error callback fires with "interrupted" on both platforms. Handle both in your error callback alongside other typed errors.
API results
faceMatch()
Success callback receives the face match result as a flat object, identical on both platforms. idCategory is always included. Every other field appears only when the native SDK returns a value for it. A missing field means there's no result to report, which is not the same as false or 0.
{
confidence: 0.99, // 0–1 match confidence
isExistingUser: true, // whether this is a returning user
existingInterviewId: "b3e2…", // interview ID of the existing user if found
isFaceMatched: true,
isNameMatched: true,
idCategory: "primary", // "primary" | "secondary" — always present
nfcVsIdConfidence: 0.94, // NFC vs ID face confidence (NFC flows only)
nfcVsSelfieConfidence: 0.91, // NFC vs selfie confidence (NFC flows only)
secondIdConfidence: 0.88 // second-ID confidence, when a secondary ID was scanned
}
There is no status field. Derive it from isFaceMatched if you need one.
The fields that are always included differ by platform, because the Android and iOS SDKs handle "unknown" differently:
| Field | Android | iOS |
|---|---|---|
idCategory |
Always | Always |
isExistingUser, isFaceMatched, isNameMatched |
Always | Present only when the native SDK has a value; isFaceMatched is absent when no ID was uploaded, so there was nothing to compare |
confidence, existingInterviewId, nfcVsIdConfidence, nfcVsSelfieConfidence, secondIdConfidence |
Present when available | Present when available |
If your app runs on both platforms, write your code for the iOS behavior. Check whether a field exists, not whether it's truthy.
The error callback receives { code, message, cause }. See faceMatch() in the API reference for the full list of codes.
This shape differs from the faceMatchData object contributed by the addFaceMatch module, which retains its own legacy field names.
finishOnboarding()
Success callback indicates the session was finalized successfully. The success string differs by platform ("onOnboardingFinished" on Android; "flow finished successfully" on iOS).
getUserScore()
Pass "fast" or "accurate" as fetchMode. The success callback receives the score object below with identity verification scores.
cordova.exec(
function (result) {
console.log("Score:", JSON.stringify(result));
},
function (error) {
console.log("Error:", error);
},
"Cplugin",
"getUserScore",
["fast"]
);
overall is always present; its value and status are null when the SDK returned no overall score. The other top-level sections—idValidation, liveness, faceRecognition, and governmentValidation—are present only when the SDK returned that section. Inside a present section, every sub-key is always present, null when the value is absent. Check lists are always arrays; they are [] when empty. extendedUserScoreJsonData is always present and is a raw JSON string ("{}" when unavailable), so it needs parsing.
status is one of ok, warn, fail, unknown, manual, or null. Entries whose status is unknown are omitted from photoSecurityAndQuality and ocrValidation; idSpecific is unfiltered.
{
"extendedUserScoreJsonData": "<raw JSON>",
"overall": { "value": "80.5", "status": "ok" },
"idValidation": {
"overall": { "value": "92", "status": "ok" },
"photoSecurityAndQuality": [ { "key": "tamperCheck", "value": "100", "status": "ok" } ],
"idSpecific": [ { "key": "…", "value": "…", "status": "…" } ]
},
"liveness": {
"overall": { "value": "88", "status": "ok" },
"livenessScore": { "value": "88", "status": "ok" },
"photoQuality": "70.5"
},
"faceRecognition": {
"overall": { "value": "95", "status": "ok" },
"existingUser": false
},
"governmentValidation": {
"overall": { "value": "90", "status": "ok" },
"recognitionConfidence": { "value": "91", "status": "ok" },
"validationStatus": { "key": "…", "value": "VALID", "status": "ok" },
"ocrValidation": [ { "key": "…", "value": "…", "status": "…" } ]
}
}
initializeSDK()
Success callback indicates the SDK was initialized successfully. The success string differs by platform ("success" on Android; "Incode SDK init complete" or "Incode SDK is already initialized" on iOS).
Errors are the same on Android and iOS, delivered as "<code>: <message>". Match on the code prefix if you need typed handling.
| Code | Meaning |
|---|---|
simulatorDetected |
Running on a simulator while testMode is false. |
testModeEnabled |
testMode is true in a production context. |
invalidInitParams |
Bad apiKey / apiUrl. |
configError |
Missing/invalid config (e.g. null config or empty apiConfig.url). |
unknown |
Unexpected error. |
isInitialized()
Success callback receives a boolean: true if the native SDK is fully initialized, false otherwise.
cordova.exec(
function (isInitialized) { console.log("Initialized:", isInitialized); },
function (err) { console.log("Error:", err); },
"Cplugin",
"isInitialized",
[]
);
setupOnboardingSession()
Success callback receives an object containing the created session identifiers:
{
interviewId: "string", // the session id
token: "string" // the session token
}
startFaceLogin()
iOS success callback receives a mapped face login object:
{
faceMatched: true, // boolean
spoofAttempt: false, // boolean
image: {
pngBase64: "", // base64-encoded selfie
encryptedBase64: "" // E2EE-encrypted selfie (when E2EE is enabled)
},
customerUUID: "", // string or null; null when faceMatched is false
interviewId: "", // string; session ID in which the user was approved
interviewToken: "", // string; session token in which the user was approved
token: "", // string; token for further API calls
transactionId: "", // string; unique ID of this face login attempt
hasFaceMask: false // boolean; true when login failed because user wore a mask
}
Android success (and some failure) callbacks receive the native SelfieScanResult JSON from Gson.
Error callback receives a platform-specific value. Neither platform emits fixed strings.
- iOS:
"face login failed: <native error>", or another descriptive string from the SDK. - Android: the native error message (or
"onError"when none is available),"onUserCancelled"when the user cancels, or in some failure paths the face login result JSON is passed to the error callback.
startOnboarding()
Success callback receives the aggregated result of the executed flow: a top-level object with one key per module that ran (for example, frontIdData, selfieData, faceMatchData). There is no top-level status field on this API — status is only added for startOnboardingSection(). See Module result objects below for each module's shape.
startOnboardingSection()
The success callback receives a top-level object:
{
status: "success",
sectionTag: "your-tag", // the value of the sectionTag parameter you passed
// ...plus one key per module that ran (see Module result objects below)
}
Each module that ran in the section contributes its own key—such as frontIdData, selfieData, and faceMatchData—to this object.
Before the section starts, the error callback receives { code, message, cause }:
{
code: "configError",
message: "sectionTag is required to start an onboarding section",
cause: null
}
Start-up codes are activityNotPresent, unknownModule, configError, sectionAlreadyRunning, noActiveSession (Android), and unknown. cause is null or an object with type and message. Android also includes stackTrace. See the API Reference for each code.
A concurrent call fails with sectionAlreadyRunning on both platforms and leaves the running section's callback and results unchanged.
After the section starts, the error callback receives one of the following typed strings from native onError or user-cancel handlers:
| Error | Platform | Meaning |
|---|---|---|
permissionsDenied |
Android, iOS | Required permissions denied, including a camera or microphone permission during Video Selfie. |
videoSelfieNotCompleted |
Android, iOS | Video Selfie could not be completed. |
faceAuthenticationFailed |
Android, iOS | Face authentication module failed. |
sslPinningFailed |
Android, iOS | SSL pinning failure (MITM or bad certificate). |
locationUnavailable |
Android, iOS | Unable to determine location. |
storageUnavailable |
Android | No writable images directory available on the device. |
integrityCompromised |
iOS | Device integrity check failed. |
combinedConsentsNotReceived |
iOS | A mandatory combined consent had no readable text or checkbox ID, so the flow stopped. |
userCancelled |
Android, iOS | User cancelled the flow. |
interrupted |
Android, iOS | The system ended the flow, for example when it destroyed the SDK screen in the background. |
sessionCreationFailed |
iOS | The onboarding session could not be created. |
captchaNotVerified |
iOS | The CAPTCHA could not be verified, so the flow ended. On Android a failed CAPTCHA fails with unknown. |
biometricConsentNotGiven |
Android, iOS | The user did not give consent to store biometric data. |
biometricConsentNotReceived |
Android, iOS | The biometric consent did not reach Incode. |
sectionAlreadyRunning |
iOS | A section was started while another one was running. |
noActiveSession |
iOS | The flow needs an onboarding session and there is none. |
insufficientDiskSpace |
Android | Not enough free disk space for the SDK's ML models. |
onDeviceProcessingNotCompatible |
Android | On-device processing is enabled together with a setting it does not support: for example, no end-to-end encryption, frame streaming, or screen recording. |
unknown |
Android, iOS | Unexpected or unmapped error. |
The error callback is called once per flow. The same post-start codes apply to startOnboarding(), startFlow() and startWorkflow().
Detailed face-authentication failure reasons, such as userIsNotRecognized, appear on the module result as faceAuthenticationData.error, not as the section errorCallback string.
startWorkflow()
Success callback receives the aggregated result of the workflow, in the same shape as startOnboarding().
If the workflow cannot be started, the error callback receives an object:
{
code: "configError",
message: "configurationId or token is required to start a workflow",
cause: null
}
| Code | Platform | Meaning |
|---|---|---|
activityNotPresent |
Android, iOS | No host Activity (Android) or presenting view controller (iOS). Reported before the flow starts. |
configError |
Android, iOS | sessionConfig has neither a non-empty configurationId nor a non-empty token. Reported before the flow starts; no network request is made. |
unknown |
Android, iOS | The SDK threw while starting. |
bridgeFailure |
Android | The native call threw before producing a result. |
After the Workflow starts, errors are reported the same way as for startOnboardingSection().
startFlow()
Success callback receives the aggregated result of the flow, in the same shape as startOnboarding().
If the flow cannot be started, the error callback receives an object:
{
code: "configError",
message: "configurationId or token is required to start a flow",
cause: null
}
| Code | Platform | Meaning |
|---|---|---|
activityNotPresent |
Android, iOS | No host Activity (Android) or presenting view controller (iOS). Reported before the flow starts. |
configError |
Android, iOS | sessionConfig has neither a non-empty configurationId nor a non-empty token. Reported before the flow starts. |
unknown |
Android, iOS | The SDK threw while starting. |
bridgeFailure |
Android | The native call threw before producing a result. |
An unknown or empty moduleId starts the flow from the first module. After the flow starts, errors are reported the same way as for startOnboardingSection().
Module result objects
Each module contributes a key to the startOnboarding() or startOnboardingSection() success callback payload. This section catalogs the shape of each key's value, alphabetized by key name.
antifraudData
From addAntifraud.
{ status: true } // boolean: true = antifraud check passed
approveData
From the non-UI approve module. The approve() API returns this same object directly.
{
success: true, // boolean: true = user approved
uuid: "<uuid>", // string | null; customer ID of the created customer
customerToken: "<token>", // string | null; customer token
error: null // string | null; iOS only, always null on Android
}
error carries a flow error code—sslPinningFailed, integrityCompromised, or unknown—when the iOS approval module reports one. Android's native ApproveResult has no error field, so the key is always null there.
backIdData
From addId.
{
status: "ok", // see status values below
image: "<base64String>", // base64-encoded image
classifiedIdType: "ID", // classified document type, e.g. "ID"
idCategory: "primary", // "primary" | "secondary"
chosenIdType: "id", // "id" | "passport"
allAttemptsExhausted: false // true when no more retries available
}
status values:
| Value | Meaning |
|---|---|
ok |
Capture succeeded |
unknown |
Unknown error |
errorClassification |
Document classification failed |
errorGlare |
Glare detected |
errorSharpness |
Image not sharp enough |
errorReadability |
Document not readable |
errorInCapture |
Capture error (iOS) |
errorUnacceptableID |
ID not acceptable (iOS) |
wrongSide |
Wrong document side shown (iOS) |
curpValidationData
From CurpValidation.
{
curp: "MXMO860324HDFRDM05", // the validated, generated, or entered CURP
valid: true, // true if RENAPO accepted the CURP
data: { success: true, curp: "MXMO860324HDFRDM05" }, // raw response from the validation service
status: "success", // "success" | "fail"
resultCode: "success" // "success" | "error"
}
statusissuccessonly when RENAPO accepted the CURP. A rejected CURP or a failed request givesstatus: "fail"andresultCode: "error", on both platforms.curpanddataare omitted when the SDK has no value: for example, after a network failure.datais an object. Keys inside it that the service returns asnullstaynull.- With
validationEnabled: false, no server check runs, sovalidanddataare omitted.statusissuccesswhen a CURP was captured. When the step ends without one,statusisfail,resultCodeiserror, andcurpis omitted. - When the user enters more than one CURP, only the final attempt is reported.
- Cancelling the step doesn't deliver
curpValidationData. The error callback gets the user-cancelled string instead.
documentData
From addDocumentScan. The data field's structure depends on the document type captured.
{
type: "addressStatement", // "addressStatement" | "medicalDoc" | "paymentProof" | "otherDocument1" | "otherDocument2" | "otherDocument3"
image: "<base64String>",
address: {
city: "string",
colony: "string",
postalCode: "string",
street: "string",
state: "string"
},
data: "<rawData>"
}
eKYC
From addEKYC. Note that the result key is eKYC, not eKYCData.
{ status: true } // boolean: true = eKYC checks passed
emailData
From Email.
{
email: "user@example.com",
status: "success", // "success" | "fail"
resultCode: "success" // success | error on both; userCancelled | emulatorDetected on Android
}
faceAuthenticationData
From addFaceAuthentication.
{
status: "success", // "success" | "fail"
customerUUID: "string", // UUID of the authenticated customer
selfieBase64: "string", // base64-encoded selfie image
selfieEncryptedBase64: "string", // E2EE-encrypted selfie (when E2EE is enabled)
error: null // null on success; typed string on failure (see below)
}
error values when status is "fail":
| Error | Meaning |
|---|---|
inactiveSession |
Session is no longer active |
nonexistentCustomer |
No enrolled face found for this user |
lensesDetected |
Glasses or lenses detected |
faceMaskDetected |
Face mask detected |
headCoverDetected |
Head covering detected |
closedEyesDetected |
Eyes are closed |
faceTooDark |
Insufficient lighting |
spoofAttemptDetected |
Liveness check failed |
userIsNotRecognized |
Face does not match enrolled user |
selfieImageLowQuality |
Selfie image quality too low |
hintNotProvided |
Required authentication hint was not set |
faceNotFound |
No face detected in frame |
faceCroppingFailed |
Face region could not be extracted |
faceTooSmall |
Face is too far from the camera |
faceTooBlurry |
Image is too blurry |
badPhotoQuality |
General photo quality failure |
processingError |
Server-side processing error |
badRequest |
Malformed request |
deniedCameraPermissions |
Camera permission denied (iOS) |
userCancelled |
User cancelled face authentication (iOS) |
unknown |
Unexpected error |
faceMatchData
From the addFaceMatch module. The standalone faceMatch() API returns a
different, flat shape.
{
status: "match", // "match" | "mismatch"
confidence: 0.99, // 0–1 match confidence
existingUser: true, // whether this is a returning user
existingInterviewId: "", // interview ID of the existing user if found
isFaceMatched: true,
isNameMatched: true,
idCategory: "primary", // "primary" | "secondary"
nfcVsIdConfidence: 0, // NFC vs ID face confidence (NFC flows only)
nfcVsSelfieConfidence: 0 // NFC vs selfie confidence (NFC flows only)
}
Older documentation may refer to existingUser as isExistingUser; the current name is existingUser.
frontIdAttemptData / backIdAttemptData
From addId attempt callbacks. iOS only — Android does not emit these keys.
Shape matches frontIdData / backIdData.
frontIdData
From addId.
{
status: "ok", // see status values below
image: "<base64String>", // base64-encoded image
classifiedIdType: "ID", // classified document type, e.g. "ID"
idCategory: "primary", // "primary" | "secondary"
chosenIdType: "id", // "id" | "passport"
allAttemptsExhausted: false // true when no more retries available
}
status values:
| Value | Meaning |
|---|---|
ok |
Capture succeeded |
unknown |
Unknown error |
errorClassification |
Document classification failed |
errorGlare |
Glare detected |
errorSharpness |
Image not sharp enough |
errorReadability |
Document not readable |
errorInCapture |
Capture error (iOS) |
errorUnacceptableID |
ID not acceptable (iOS) |
wrongSide |
Wrong document side shown (iOS) |
fullNameData
From FullName.
{
name: "Jane Doe",
status: "success", // "success" | "fail"
resultCode: "success" // success | error on both; userCancelled | emulatorDetected on Android
}
geoLocationData
From Geolocation. Identical in shape on Android and iOS.
{
addressFields: { // absent when no location was fetched
street: "string", // each field absent when the SDK has no value
colony: "string",
postalCode: "string",
city: "string", // falls back to the region when the city is unknown
state: "string" // the country name
},
latitude: 19.4326, // absent when no location was fetched
longitude: -99.1332, // absent when no location was fetched
status: "success", // success only when a location was fetched, otherwise fail
resultCode: "success", // success | error on both; userCancelled on Android
error: "locationUnavailable" // only when resultCode is error: permissionsDenied | locationUnavailable | sslPinningFailed | integrityCompromised | unknown
}
A skipped, denied, or unavailable location is reported here with status: "fail", and the flow continues. When isSkippable is false, the flow ends through errorCallback instead, with permissionsDenied or locationUnavailable. On Android, the native SDK reports a fail result for the step first and then the error, so the section still ends through errorCallback. On iOS, a skip in the current UI is always reported as locationUnavailable, and a location whose address could not be fully resolved is reported as fail with locationUnavailable but still carries the partial addressFields and the coordinates.
govresult / govValidationData
From addGovernmentValidation. The result key differs by platform:
- Android:
govresult - iOS:
govValidationData
{ status: true } // boolean
machineLearningConsentData / MLConsentData
From addMachineLearningConsent. The result key differs by platform:
- Android:
machineLearningConsentData - iOS:
MLConsentData
{ status: true } // boolean: true = consent accepted, false = consent declined
The consent is optional and the flow continues either way, so treat status: false as
declined, not as a module failure. On iOS, false is also reported when the choice
could not be recorded.
nfcData
From addNFC. All MRZ and chip fields are extracted from the document chip. Date fields (birthDate, expireAt) follow the MRZ YYMMDD format returned by the document chip.
{
birthDate: "",
compositeCheckDigit: "",
dateOfBirthCheckDigit: "",
documentCode: "",
documentNumber: "",
documentNumberCheckDigit: "",
expirationDateCheckDigit: "",
expireAt: "",
gender: "",
issuingStateOrOrganization: "",
nationality: "",
optionalData1: "",
optionalData2: "",
personalNumber: "",
personalNumberCheckDigit: "",
primaryIdentifier: "",
secondaryIdentifier: "",
status: true // boolean
}
phoneData
From Phone.
{
phone: "+1234567890",
status: "success", // "success" | "fail"
resultCode: "success" // success | error on both; userCancelled | emulatorDetected on Android
}
processIdData
From addId (added automatically via processId).
{
extendedOcrData: "<jsonString>", // raw JSON string with full OCR data
data: {
address: {
city: "string",
colony: "string",
postalCode: "string",
street: "string",
state: "string"
},
fullAddress: "string",
birthDate: 0, // Unix timestamp in milliseconds
expirationDate: 0, // Unix timestamp
gender: "string",
name: "string",
issueDate: 0, // Unix timestamp
numeroEmisionCredencial: "string"
}
}
selfieAttemptData
From addSelfieScan attempt callbacks. Same shape as selfieData. Emitted on both Android and iOS when a selfie capture attempt completes (including retries).
{
status: "success", // "success" | "unknown"
image: "<base64String>", // base64-encoded selfie
spoofAttempt: false,
allAttemptsExhausted: false
}
selfieData
From addSelfieScan.
{
status: "success", // "success" | "unknown"
image: "<base64String>", // base64-encoded selfie
spoofAttempt: false,
allAttemptsExhausted: false
}
signatureData
From addSignature. Only fires when the signature is collected.
{ status: "success" }
Older documentation may refer to this key as signaturePath; the current name is signatureData.
userConsentData
From addUserConsent.
- iOS:
{ status: true }when consent is given (statusis a boolean). - Android: currently emits an empty object
{}for this key.
userScore result (inline)
When userScore is run inline via { module: "userScore", mode: "fast" } in a flowConfig, the score is included in the section result under userScoreData in the same shape as getUserScore.
videoSelfieData
From addVideoSelfie.
{ status: true } // boolean: true = success, false = failed
getUserScore errors (typed strings)
| Error | Meaning |
|---|---|
userScoreFailed |
Transport or HTTP failure, mapping failure, or submit-only mode. Also reported on iOS when the server returns a completely empty score, where Android instead reports success with an empty payload—a platform difference the underlying SDKs make unavoidable. |
userCancelled |
User cancelled. Android only. The call has no UI, so iOS never reports it. |