Getting the Journey Result

Overview

This section shows how to access key journey processing results directly on the client, so you can quickly react to outcomes like pass or fail status, or retrieve extracted document data without waiting on backend calls.

Think of this as a fast path for driving UI behavior: enabling flows, showing messages, or pre filling fields based on the result.

That said, this client side access is a convenience, not your source of truth. For anything critical, you should always retrieve the full journey result from your backend and store it securely. Backend retrieval (Through GetJourneyByID API) is more reliable, ensures data integrity, and avoids risks associated with running on an uncontrolled client device.

Wait for the onJourneyFinished callback before you call IDWise.getJourneyResult(). That callback tells you the capture flow has ended and the SDK can return the journey outcome.

IDWise.getJourneyResult() returns the overall system decision, document and selfie processing results, and any rule evaluation results. If processing is still in progress, the async method waits and then returns the result object.

📘

Ensure you are running a recent version of IDWise SDK that supports this functionality.
This is supported from SDK version 6.5.0 and newer.

Example Code

IDWise.getJourneyResult { result, error in
    if let error = error {
        // Handle known error codes
        switch error.code {
        case IDWiseErrorCode.timeout:
            // The journey is still processing. Check your flow configuration.
            print("Request timed out. Check network connectivity.")
        case IDWiseErrorCode.noActiveJourney:
            print("There is no active journey. Ensure you call startJourney or resumeJourney.")
        case IDWiseErrorCode.duplicateCall:
            print("A getJourneyResult request is already in progress. You can only call this method once at a time.")
        default:
            print("Unexpected error code: \(error.code) \(error.message)")
        }
        return
    }

    guard let result = result else { return }

    // Route based on the system decision
    switch result.systemDecision {
    case .Complete:
        print("Verification passed for journey: \(result.journeyId)")
        // All checks in the journey passed, so you can continue onboarding.

        // You can get Step ID by selecting the step in Flow Builder
        let idDocumentStepId = "20"
        let identityDocument = result.documents?[idDocumentStepId]

        let fullNameField = identityDocument?.extractedFields?["Full Name"]
        if let fullNameField = fullNameField {
            // Read the extracted value and map it into your onboarding flow.
            print("Full Name: \(fullNameField.value ?? "")")
        }
        // Read any additional extracted fields your flow requires.

    case .Rejected:
        print("Sorry we are unable to open an account for you at this time \(result.journeyId)")
        // At least one rule failed with an action on failure set to reject.
        // The user did not pass verification, so you should stop the flow.

    case .Refer:
        print("Thanks for completing the verification steps. We are reviewing your submissions and will get back to you soon \(result.journeyId)")
        // On your backend you can handle Finished Journey webhook so any journey with
        // a Refer system decision gets pushed to your Review team to make a decision.
        // Then you may inform your user of the decision based on your requirements and logic.

    default:
        print("Unexpected systemDecision: \(result.systemDecision)")
    }
}
IDWise.getJourneyResult { result, error in
    if let error = error {
        // Handle known error codes
        switch error.code {
        case IDWiseErrorCode.journeyNotCompleted:
            // You should call getJourneyResult only after onJourneyCompleted callback is triggered
            print("Please call getJourneyResult after onJourneyCompleted callback handler.")
        case IDWiseErrorCode.timeout:
            // The journey is still processing. Check your flow configuration.
            print("Request timed out. Check network connectivity.")
        case IDWiseErrorCode.noActiveJourney:
            print("There is no active journey. Ensure you call startJourney or resumeJourney.")
        case IDWiseErrorCode.duplicateCall:
            print("A getJourneyResult request is already in progress. You can only call this method once at a time.")
        default:
            print("Unexpected error code: \(error.code) \(error.message)")
        }
        return
    }

    guard let result = result else { return }

    // Route based on the system decision
    switch result.systemDecision {
    case .Complete:
        print("Verification passed for journey: \(result.journeyId)")
        // All checks in the journey passed, so you can continue onboarding.

        // You can get Step ID by selecting the step in Flow Builder
        let idDocumentStepId = "20"
        let identityDocument = result.documents?[idDocumentStepId]

        let fullNameField = identityDocument?.extractedFields?["Full Name"]
        if let fullNameField = fullNameField {
            // Read the extracted value and map it into your onboarding flow.
            print("Full Name: \(fullNameField.value ?? "")")
        }
        // Read any additional extracted fields your flow requires.

    case .Rejected:
        print("Sorry we are unable to open an account for you at this time \(result.journeyId)")
        // At least one rule failed with an action on failure set to reject.
        // The user did not pass verification, so you should stop the flow.

    case .Refer:
        print("Thanks for completing the verification steps. We are reviewing your submissions and will get back to you soon \(result.journeyId)")
        // On your backend you can handle Finished Journey webhook so any journey with
        // a Refer system decision gets pushed to your Review team to make a decision.
        // Then you may inform your user of the decision based on your requirements and logic.

    default:
        print("Unexpected systemDecision: \(result.systemDecision)")
    }
}
IDWise.getJourneyResult({
      onJourneyResult(journeyResultInfo) {
      console.log('Event onJourneyResult received:', journeyResultInfo);
      console.log('isCompleted:', journeyResultInfo.isCompleted);
      console.log('system Decision:', journeyResultInfo.systemDecision);
      console.log('rules:', journeyResultInfo.rules);
      
      const document = journeyResultInfo.documents["STEP_ID_DOCUMENT"]
      if(document != null) {
        console.log('Document Result:', document);
        console.log('Document Passed:', document["hasPassedRules"]);
        console.log('Full Name:',  document["extractedFields"]["Full Name"]);
        console.log('Nationality:',  document["extractedFields"]["Nationality"]);
      }

      const selfie = journeyResultInfo.selfie;
      if(selfie != null) {
        console.log('Selfie Result:', selfie);
        console.log('Selfie Passed:', selfie["hasPassedRules"]);
      }

    },
  onError(error) {
   	console.log('Event onJourneyResultError:', error.code, error.message);
  },
});
IDWise.getJourneyResult(onJourneyResult: (dynamic journeyResultInfo) {

  if (journeyResultInfo["error"] != null) { 
    var error = journeyResultInfo["error"];
    // Handle known error codes
    switch (error["code"]) {                                                                         
      case "journey_not_completed":
        // You should call getJourneyResult only after onJourneyCompleted callback is triggered       
        print("Please call getJourneyResult after onJourneyCompleted callback handler.");
        break;
      case "timeout":                                                                                 
        // The journey is still processing. Check your flow configuration.
        print("Request timed out. Check network connectivity.");
        break;
      case "no_active_journey":
        print("There is no active journey. Ensure you call startJourney or resumeJourney.");
        break;
      case "duplicate_call":                                                                          
        print("A getJourneyResult request is already in progress. You can only call this method once at a time.");
        break;
      default:                                                                                       
        print("Unexpected error code: ${error["code"]} ${error["message"]}");
    }  
    return;                             
  }

  if (journeyResultInfo["result"] != null) {
    var result = journeyResultInfo["result"];                
    // Route based on the system decision
    switch (result["systemDecision"]) {
      case "Complete":                      
        print("Verification passed for journey: ${result["journeyId"]}");
        // All checks in the journey passed, so you can continue onboarding.
        // You can get Step ID by selecting the step in Flow Builder
        var documents = result["documents"];                                                         
        var identityDocument = documents != null ? documents["20"] : null;

        if (identityDocument != null) {     
          var extractedFields = identityDocument["extractedFields"];
          var fullNameField = extractedFields != null ? extractedFields["Full Name"] : null;
          if (fullNameField != null) {                                                               
            // Read the extracted value and map it into your onboarding flow.
            print("Full Name: ${fullNameField["value"]}");                                           
          }     
          // Read any additional extracted fields your flow requires.
        }
        break;                                                                                        
      case "Rejected":                      
        print("Sorry we are unable to open an account for you at this time ${result["journeyId"]}");
        // At least one rule failed with an action on failure set to reject.
        // The user did not pass verification, so you should stop the flow.
        break;
      case "Refer":                     
        print("Thanks for completing the verification steps. We are reviewing your submissions and will get back to you soon ${result["journeyId"]}");
        // On your backend you can handle Finished Journey webhook so any journey with
        // a Refer system decision gets pushed to your Review team to make a decision.
        // Then you may inform your user of the decision based on your requirements and logic.
        break;                          
      default:                                                                                       
        print("Unexpected systemDecision: ${result["systemDecision"]}");
    }                                                                                                 
  }                                                       
});                       

