Implementation steps

This series of guides explains how to use the FrankieOne API to perform many different types of functions. It includes descriptions, code samples and things to consider during implementation It is important to remember the following:

  • The Individuals API is separate and can not be used in conjunction with any other API.
  • All sample requests require authorization as defined in the Getting Started section.

Individual Verification

The following examples show how to use the FrankieOne API to perform functions related to an individual.

Create an individual entity

To create an individual entity eligible for verification, make a request to the POST /v2/individuals API endpoint.

  • To add a name to an individual, use the name object in the request body.
"name": {
	"givenName": "Johnny",
	"middleName": "Tan",
	"familyName": "Doe",
	"displayName": "Johnny Tan Doe"
}
  • To add a date of birth to an individual, use the dateOfBirth object in the request body.
...
"dateOfBirth": {
	"year": "1990",
	"month": "05",
	"day": "15"
},
...
  • To add an address to an individual, use the addresses array in the request body.
  • To add multiple addresses, add a separate address to the addresses array.
...
"addresses": 
[
	{
		"type": "RESIDENTIAL",
		"streetName": "King",
		"streetNumber": "123",
		"streetType": "Street",
		"neighborhood": "Melbourne CBD",
		"locality": "Melbourne",
		"subdivision": "VIC",
		"country": "AUS",
		"postalCode": "3000",
		"status": "CURRENT"
	}
]
...
  • To acknowledge consent for an individual, use the consents array in the request body.
...
"consents": 
[
	{
		"type": "GENERAL"
	},
	{
		"type": "CREDITHEADER"
	},
	{
		"type": "DOCS"
	},	
]
}
...

Sample request

curl --location 'http://api.{{env}}.frankie.one/v2/individuals' \
--header 'api_key: {{your_apiKey}}' \
--header 'X-Frankie-CustomerID: {{your_CustomerID}}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
  "individual": {
"name": 
{
		"givenName": "Johnny",
		"middleName": "Tan",
		"familyName": "Doe",
		"displayName": "Johnny Tan Doe"
	},
"dateOfBirth": 
{
		"year": "1990",
		"month": "05",
		"day": "15"
},
"addresses": 
[
{
"type": "RESIDENTIAL",
	"streetName": "King",
	"streetNumber": "123",
	"streetType": "Street",
	"neighborhood": "Melbourne CBD",
	"locality": "Melbourne",
	"subdivision": "VIC",
	"country": "AUS",
	"postalCode": "3000",
	"status": "CURRENT"
}
],
"consents": 
[
	{
		"type": "GENERAL"
	},
	{
		"type": "CREDITHEADER"
	},
	{
		"type": "DOCS"
	}
]
}
}'

Sample response

🚧

Collect the entityId in the response as it will be used in subsequent API calls for this individual.

Status: 201 Created

{
  "individual": {
    "entityId": "{entityId}",
    "entityType": "INDIVIDUAL",
    "createdAt": "2024-01-31T23:21:57.296Z",
    "schemaVersion": 2,
    "addresses": [
      {
        "addressId": "{addressId}",
        "type": "RESIDENTIAL",
        "streetName": "King",
        "streetNumber": "123",
        "streetType": "Street",
        "neighborhood": "Melbourne CBD",
        "locality": "Melbourne",
        "subdivision": "VIC",
        "country": "AUS",
        "postalCode": "3000",
        "status": "CURRENT"
      }
    ],
    "name": {
      "nameId": "{nameId}",
      "givenName": "Johnny",
      "middleName": "Tan",
      "familyName": "Doe",
      "displayName": "Johnny Tan Doe"
    },
    "dateOfBirth": {
      "dateOfBirthId": "{dateOfBirthId}"
      "normalized": "1990-03-31",
      "year": "1990",
      "month": "03",
      "day": "27",
      "type": "GREGORIAN"
      },
"consents": 
[
	{
		"type": "GENERAL"
	},
	{
		"type": "CREDITHEADER"
	},
	{
		"type": "DOCS"
	},	
]
}
  },
  "requestId": "{requestId}"
}

Note: Service Profiles have been intentionally omitted for brevity

Addresses

🚧

Don't forget the Address ID.

When updating an address, don’t forget to include the addressId field. This would have been in the response message when you first added the address.

You can always get the addressId (and all other IDs) if you call the GET /v2/{entityType}/{entityId} API call.

🚧

Don't forget the Country

This field is mandatory and must be one of the ISO-3166-alpha-3 codes.

See here: List of ISO 3166 country codes

Address Types

Addresses have a number of available type options. Whilst this is an optional field, it is good practice to include the type to assist with processing and checking. It is recommended that these following types be used:

  • **RESIDENTIAL **- This will be the primary address used when trying to determine the country of residence and primary current address. If RESIDENTIAL has been used for this, note that this will be deprecated and removed in the next major version of the API.
  • **POSTAL **- This is a mailing address. It is also used as the current residential address if no RESIDENTIAL type is found.

Street Address and the use of the streetName field

It can be hard to break down an address and so we’ve made the streetName field quite flexible.

Whilst it is best to break the address into its constituent parts, you can combine streetNumber, streetName and streetType into the streetName field if required.

🚧

It's better to break down the address fields.

Whilst combining the fields is readily supported, best matching results are found when you break the address down into as many fields as you can.

Structured Addresses

It is always best to use the structured address and map in 1-1 the following fields.

Field nameDescriptionType
typeThe type of address, for example residential, postalString (enum)
typeDescriptionThe description of the address. Used for reference only.string
unitNumberUnit | Apartment | Flat | Suite | others number.string
streetNumberThe number on the street. Generally a number, but can also be alphanumeric ( for example, 3A).string
streetNameThe name of the street.string
streetTypeThe street type - for example, Road, St, Ave, Circuit, and others.string
buildingNameThe name of the building, apartment block, condo, and othersstring
locality(formerly town) The locality, town, village, suburb, or citystring
district(formerly region) The district, region, county, province, or cantonment of the addressstring
neighborhoodThe neighborhood or suburb in the town or city.

