Manual KYC Verification (mKYC)

A step-by-step guide to verifying an entity that has completed an in-person or offline identity check.

What is Manual KYC?

Manual KYC (mKYC) is the process of verifying a customer’s identity using physical documents that are sighted and confirmed by an authorised representative (e.g., during a face-to-face meeting).

This guide explains how to use the FrankieOne API to record the outcome of a manual verification, ensuring it is correctly reflected in your compliance workflows and audit trails.

How It Works: The FrankieOne Approach

FrankieOne facilitates mKYC through a simple two-part process that separates the recording of the approval from the verification check itself.

1

1. Log the Manual Approval

You make a single API call to create special “Manual” Process Results for an entity. This acts as a record that a trusted employee has verified the customer’s identity documents in person.

2

2. Verify via Workflow

A dedicated Manual KYC step within your configured workflow checks for the existence of these “Manual” Process Results. If they are present and valid, the step passes, allowing the entity to proceed through the workflow just like an electronic verification.


Implementation Guide

This guide will walk you through the API calls required to perform a manual KYC verification.

Prerequisites

Before you begin, ensure you have the following:

  1. An existing entityId for the individual you want to verify.
  2. The entity has all the necessary information and documents (e.g., name, address, date of birth, and document details) already added to their profile via the API.
  3. A workflow has been configured in your FrankieOne instance that includes the Manual KYC step.

Step 1: Log the Manual Approval

First, you must log that the manual verification has taken place. You do this by calling the POST /v2/individuals/{entityId}/results/mkyc endpoint.

This request tells FrankieOne to create the special “Manual” Process Results (PROs) that will be used as evidence in the workflow.

cURL
1curl --location '[https://api.frankieone.com/v2/individuals/](https://api.frankieone.com/v2/individuals/){{entityId}}/results/mkyc' \
2--header 'api_key: {{your_api_key}}' \
3--header 'X-Frankie-CustomerID: {{your_customer_id}}' \
4--header 'Content-Type: application/json' \
5--data '{
6 "approvedBy": "Jane Doe (Officer #1234)",
7 "approvedDocuments": [
8 "doc_01HBFB8W6A7E8F9G0H1J2K3L4M"
9 ]
10}'

Request Body Explained:

  • approvedBy: (string) The name or identifier of the person who performed the manual verification.
  • approvedDocuments: (array of strings) A list of the documentIds that were sighted and approved as part of the check.

A successful request will return a 200 OK response containing the newly created Process Results. Note the key fields that identify these as manual results: providerResult.name is set to MANUAL and result is MATCH.

JSON
1{
2 "processResults": [
3 {
4 "class": "KYC",
5 "providerResult": { "name": "MANUAL", "reference": "Jane Doe (Officer #1234)" },
6 "result": "MATCH",
7 "state": "COMPLETED",
8 "systemStatus": "VALID",
9 "objectType": "NAME",
10 "...": "..."
11 },
12 {
13 "class": "KYC",
14 "providerResult": { "name": "MANUAL", "reference": "Jane Doe (Officer #1234)" },
15 "result": "MATCH",
16 "state": "COMPLETED",
17 "systemStatus": "VALID",
18 "objectType": "DATE_OF_BIRTH",
19 "...": "..."
20 },
21 {
22 "class": "KYC",
23 "providerResult": { "name": "MANUAL", "reference": "Jane Doe (Officer #1234)" },
24 "result": "MATCH",
25 "state": "COMPLETED",
26 "systemStatus": "VALID",
27 "objectType": "DOCUMENT",
28 "...": "..."
29 }
30 ],
31 "requestId": "req_01HBFBCJ5P6Q7R8S9T0V1W2X3Y"
32}

Step 2: Execute the Verification Workflow

With the manual approval logged, you can now execute your standard verification workflow. The Manual KYC step in this workflow will automatically detect the PROs created in Step 1 and pass.

cURL
1--location --request POST '[https://api.frankieone.com/v2/individuals/](https://api.frankieone.com/v2/individuals/){{entityId}}/serviceprofiles/{{serviceName}}/workflows/{{workflowName}}/execute' \
2--header 'api_key: {{your_api_key}}' \
3--header 'X-Frankie-CustomerID: {{your_customer_id}}'

In the workflow execution response, you will see the Manual KYC step result. Look for provider: “MANUAL” and a result of MATCH or PASS to confirm success.

JSON
1{
2 "workflowResult": {
3 "...": "...",
4 "workflowStepResults": [
5 {
6 "stepName": "Manual KYC",
7 "result": "MATCH",
8 "serviceProviders": [
9 {
10 "provider": "MANUAL",
11 "result": "PASS",
12 "...": "..."
13 }
14 ],
15 "...": "..."
16 }
17 ]
18 }
19}

Here is an example configuration:

JSON
1{
2 "requirements": [
3 {"name": 1, "dateOfBirth": 1, "primaryPhotographic": 1},
4 {"name": 1, "address": 1, "primaryPhotographic": 1},
5 {"name": 1, "dateOfBirth": 1, "address": 1, "primaryNonPhotographic": 2},
6 {"name": 1, "dateOfBirth": 1, "address": 1, "primaryNonPhotographic": 1, "secondary": 1}
7 ],
8 "countries": {
9 "AUS": [
10 {
11 "type": "primaryPhotographic",
12 "documentTypes": ["DRIVERS_LICENSE", "PASSPORT"]
13 },
14 {
15 "type": "primaryNonPhotographic",
16 "documentTypes": ["BIRTH_CERT", "CITIZENSHIP_CERT"]
17 },
18 {
19 "type": "secondary",
20 "documentTypes": ["UTILITY_BILL", "BANK_STATEMENT"]
21 }
22 ]
23 }
24}

In this example, to manually approve an Australian entity, you could satisfy the policy by providing a name, date of birth, and a passport.

Invalidating Manual Results

If you need to revert a manual approval (e.g., to perform a new electronic check), you can invalidate all existing manual results for an entity.

Call the POST /v2/individuals/{entityId}/results/mkyc/invalidate endpoint. This will mark all existing manual PROs as invalid, causing any subsequent Manual KYC workflow steps to fail until a new manual approval is logged.

cURL
1--POST '[https://api.frankieone.com/v2/individuals/](https://api.frankieone.com/v2/individuals/){{entityId}}/results/mkyc/invalidate' \
2--header 'api_key: {{your_api_key}}' \
3--header 'X-Frankie-CustomerID: {{your_customer_id}}' \
4--header 'Content-Type: application/json' \
5--data ''