Response Model

JourneyResultInfo response Object

This is the JSON format of the object returned by the SDK in response to getJourneyResult() method call:

{
    "isCompleted": true,
    "systemDecision": "Rejected",
    "referenceNo": "ABC1234",
    "journeyId": "69e00000000000001304",
    "documents": {
        "20": { //20 is step id of this Document step
            "stepTitle": "ID Document",
            "stepId": "20",
            "hasPassedRules": false,
            "documentType": "Identity Card",
            "documentSubtype": null,
            "issuingCountry": "Netherlands",
            "issuingCountryCode": "NLD",
            "extractedFields": {
                "Full Name": {
                    "value": "Willeke Liselotte De Bruijn"
                },
                "First Name": {
                    "value": "Willeke Liselotte"
                },
                "Last Name": {
                    "value": "De Bruijn"
                },
                "Sex": {
                    "value": "Female"
                },
                "Sex Native": {
                    "value": "V"
                },
                "Birth Date": {
                    "value": "1965-03-10"
                },
                "Issue Date": {
                    "value": "2014-03-09"
                },
                "Expiry Date": {
                    "value": "2024-03-09"
                },
                "Document Number": {
                    "value": "SPECI2014"
                },
                "Nationality": {
                    "value": "ABW"
                },
                "Nationality Native": {
                    "value": "Nederlandse"
                },
                "Signature": {
                    "value": null
                }
            }
        },
        "50": { //50 is step if of the Document step
            "stepTitle": "Proof of Address",
            "stepId": "50",
            "hasPassedRules": true,
            "documentType": "",
            "documentSubtype": "",
            "issuingCountry": "",
            "issuingCountryCode": "",
            "extractedFields": {}
        }
    },
    "selfie": {
        "status": "Refer",
        "hasPassedRules": false,
        "isLive": true,
        "livenessStatusCode": null
    },
    "rules": {
        "unrecognized_document": {
            "name": "Recognised Document",
            "result": "Passed"
        },
        "document_validation": {
            "name": "Authentic Document",
            "result": "Failed"
        },
        "expired_document": {
            "name": "Expired Document",
            "result": "Failed"
        },
        "user_confirmation": {
            "name": "Confirmed Data Mismatch",
            "result": "Passed"
        },
        "document_quality": {
            "name": "Document Quality",
            "result": "Failed"
        },
        "no_duplicate_documents": {
            "name": "Unique Document",
            "result": "Passed"
        },
        "no_duplicate_applicant": {
            "name": "Unique Applicant",
            "result": "Failed"
        },
        "same_subject": {
            "name": "Same Person",
            "result": "Failed"
        },
        "selfie_liveness": {
            "name": "Selfie Liveness",
            "result": "Passed"
        },
        "behavioural_checks": {
            "name": "Behavioural Checks",
            "result": "Failed"
        }
    }
}