Note: Only use neighborhood if locality is already captured as part of the address and an additional location is required. Otherwise just use locality.
string
subdivisionThe administrative area, state, or subdivision.

Note: Abbreviations (“VIC”) and full names (“Victoria”) are acceptable.
string
countryThe ISO-3166-1 alpha 3 country code of the address.string
postalCodeThe postal code or zip code of the address.string
careOfIndividual or business name at this address if not the same as the name of the entity to which this address belongs.string
longFormThe full address details. It is preferable that the address is broken down into its constituent parts however where that is not possible, a longForm can be used.

Note: longForm address matching generally produces weaker results due to the complexity involved in breaking down, interpreting and mapping an entire address from a single string.
string
statusDetermines the status of this address in relation to the entity using it.
Example: Current or Future

Note: “Current” addresses will be treated as primary addresses for verification purposes.
string (enum)
validToWhen will this entity no longer be using this address? Used for reference only.date
validFromWhen did the entity first start using this address? Used for reference only.date

Example 1: Full Address Entered as Separate Fields (preferable)

...
"addresses": 
[
	{
		"type": "RESIDENTIAL",
		"streetName": "King",
		"streetNumber": "123",
		"streetType": "Street",
                "locality": "Melbourne",
		"subdivision": "VIC",
		"country": "AUS",
		"postalCode": "3000",
		"status": "CURRENT"
	}
]
...

Example 2: Full Address Entered as Long Form

...
"addresses": 
[
	{
		"type": "RESIDENTIAL",
		"longForm": "123 King Street, Melbourne 3000, Victoria, Australia",
		"status": "CURRENT"
	}
]
...

Consent

Before proceeding with data verification checks, obtaining consent is essential and varies based on the verification type. While general consent encompasses standard verifications against government databases, it may not include credit checks and document validations. Consult with your AML team and the FrankieOne team to determine what consent flags you need to supply.

ConsentDescription
GENERALThis indicates that the entity has given consent for their name, address, or DoB to be checked against our various databases and external services.
DOCSThis indicates that the entity has given consent to have their identity documents checked against official sources.
CREDITHEADERThis indicates that the entity has given permission to have their details checked against a credit bureau service. If this check fails, you must inform the user that the check failed and put them in touch with the bureau directly so that they may update their details as necessary. This is not normally available by default, so please see your account manager about making this service available.
UNDER18This indicates that the entity is under the age of 18 and a parent or guardian has provided consent. This is a special case of the consent.general flag (see above). consent.docs would still be required to check their passports or drivers license.
PAYROLLThis consent is used to allow access to verifying an identity using payroll data.
INSURANCEThis consent is used to allow access to verifying an identity using workcover data.
SUPERANNUATIONThis consent is used to allow access to verifying an identity using superannuation data.

Retrieve an individual entity

The individual entity can be retrieved at any time by making a request to the GET /v2/individuals/{entityId} API endpoint.

Update an individual entity

The individual entity can be updated at any time by making a request to the PATCH /v2/individuals/{entityId} API endpoint.

To update a specific element of an individual entity, be sure to provide the relevant information you wish to update along with the ID of the object. This does not the case with primary entity elements (name, dateOfBirth, placeOfBirth)

Example 1: update a name

"name": 
{
	"givenName": "James",
	"familyName": "Done"
}

Example 2: update an address

"addresses": 
[
	{
		"addressId": "{addressId}",
		"status": "CURRENT"
	}
]

Example 3: update alternateDatesOfBirth

"alternateDatesOfBirth": 
{
	"dateOfBirthId": "{dateOfBirthId}",
        "year": "1992",
	"month": "12",
	"day": "05"
}

Adding entity elements

To add a new object to an existing entity, simply add the new object without an ID.

Example 1: adding an address

"addresses": 
[
	{
		"type": "RESIDENTIAL",
		"streetNumber": "123",
		"streetName": "King",
		"streetType": "Street",
		"locality": "Melbourne",
		"postalCode": "3000",
		"subdivision": "NSW",
		"country": "AUS",
		"status": "CURRENT"
	}
]

Adding consents

Consents will not be duplicated so new consent types will simply be added if not already applied.

Example 2: adding consents

"consents":  
[  
	{  
		"type": "CREDITHEADER"  
	}  
]

Deleting entity elements

Individual entity objects can be deleted at any time by making a request to the DELETE /v2/individuals/{entityId}/{objectType}/{objectId} API endpoint.

Example 1: deleting a phoneNumber

DELETE /v2/individuals/{entityId}/phonenumbers/{objectId}

Example 2: deleting a emailAddress

DELETE /v2/individuals/{entityId}/emailaddresses/{objectId}

Deleting documents

Individual document objects can be deleted at any time by making a request to the DELETE /v2/individuals/{entityId}/documents/{documentId} API endpoint.

DELETE /v2/individuals/{entityId}/documents/{documentId}

Deleting document attachments

Individual document attachment objects can be deleted at any time by making a request to the DELETE /v2/individuals/{entityId}/documents/{documentId}/attachments/{attachmentId} API endpoint.

DELETE /v2/individuals/{entityId}/documents/{documentId}/attachments/{attachmentId}

Withdrawing consent

Individual consent of a certain type can be withdrawn at any time by making a request to the DELETE /v2/individuals/{entityId}/consents/{consentType} API endpoint.

DELETE /v2/individuals/{entityId}/consents/CREDITHEADER

Delete an individual entity

The individual entity can be deleted at any time by making a request to the DELETE /v2/individuals/{entityId} API endpoint.

❗️

Individual entities that are deleted can not be recovered by FrankieOne.

Please ensure you only delete entities that are no longer needed for any purpose, including audit or compliance.

Execute a workflow

To start onboarding an individual and running checks on them, you’ll need to call the "execute workflow" API endpoint. Upon execution, the workflow will return a result.

curl --location --request POST
'https://api.{{env}}.frankie.one/v2/individuals/{entityId}/serviceprofiles/kyc/workflows/{workflowName}/execute' \
--header 'api_key: {{your_apiKey}}' \
--header 'X-Frankie-CustomerID: {{your_CustomerID}}' \
--header 'X-Frankie-CustomerChildID: {{your_CustomerChildID}}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \

Retrieve a workflow execution result

The workflow execution result can be retrieved at any time post execution by making a request to the GET /v2/individuals/{entityId}/serviceprofiles/{serviceName}/workflows/{workflowName}/executions/{workflowExecutionId} API endpoint.

Retrieve a history of workflow execution result

The individual entity can be updated at any time by making a request to the PATCH /v2/individuals/{entityId} API endpoint.

Interpreting Workflow Results

After a workflow has been executed, various elements require examination to determine the final outcome.

Legend:

  • ‼️ - Results that deem whether the entity has passed or failed or the workflow failed to execute to completion.
  • ⚠ - Context on why the entity may have passed or failed.
  • ℹ️ - Information-only, no contribution to whether the entity has passed or failed.

Field nameDescriptionImportance
statusThe ultimate assessment of whether the individual passed all workflow requirements lies in the status, which provides a conclusive recommendation based on the checks run. It accounts for whether all verification checks were successful or if there were failures.
The status also captures manual intervention such as any action of overriding the result directly outside the context of a workflow.

UNCHECKED - Workflow has not yet been executed or the workflow result was not updated successfully as part of the workflow execution.
IN_PROGRESS - Workflow is currently running and awaiting completion.
PASS - Workflow completed successfully and the entity passed all checks required. Alternatively, the status was applied manually proceeding workflow execution.
FAIL - Workflow completed successfully, however the entity did not pass all checks required. Alternatively, the status was applied manually proceeding workflow execution.

Note: the **statusOverrideAt** field can be used to determine if the status was manually overridden.
‼️
statusOverrideAtThe UTC time of when the status was manually overridden outside the workflow execution.ℹ️
statusOverrideRequestIdThe unique requestId of the request that manually overrode the status outside the workflow execution.ℹ️
statusOverrideByThe X-Frankie-Username header value in the request that manually overrode the status outside of the workflow execution.ℹ️
resultThe result is the original workflow outcome that was determined at the completion of the workflow. In the case of manual override, this will differ from the status.
UNCHECKED - Workflow has not yet been executed or the workflow result was not updated successfully as part of the workflow execution.

IN_PROGRESS - Workflow is currently running and awaiting completion.
PASS - Workflow completed successfully and the entity passed all checks required.
FAIL - Workflow completed successfully, however the entity did not pass all checks required.
workflowExecutionStateThe workflowExecutionState is an indicator of whether the workflow was able to execute to completeness. The workflowExecutionState should always be in a state of “COMPLETED” otherwise it is telling that the workflow execution did not finish executing and that the result should be taken with that context in mind.‼️
workflowStepResultsThe workflowStepResults is a detailed list of all the steps that were executed as part of the workflow and their individual outcomes.
riskAssessmentThe riskAssessment is a summary of all the risk factors that were encountered during the execution of the workflow and the accumulated risk level of the entity as a result of those factors.
issuesissues is a summary of all the issues that were encountered during the execution of the workflow that may have affected the outcome such as errors, insufficient data, or simply a failed verification.

Typically issues will only be present if any checks have failed.
workflowExecutionIdThe unique identifier of the workflow execution. Generated on triggering the workflow execution.ℹ️
serviceProfileIdThe unique identifier of the service profile in which the workflow was executed. Set based on the serviceName in the path of the workflow execution request API.ℹ️
workflowIdThe ID of the workflow that was executed. Set based on the workflowName in the path of the workflow execution request API.ℹ️
workflowNameThe name of the workflow that was executed. Set based on the workflowName in the path of the workflow execution request API.ℹ️
stepsThe steps that were executed as part of this workflow execution:
order - order in which the steps were executed
passed - steps that passed or were successful in execution
failed - steps that failed or were unsuccessful in execution
incomplete - steps that did not execute or did not execute to completion
notApplicable - steps that did not run because they were deemed unnecessary
ℹ️
entityTypeThe type of entity in which the workflow was executed. INDIVIDUAL or ORGANIZATION.ℹ️
errorsAny errors that were encountered as part of the workflow execution
requestIdThe requestId is the unique identifier of the request that triggered this workflow execution.ℹ️
entityIdThe entityId of the individual/organization in which the workflow was executed.ℹ️
startedAtstartedAt refers to when the workflow started executing.ℹ️
endedAtendedAt refers to when the workflow finished executing.ℹ️
createdAtcreatedAt refers to when the process result was created.ℹ️
updatedAtupdatedAt refers to when the process result was last updated.ℹ️
updatedByupdatedBy refers to who last updated the workflow execution. This will be the value of the X-Frankie-Username header of the request that executed the workflow or overrode the workflow result.ℹ️
schemaVersionRefers to the version of the schema returned. Will always be 2 in the FrankieOne v2.x API.ℹ️
notesAny additional notes that were captured during the process.ℹ️
Know Your Customer (KYC) Database Verification

Example 1: Pass

"workflowResult": {
    "createdAt": "2024-07-08T06:37:22.520433Z",
    "endedAt": "2024-07-08T06:37:27.697016Z",
    "entityType": "INDIVIDUAL",
    "issues": [...],
    "workflowExecutionId": "{workflowExecutionId}",
    "requestId": "{requestId}",
    "entityId": "{entityId}",
    "startedAt": "2024-01-15T02:18:11.365Z",
    "endedAt": "2024-01-15T02:18:11.365Z",
    "workflowId": "{workflowId}",
    "workflowName": "onboarding",
    "steps": "[KYC]",
    "result": "PASS",
    "status": "PASS",
    "workflowExecutionState": "COMPLETED",
    "schemaVersion": 2,
    "serviceProfileId": "{serviceProfileId}",
    "updatedAt": "2024-07-08T06:37:27.769601Z",
    "updatedBy": "system:frankieone",
    "riskAssessment": [...],
    "workflowStepResults": [...]
},
"requestId": "{requestId}"