These are the fields that and their description of the JourneyResultObject

Field

Type

Description

isCompleted

boolean

Indicates that the journey was completed

systemDecision

SystemDecision

Indicates the high level outcome of the journey. This can be one of the values: Complete, Rejected or Refer Check the table below for details.

journeyId

string

The unique identifier of the journey

referenceNo

string

The reference number that was provided during starting of the journey

documents

Map < string, DocumentResult>

Contains the processing results of the documents in this journey. This is a dictionary with the key being the Step ID. You can find the Step ID for a given Document in your Flow by checking in Flow Builder.
For more details on the Document Result object, check the table below.

selfie

Map <string, SelfieResult >

Selfie verification results. Check the corresponding table for SelfieResult below for details.

rules

Map <string, RuleDetail >

Results of the business rules for this journey. The business rules reflect their result on the systemDecision field. And in many cases you that field is sufficient to drive the logic of your app. But in case you need to have custom handling of specific rules then this dictionary gives you access to the details for each specific rule and whether it passed or failed. Check the RuleDetail table below for details.

SystemDecision Enum

The systemDecision field indicates the overall verification outcome:

DecisionMeaningRecommended Action
CompleteAll verification checks passed.Allow the user to proceed.
RejectedOne or more checks failed and the user did not pass verification.Block the user and display a rejection message.
ReferThe system could not make a definitive decision. Manual review is required.Queue the journey for manual review by your compliance team.