Example 2: Fail

"workflowResult": {
    "createdAt": "2024-07-08T06:37:22.520433Z",
    "endedAt": "2024-07-08T06:37:27.697016Z",
    "entityType": "INDIVIDUAL",
    "issues": [...],
    "workflowExecutionId": "{workflowExecutionId}",
      "requestId": "{requestId}",
    "entityId": "{entityId}",
    "startedAt": "2024-01-15T02:18:11.365Z",
    "endedAt": "2024-01-15T02:18:11.365Z",
    "workflowId": "{workflowId}",
    "workflowName": "onboarding",
    "steps": "[KYC]",
    "result": "FAIL",
    "status": "FAIL",
    "workflowExecutionState": "COMPLETED",
    "schemaVersion": 2,
    "serviceProfileId": "{serviceProfileId}",
    "updatedAt": "2024-07-08T06:37:27.769601Z",
    "updatedBy": "system:frankieone",
    "riskAssessment": [...],
    "workflowStepResults": [...]
},
"requestId": "{requestId}"

Example 3: Workflow failed but status was overridden to be passed

"workflowResult": {
    "createdAt": "2024-07-08T06:37:22.520433Z",
    "endedAt": "2024-07-08T06:37:27.697016Z",
    "entityType": "INDIVIDUAL",
    "issues": [...],
    "workflowExecutionId": "{workflowExecutionId}",
    "requestId": "{requestId}",
    "entityId": "{entityId}",
    "startedAt": "2024-01-15T02:18:11.365Z",
    "endedAt": "2024-01-15T02:18:11.365Z",
    "workflowId": "{workflowId}",
    "workflowName": "onboarding",
    "steps": "[KYC]",
    "result": "FAIL",
    "status": "PASS",
    "workflowExecutionState": "COMPLETED",
    "schemaVersion": 2,
    "serviceProfileId": "{serviceProfileId}",
    "updatedAt": "2024-07-08T06:37:27.769601Z",
    "updatedBy": "system:frankieone",
    "riskAssessment": [...],
    "workflowStepResults": [...]
},
"requestId": "{requestId}"

Interpreting Workflow Step Results

Workflow outcomes will encompass a variety of individual step outcomes, each autonomously documenting the findings of their specific verification processes. Steps such as data verification/Know Your Customer (KYC) checks, Anti-Money Laundering (AML) screenings, Identity Verification (IDV), and risk evaluations are integral components of a workflow. To streamline reporting, step outcomes are consolidated according to their category, ensuring that identical steps are aggregated and presented as a unified outcome. For instance, KYC procedures may be executed repeatedly using a diversified set of service providers and configurations; however, a singular step outcome will be generated, encapsulating the entirety of the assessments conducted.

Each step is defined in a consistent format, with significant variations stemming from the stepData and processResults only. These elements are distinct to each step type, providing tailored insights specific to the step’s function.

Know Your Customer (KYC) Database Verification

The KYC workflow step takes into account all the processed data and indicates the outcome in the result field.

  • UNCHECKED - KYC was not attempted due to a failure in a previous step
  • MISSING_DATA - KYC was not attempted as not enough data was available
  • MATCH - KYC was attempted successfully, the entity was verified against the required number of data sources
  • NO_MATCH - KYC was attempted, however the entity was not verified against any data sources
  • PARTIAL - KYC was attempted, however the entity was not verified against the required number of data sources if more than 1 was required
  • ERROR - KYC was attempted, however an error was encountered during the process. See errors for more information.
{
    "workflowResult": {
        "workflowStepResults": [
            {
                "endedAt": "2024-05-14T04:04:12.66319Z",
                "objectId": "{objectId}",
                "objectType": "INDIVIDUAL",
                "processResults": [...],
                "requestId": "{requestId}",
                "result": "MATCH",
                "serviceProviders": [...],
                "startedAt": "2024-05-14T04:04:11.849152Z",
                "stepData": {...},
                "stepName": "kyc",
                "stepResultId": "{stepResultId}",
                "workflowExecutionId": "{workflowExecutionId}"
            },
        ]
    }
}

🚧

Service Provider Result

The KYC workflow step indicates the service provider overall outcome as the serviceProviders.result

{
    "workflowResult": {
        "workflowStepResults": [
            {
                "endedAt": "2024-05-14T04:04:12.66319Z",
                "objectId": "{objectId}",
                "objectType": "INDIVIDUAL",
                "processResults": [...],
                "requestId": "{requestId}",
                "result": "MATCH",
                "serviceProviders": [
                    {
                        "endedAt": "2024-05-14T04:04:12.663187286Z",
                        "provider": "dvs",
                          "result": "MATCH",
                        "startedAt": "2024-05-14T04:04:11.849152Z"
                    }
                ],
                "startedAt": "2024-05-14T04:04:11.849152Z",
                "stepData": {...},
                "stepName": "kyc",
                "stepResultId": "{stepResultId}",
                "workflowExecutionId": "{workflowExecutionId}"
            },
        ]
    }
}
Step Summary: Data Source Match Details

To gain insight into which personal information matched against specific sources, please refer to the matchedRules. Commonly, you’ll find a singular ruleMatches entry detailing the outcome of a particular rule established in the workflow. For example, a rule might stipulate that both a name and either a date of birth or address be verified against two independent data sources. matchTypes will reveal the exact element verified, while matchSources will specify the data sources used for confirmation. Any data sources consulted but yielding no matches will be listed as nonMatchSources.

After a KYC step has been executed, various elements require examination to determine the final outcome.

Legend:

  • ‼️ - Results that deem whether the entity has passed or failed or the workflow failed to execute to completion.
  • ⚠ - Context on why the entity may have passed or failed.
  • ℹ️ - Information-only, no contribution to whether the entity has passed or failed.
Matched and Unmatched Rules

The matchedRules and unmatchedRules that exist within the KYC workflow step summary are identical in structure and differ only in whether the ruleset was matched against successfully (matchedRules) or not (unmatchedRules).

Field nameDescriptionImportance
matchedRulesList of all the KYC rulesets that matched and the summary of those matches. See Matched and Unmatched Rules.
unmatchedRulesList of all the KYC rulesets that did not match and the summary of those matches. See Matched and Unmatched Rules.
Rulesets

The requirements rulesets are defined within the KYC workflow step configuration and are used to determine whether the number of data source matches have been met for each entity element (for example, name, date of birth, address and others) for the verification to be considered a match.

Field nameDescriptionImportance
ruleNameName of the ruleset
Default: default
ℹ️
ruleOrderOrder in which we attempted to match the results against the requirements defined in the ruleset.

Example: 1
ℹ️
ruleMatchesList of matches that made up this ruleset. See Rule Matches.
Ruleset Match Details

The specific matching details of each rule that was matched or not matched.

Field nameDescriptionImportance
matchTypesThe match types that this overall count and results refer to
matchCountNumber of matches found for this ruleset
matchCountRequiredNumber of matches required for this ruleset to be satisfied
hasAllRequiredSourcesMatchedDetermines whether a match has been found for all required data sources defined in the ruleset.

Note: Optional. This is only evaluated if 1 or more data sources have been set as mandatory within the KYC workflow step configuration.
requiredSourcesMatchedList of the required sources that the entity has been matched against.

Note: Optional. This is only evaluated if 1 or more data sources have been set as mandatory within the KYC workflow step configuration.
requiredSourcesNotMatchedList of the required sources that the entity has not been matched against.



Note: Optional. This is only evaluated if 1 or more data sources have been set as mandatory within the KYC workflow step configuration.
isVerifiedDetermines whether the matches required have been satisfied, indicating a successful matched ruleset. Based on whether matchCount >= matchCountRequired

true/false
‼️
Ruleset Matched Types

The specific matching details of each element (for example, name, dateOfBirth, and others) that was matched or not matched.

Field nameDescriptionImportance
objectIdThe unique identifier of the object (for example: name, address, date of birth) that was verifiedℹ️
objectTypeThe type of the object that was verified (for example: name, address, date of birth)ℹ️
matchCountNumber of matches found for this object type
matchSourcesList of all the data sources that the entity was matched against.
Example: “au-elec-roll”
nonMatchSourcesList of all the data sources that the entity was not matched against.
Example: “au-elec-roll”
isCheckedDetermines whether an attempt was made to verify the entity’s personal information as identified by the objectId and objectType (for example: name, date of birth, address)
isVerifiedDetermines whether the entity’s personal information as identified by the objectId and objectType (for example: name, date of birth, address) was able to be verified by at least 1 data source.‼️
Example 1: Successful KYC Database Verification

Let’s break down the following match result:

  • name, dob and address were checked as they are listed under matchTypes
  • Based on the matchCount we can determine how many data sources we were able to match against for each element:
    • name matched against the Australian Electoral Roll (“au-elec-roll”) and Equifax Public Credit Data Header (“au-efax-cdh-pub”)
    • address matched against the Australian Electoral Roll (“au-elec-roll”) only
    • dateOfBirth matched against the Equifax Public Credit Data Header (“au-efax-cdh-pub”)
  • matchCount equals the matchCountRequired which means we were able to find enough matches for a positive result
  • requiredSourcesMatched indicates that the Australian Electoral Roll (“au-elec-roll”) was a source that was required to be matched against, which it was (name, address)
  • isVerified indicates that the match requirements were satisfied based on the rule criteria