DocumentResult Object

Each entry in the documents dictionary describes the result for one document step:

FieldTypeDescription
stepTitlestringTitle of the journey step that collected the document.
stepIdstringIdentifier of the document step.
hasPassedRulesbooleantrue if the document passed the configured document-level rules.
documentTypestringDetected document type, such as "Identity Card" or "Passport".
documentSubtypestring / nullMore specific document classification when available.
issuingCountrystringFull name of the country that issued this document.
issuingCountryCodestringISO 3166 1 alpha 3 country code for the country that issued this document.
extractedFieldsMap <string, FieldValue>OCR-extracted fields returned for the document, keyed by field name.

FieldValue Object

Each entry in extractedFields represents one OCR-extracted field from the document:

The key is the field name returned by OCR, such as Full Name, Nationality Native, or Signature.

FieldTypeDescription
valuestring / nullExtracted value for the field. This is null when the field is present but no value could be extracted.

Example:

{
  "Full Name": {
    "value": "Willeke Liselotte De Bruijn"
  },
  "Signature": {
    "value": null
  }
}

SelfieResult Object

The selfie object describes the selfie and liveness verification outcome:

FieldTypeDescription
statusstringOverall selfie verification result, such as Refer.
hasPassedRulesbooleantrue if the selfie passed the configured selfie-related rules.
isLivebooleantrue if the liveness check detected a live person.
livenessStatusCodestringDetailed liveness result code, such as FACE_NOT_FOUND.

RuleDetail Object

Each entry in the rules dictionary describes a single verification rule and its outcome:

Field

Type

Description

name

string

Human-readable name of the rule (e.g., "Document Expiry Check")

result

string

The result of running this rule. This can be one of the following values:

  • Passed : The rule's conditions were met.
  • Failed : The rule's conditions were not met (e.g., the document is expired for Document Expiry rule).
  • CouldNotApply : The rule could not be evaluated, usually because the required data was missing or unreadable.

Example:

{
  name: "Document Expiry Check",
  result: "Passed"
}

Error Handling

If the request cannot be fulfilled, the SDK returns an error object:

{
  "code": "STRING",
  "message": "STRING"
}
FieldTypeDescription
codestringIdentify the failure type and handle it programmatically.
messagestringExplanation of the error that describes what went wrong and what you should check next.

Error Codes

Error CodeDescription
journey_not_completedThe journey is not completed yet. Please call getJourneyResult only after the onJourneyFinished callback was triggered
no_active_journeyThere is no active journey. Ensure you call startJourney or resumeJourney and wait for onJourneyFinished callback to call getJourneyResult method
duplicate_callA getJourneyResult request is already in progress. You can only call this method once at a time.
timeoutRequest timed out. Please check the internet connection and try again.