"summary": {
  "matchedRules": [
	{
	  "ruleName": "SafeHarbour2x2",
	  "ruleOrder": 1,
	  "ruleMatches": [
		{
		  "matchTypes": {
			"name": {
			  "objectId": "{objectId}",
			  "matchCount": 2,
			  "matchSources": ["au-elec-roll", "au-efax-cdh-pub"],
			  "nonMatchSources": ["au-efax-cdh-consumer"],
			  "isChecked": true,
			  "isVerified": true
			},
 			"address": {
			  "objectId": "{objectId}",
			  "matchCount": 1,
			  "matchSources": ["au-elec-roll"],
			  "nonMatchSources": ["au-efax-cdh-pub", "au-efax-cdh-consumer"],
			  "isChecked": true,
			  "isVerified": true
			},
 			"dateOfBirth": {
			  "objectId": "{objectId}",
			  "matchCount": 1,
			  "matchSources": [""au-efax-cdh-pub""],
			  "nonMatchSources": ["au-elec-roll", "au-efax-cdh-consumer"],
			  "isChecked": true,
			  "isVerified": true
			}
		  },
		  "matchCount": 2,
		  "matchCountRequired": 2,
		  "hasAllRequiredSourcesMatched": true,
		  "requiredSourcesMatched": ["au-elec-roll"],
		  "isVerified": true
		}
	  ]
	}
  ],
...
Example 2: Unsuccessful KYC Database Verification

Similarly to the matchedRules, the unmatchedRules contains a singular ruleMatches entry detailing the outcome of a particular rule established in the workflow that has not been met.

Let’s break down the following non matched result:

  • name, dob and address were checked as they are listed under matchTypes
  • Based on the matchCount we can see no matchSources present which tells us that there were no matches.
  • The nonMatchSources lists the sources that were checked against but without a successful match result
    • name did not match against the Australian Electoral Roll (“au-elec-roll”) and Equifax Public Credit Data Header (“au-efax-cdh-pub”) or Equifax Consumer Credit Data Header (“au-efax-cdh-consumer”)
    • address did not match against the Australian Electoral Roll (“au-elec-roll”) and Equifax Public Credit Data Header (“au-efax-cdh-pub”) or Equifax Consumer Credit Data Header (“au-efax-cdh-consumer”)
    • dateOfBirth did not match against the Australian Electoral Roll (“au-elec-roll”) and Equifax Public Credit Data Header (“au-efax-cdh-pub”) or Equifax Consumer Credit Data Header (“au-efax-cdh-consumer”)
  • matchCount does not equal the matchCountRequired which means we were not able to find enough matches for a positive result
  • requiredSourcesMatched indicates that the Australian Electoral Roll (“au-elec-roll”) was also a source that was required to be matched against, which was not
  • isVerified indicates that the match requirements were not satisfied based on the rule criteria
"summary": {
  "unmatchedRules": [
	{
	  "ruleName": "SafeHarbour2x2",
	  "ruleOrder": 1,
	  "ruleMatches": [
		{
		  "matchTypes": {
				"name": {
			  	"matchCount": 0,
			  	"nonMatchSources": ["au-elec-roll", "au-efax-cdh-pub", "au-efax-cdh-consumer"],
			  	"isChecked": true,
			  	"isVerified": false
			},
 			"address": {
			  "matchCount": 0,
			  "nonMatchSources": ["au-elec-roll", "au-efax-cdh-pub", "au-efax-cdh-consumer"],
			  "isChecked": true,
			  "isVerified": false
			},
 			"dateOfBirth": {
			  "matchCount": 0,
			  "nonMatchSources": ["au-elec-roll", "au-efax-cdh-pub" "au-efax-cdh-consumer"],
			  "isChecked": true,
			  "isVerified": false
			}
		  },
		  "matchCount": 0,
		  "matchCountRequired": 2,
		  "hasAllRequiredSourcesMatched": false,
		  "requiredSourcesNotMatched": ["au-elec-roll"],
		  "isVerified": false
		}
	  ]
	}
  ]
Process Results: Data Source Match Details

KYC match details are represented as processResults existing under the workflow step results for steps that require verification or some sort of checks to be run and differ based on the context of what the check is trying to accomplish. For checks against external data sources, the processResults will aim to capture what exactly has matched against what source. Steps typically return an array of all the individual process results that were used in determining that step’s result.

After a KYC step has been executed, various elements require examination to determine the final outcome.

Legend:

  • ‼️ - Results that deem whether the entity has passed or failed or the workflow failed to execute to completion.
  • ⚠ - Context on why the entity may have passed or failed.
  • ℹ️ - Information-only, no contribution to whether the entity has passed or failed.

Field nameDescriptionImportance
processResultIdThe processResultId represents the unique identifier of the process resultℹ️
classThe class reflects the type of process result (for example: KYC, AML)ℹ️
resultThe result is the overall outcome of the process (for example: MATCH, NO_MATCH, PARTIAL)‼️
stateThe state reflects whether the process was completed successfully or whether an error of some kind was encountered during the process
stepNameThe stepName indicates the workflow step that triggered the process and thus generated the process resultℹ️
stepTypeThe stepType indicates whether there was a subtype for the step. Generally used in non-KYC step process results.ℹ️
groupIdThe groupId is generated in order to tie related process results together. In the context of KYC, a single groupId will be generated and added to each process result per data source that is checked.ℹ️
systemStatusThe systemStatus indicates that the result is valid and was used in determining the overall step result (typically only VALID results will be returned unless specifically requested).
manualStatusThe manualStatus indicates whether the result has been manually classified by an operator outside of FrankieOne (for example: via API or Portal). This is set most commonly in AML classifications where an operator has registered whether a potential match is a true positive or false positive.
providerResult• The providerResult.confidence refers to the confidence rating that was returned by the provider. Defaults to 0/100 if confidence is not explicit.
providerResult.name refers to the name of the provider
• Any unique identifier on the data provider side will be returned as providerResult.reference
The providerResult.source indicates the raw source that was checked against
The providerResult.sourceNormalized indicates the normalized source that was checked against.

Note: Same sources checked by different providers will have the same sourceNormalized value but different source values.
riskFactorsAny risk factors returned by the service provider will be present as riskFactors and potentially utilized in FrankieOne’s own risk engine, depending on your risk configuration.
objectIdThe objectId indicates the exact element that was checked.ℹ️
objectTypeThe objectType indicates the specific type of element that was checked.ℹ️
entityIdThe entityId of the individual that was checkedℹ️
createdAtcreatedAt refers to when the process result was created.ℹ️
updatedAtupdatedAt refers to when the process result was last updated.ℹ️
updatedByupdatedBy refers to who last updated the process result. Generally this will be FrankieOne unless a manual override was triggered.ℹ️
schemaVersionRefers to the version of the schema returned. Will always be 2 in the FrankieOne v2.x API.ℹ️
requestIdThe unique identifier of the request that generated this process resultℹ️
notesAny additional notes that were captured during the process. May contain extra information about how the result was determined.
errorsAny errors that were encountered as part of the process.
Example: 1: KYC Data Source Match Details

Process Result Objects (PROs) encapsulate the outcomes of specific processes (check, comparison, verification etc.). They play a crucial role in evaluating the overall outcome of relevant workflow steps.

Let’s break down the following KYC process result:

  • The class is “KYC” which indicates the process is in relation to a KYC database verification check.
  • The address of the entity has been successfully verified against the Australian Electoral Roll:
    • Based on the objectType we can see that the specific element checked was an “ADDRESS”
    • The providerResult array contains the details of the service provider that the entity was checked against:
      • The service provider is the Document Verification Service as indicated by the name field (“dvs”)
      • The specific data source that was checked is the Australian Electoral Roll as indicated by the source (“au-elec-roll”) and sourceNormalized (“au-elec-roll”) fields
    • The result is “MATCH” indicating that the address was successfully matched.
  • The check was completed successfully (state is “COMPLETED”) and has not yet been invalidated in any way (systemStatus is “VALID”), therefore it is safe to determine that the process ran to completion and was indeed used in determining the successful result.
  • There has been no manual status applied to the process (due to the absence of a manualStatus field)
"processResults": [
{
	"class": "KYC",
	"createdAt": "2024-07-11T23:57:08.197185Z",
	"entityId": "{entityId}",
	"groupId": "{groupId}",
	"notes": {...},
	"objectId": "{objectId}",
	"objectType": "ADDRESS",
	"processResultId": "{processResultId}",
	"providerResult": {
		"confidence": "100",
		"name": "dvs",
		"reference": "{referenceId",
		"source": "au-elec-roll",
		"sourceNormalized": "au-elec-roll"
	},
	"supplementaryData": {
		"matchStrengths": {
			"fullAddress": 100,
			"streetNumber": 100,
			"streetName": 100
			"streetType": 100,
			"locality": 100,
			"district": 100,
			"subdivision": 100,
			"postalCode": 100,
			"country": 100,
		},
		"fuzziness": {
			"normalized": 0,
			"actual": 0
		},
		"wasNameMatchStrongEnough": true
	},
	"requestId": "{requestId}",
	"result": "MATCH",
	"schemaVersion": 2,
	"state": "COMPLETED",
	"stepName": "KYC",
	"systemStatus": "VALID",
	"updatedAt": "2024-07-11T23:57:08.197185Z"
}
Example: 2: KYC Data Source Non-Match Details

Similar to Process Results (PROs) for KYC database verification matches, process results that result in no match will be generated during step execution and will provide insights into why the data source could NOT be matched.

Let’s break down the following KYC process result:

  • The class is “KYC” which indicates the process is in relation to a KYC database verification check.
  • The address of the entity has been checked but was not verified against the Australian Electoral Roll:
    • Based on the objectType we can see that the specific element checked was an “NAME”
    • The providerResult array contains the details of the service provider that the entity was checked against:
      • The service provider is the Document Verification Service as indicated by the name field (“dvs”)
      • The specific data source that was checked is the Australian Electoral Roll as indicated by the source (“au-elec-roll”) and sourceNormalized (“au-elec-roll”) fields
    • The result is “MATCH” indicating that the address was successfully matched.
  • The matchStrengths within supplementaryData shows that no part of the name matched at all.
  • The fuzziness within supplementaryData shows that an exact match (normalized as “0”) was required, potentially restricting any passable partial matching (“Sarah”, “Sara”).
  • The check was completed successfully (state is “COMPLETED”) and has not yet been invalidated in any way (systemStatus is “VALID”), therefore it is safe to determine that the process ran to completion and was indeed used in determining the successful result.
  • There has been no manual status applied to the process (due to the absence of a manualStatus field).
"processResults": [
{
	"class": "KYC",
	"createdAt": "2024-07-11T23:57:08.197185Z",
	"entityId": "{entityId}",
	"groupId": "{groupId}",
	"notes": {...},
	"objectId": "{objectId}",
	"objectType": "NAME",
	"processResultId": "{processResultId}",
	"providerResult": {
		"confidence": "0",
		"name": "dvs",
		"reference": "{referenceId}",
		"source": "au-elec-roll",
		"sourceNormalized": "au-elec-roll"
	},
	"supplementaryData": {
		"matchStrengths": {
			"fullname": 0,
			"familyName": 0,
			"givenName": 0,
			"otherNames": 0,
			"firstInitialFamilyName": 0
		},
		"fuzziness": {
			"normalized": 0,
			"actual": 0
		}
	}
	"requestId": "{requestId}",
	"result": "NO_MATCH",
	"schemaVersion": 2,
	"state": "COMPLETED",
	"stepName": "KYC",
	"systemStatus": "VALID",
	"updatedAt": "2024-07-11T23:57:08.197185Z"
}

Anti-Money Laundering (AML) Screening

AML screening results are reflected in the result field, which clearly indicates the step’s outcome. This field summarizes the step’s result, taking into account all the processed data. For instance, if an individual’s details such as name show up on any AML screening lists like PEP or Sanctions lists, the result will be HIT. If not, the result will be CLEAR.

{
    "workflowResult": {
        "workflowStepResults": [
            {
                "endedAt": "2024-05-14T04:04:12.66319Z",
                "objectId": "{objectId}",
                "objectType": "INDIVIDUAL",
                "processResults": [...],
                "requestId": "{requestId}",
                "result": "CLEAR",
                "serviceProviders": [
                    {
                        "endedAt": "2024-05-14T04:04:12.663187286Z",
                        "provider": "complyadvantage",
                        "result": "CLEAR",
                        "startedAt": "2024-05-14T04:04:11.849152Z"
                    }
                ],
                "startedAt": "2024-05-14T04:04:11.849152Z",
                "stepData": {...},
                "stepName": "aml",
                "stepResultId": "{stepResultId}",
                "workflowExecutionId": "{workflowExecutionId}"
            },
        ]
    }
}

processResults and summary has been omitted for brevity

Process Results: AML Match Results

processResults exist under the workflow step results for steps that require verification or some sort of checks to be run and differ based on the context of what the check is trying to accomplish. For checks against external data sources, the processResults will aim to capture what exactly has matched against what source. Steps typically return an array of all the individual process results that were used in determining that step’s result.

Take for instance the following example:

"processResults": [
	{
		"class": "AML",
		"createdAt": "2024-05-14T04:04:12.566065Z",
		"entityId": "{entityId}",
		"notes": {...},
		"objectId": "{objectId}",
		"objectType": "name",
		"processResultId": "{processResultId}",
		"providerResult": {
			"confidence": "100",
			"name": "complyadvantage",
			"reference": "{referenceId}",
			"riskScore": 0
		},
		"result": "HIT",
		"state": "COMPLETED",
		"stepName": "pep",
		"supplementaryData": {...},
		"systemStatus": "VALID",
		"updatedAt": "2024-05-14T04:04:12.566065Z"
	}
Supplementary Workflow Steps
Start Step

The start step indicates a successful commencement of the workflow. An effective measure to ascertain if the workflow initiated without complications is to check if the execution result includes a start step with a “COMPLETE” result. Typically, no processResults are anticipated for this step.

{
    "requestId": "{requestId}",    
    "individual": {...},
    "workflowResult": {
        "workflowStepResults": [
            {
                "endedAt": "2024-07-22T05:46:07.722933Z",
                "objectId": "{objectId}",
                "objectType": "INDIVIDUAL",
                "requestId": "{requestId}",
                "result": "COMPLETE",
                "risk": {
                    "contributedScore": 150,
                    "factors": [
                        {
                            "factor": "entity_type",
                            "score": 0,
                            "value": "Individual"
                        },
                        {
                            "factor": "country",
                            "score": 50,
                            "value": "Lithuania"
                        },
                        {
                            "factor": "entity_age",
                            "score": 100,
                            "value": "Under 18"
                        }
                    ],
                    "level": "HIGH",
                    "overallScore": 150
                },
                "schemaVersion": 2,
                "startedAt": "2024-07-22T05:46:09.013204Z",
                "stepName": "START",
                "stepResultId": "{stepResultId}",
                "updatedBy": "01J3CFKFJE1HJACPRFZ7F47N5K",
                "workflowExecutionId": "{workflowExecutionId}"
            }
        ]
    }
}
Finish Step

The finish step indicates whether the workflow completed successfully. This means that all results have been collected and stored, ready for further investigation. To check if the workflow finished without issues, look for a “COMPLETE” result. Keep in mind that this only confirms the workflow’s completion, not the success of individual checks or the absence of errors. Typically, no processResults are generated in this step.

{
    "requestId": "{requestId}",    
    "individual": {...},
    "workflowResult": {
        "workflowStepResults": [
            {
                "endedAt": "2024-07-22T05:46:26.547446Z",
                "objectId": "{objectId}",
                "objectType": "INDIVIDUAL",
                "requestId": "{requestId}",
                "result": "COMPLETE",
                "schemaVersion": 2,
                "startedAt": "2024-07-22T05:46:26.511309Z",
                "stepName": "FINISH",
                "stepResultId": "{stepResultId}",
                "updatedBy": "system:frankieone",
                "workflowExecutionId": "{workflowExecutionId}"
            }
        ]
    }
}
Decision Step

The decision step within the workflow serves as a critical juncture that determines the workflow’s status—be it PASS, FAIL, or REVIEW. This determination hinges on the specific actions taken during the workflow. For instance, if all preceding steps have been executed flawlessly and all checks were cleared, the workflow is typically set to be “PASS”. Conversely, if there’s a hiccup in any step, such as an issue with individual verification, the workflow is likely to be marked as “FAIL”. It’s important to note that the statuses set can be modified within the workflow builder.

{
"workflowStepResults": [
	{
                "endedAt": "2024-07-22T05:46:25.826735Z",
                "objectId": "{objectId}",
                "objectType": "INDIVIDUAL",
                "processResults": [],
                "requestId": "{requestId}",
                "result": "COMPLETE",
                "schemaVersion": 2,
                "startedAt": "2024-07-22T05:46:25.76572Z",
                "stepName": "DECISION",
                "stepResultId": "{stepResultId}",
                "summary": {
                    "stepName": "DECISION",
                    "workflowExecutionResult": "PASS"
                },
                "updatedBy": "system:frankieone",
                "workflowExecutionId": "{stepResultId}"
            }
    ]
}
Risk Step

The risk step in the workflow is a mandatory checkpoint for risk assessment. It doesn't result in a pass or fail status. Instead, it's simply marked as "COMPLETED" once a risk evaluation has been conducted. This step ensures that risks are always considered in the process, without directly affecting the workflow's status. While the risk assessment itself doesn't change the workflow, the information gathered may be useful for later steps.

"workflowStepResults": [
            {
                "endedAt": "2024-07-22T05:46:24.998288Z",
                "objectId": "{objectId}",
                "objectType": "INDIVIDUAL",
                "requestId": "{requestId}",
                "result": "COMPLETE",
                "schemaVersion": 2,
                "startedAt": "2024-07-22T05:46:24.963811Z",
                "stepName": "RISK",
                "stepResultId": "{stepResultId}",
                "updatedBy": "system:frankieone",
                "workflowExecutionId": "{workflowExecutionId}"
            }
	]
    }

Classifying AML Match Results

After investigating the supplementaryData for any AML screening match details, you’ll need to make a decision on whether the person you are evaluating matches the person that we found during screening (true positive) or not (false positive).

To confirm whether an AML screening hit is true positive, false positive or unknown, you’ll need to update the manualStatus of the process result. The manualStatus is used to store any manually determined statuses on a result as not to override the initial result gathered as part of the workflow execution.

Example 1: Classify Single Match as True Positive
curl --location --request POST
'https://api.{{env}}.frankie.one/v2/individuals/{entityId}/results/{processResultId}' \
--header 'api_key: {{your_apiKey}}' \
--header 'X-Frankie-CustomerID: {{your_CustomerID}}' \
--header 'X-Frankie-CustomerChildID: {{your_CustomerChildID}}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
  "processResults": [
    "{processResultId}"
  ],
  "manualStatus": "TRUE_POSITIVE"
}'
Example 2: Classify Multiple Matches as False Positive
curl --location --request POST
'https://api.{{env}}.frankie.one/v2/individuals/{entityId}/results/aml' \
--header 'api_key: {{your_apiKey}}' \
--header 'X-Frankie-CustomerID: {{your_CustomerID}}' \
--header 'X-Frankie-CustomerChildID: {{your_CustomerChildID}}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
  "processResults": [
    "processResultId", "processResultId"
  ],
  "manualStatus": "FALSE_POSITIVE"
}'