KYC/KYB Verification

US banking regulations require banks and other financial institutions to collect and verify information about the customers they do business with. These regulations require the establishment of a Customer Identification Program (CIP), commonly referred to as: know your customer (KYC) and know your business (KYB). These programs require:

  • Data Collection: name, date of birth, address, and government issued ID.
  • Disclosures: notifying customers about the collection and retention of data.
  • Verification: verifying that the information collected is current, valid, and up-to-date.
  • On-going monitoring: verifying customer is not on a known watchlist.

πŸ“˜

In order to move money all customers are required to undergo KYC or KYB verification.

Synctera's verification solution provides identity and watchlist monitoring for personal and business customers. In this article, we'll dive into what a verification is and how to manage the KYC and KYB process for your customers.

See the API reference for more information on managing customer verifications.

Prerequisites

This guide assumes that you have:

Verifications and the verification object

Synctera represents KYC and KYB verifications using the verification object. A verification object represents a category of checks that were performed on a customer. The example below shows an IDENTITY verification for a personal customer.

{
  "id": "05e2ddf3-d172-450e-9cf3-7a34f76a414f",
  "person_id": "7ef75751-e372-4c12-9b02-b9e4b1faaac9",
  "verification_type": "IDENTITY",
  "result": "ACCEPTED",
  "details": [
    {
      "description": "Full name, address, and SSN/ITIN can be resolved to the individual",
      "label": "Customer Identification Program (CIP)",
      "result": "PASS"
    },
    {
      "description": "Address can be resolved to the individual",
      "label": "Address",
      "result": "PASS"
    },
    {
      "description": "Email address is more than 2 years old",
      "label": "Email",
      "result": "PASS"
    }
  ],
  "verification_time": "2022-03-14T18:34:59.91272Z",
  "creation_time": "2022-03-14T18:34:59.918188Z",
  "last_updated_time": "2022-03-14T18:34:59.918188Z"
}

An IDENTITY verification encompasses all of the the individual checks that were done pertaining to the customer's identity. If we take a look at the details array we see the individual checks done in verifying the customer's identity. In this case we see the name, address, SSN, and email were all verified by Synctera's KYC provider.

Similarly, watchlist checks are represented by the WATCHLIST verification type.

{
  "id": "a24a16a2-4711-4486-8049-787462c61ffc",
  "person_id": "7ef75751-e372-4c12-9b02-b9e4b1faaac9",
  "verification_type": "WATCHLIST",
  "result": "ACCEPTED",
  "details": [
    {
      "description": "Global Watchlist sources selected are not correlated with the input identifiers",
      "label": "Watchlist",
      "result": "PASS"
    }
  ],
  "verification_time": "2022-03-14T18:34:59.91272Z",
  "creation_time": "2022-03-14T18:34:59.918188Z",
  "last_updated_time": "2022-03-14T18:34:59.918188Z"
}

See the API reference for more information about customer verifications.

Verification status and verifying customers

A customer's verification status is the outcome of all verifications done on the customer. All new customers are created with a verification status of UNVERIFIED. The verification status field is available on the person and business resources (see the API reference for persons and businesses).

Once all of the required information has been collected, you can initiate a verification request using the verify endpoint and the customer's ID.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/verifications/verify \
  --data-binary '
  {
    "person_id": "7ef75751-e372-4c12-9b02-b9e4b1faaac9",
    "customer_ip_address": "184.233.47.237",
    "customer_consent": true
  }'

To verify a business customer, specify business_id instead of person_id:

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/verifications/verify \
  --data-binary '
  {
    "business_id": "eaa9807f-8cda-4308-8244-90c11b1b43a5",
    "customer_ip_address": "184.233.47.237",
    "customer_consent": true
  }'

A successful verification request will result in the customer being moved from UNVERIFIED into one of the following statuses:

  • PENDING – verification is in progress for this customer.
  • PROVISIONAL – partially verified or verified with restrictions.
  • ACCEPTED – the customer has been verified.
  • REVIEW – verification has run and issues have been identified and require review.
  • VENDOR_ERROR – verification did not successfully run due to an unexpected error or failure.
  • REJECTED – the customer was rejected and should not be allowed to take certain actions e.g., open an account.

Any time a customer is moved into a verification status other than ACCEPTED, a case will be created in the Synctera Case Manager so that their profile can be manually reviewed by a compliance officer. As previously mentioned, a customer cannot move money unless their verification status is ACCEPTED.

Suggested flow for customer verification:

  • ACCEPTED – continue with your onboarding flow (e.g. create an account).
  • REVIEW – notify the user that their application is under manual review. You can continue onboarding the user but should not open an account yet. Once the case is resolved, you will either: let the user know that their application has been turned down (if REJECTED); or proceed to account creation (if ACCEPTED).
  • REJECTED – notify the applicant that their application has been turned down. Stop the applicant from going through the rest of the flow.
  • VENDOR_ERROR – Retry the call via API. Then follow the REVIEW outcome if the issue is not resolved.

If the user is not initially accepted, we recommend the following:

  • First, offer the user a chance to verify that the information they entered is correct, and allow them to update any fields as needed.
  • When the user has reviewed and corrected their information, you should call POST /v0/verifications/verify again to initiate a second verification request.
  • You may call our verification endpoint with the customer's government ID using document verification.
  • If they do not make any changes, you should not call KYC/KYB a second time. Instead, tell them that their case will be reviewed.
  • If they make changes and are still not accepted, we suggest that you stop the process and let their case be manually reviewed.

πŸ“˜

There are two statuses that fall outside the typical integration path:

  • PENDING – when verifying a businesses the results may not be immediately available. Consider subscribing to the BUSINESS.VERIFICATION_OUTCOME.UPDATED webhook.
  • PROVISIONAL – a special verification status that indicates an entity has been partially verified.

Example: Create a personal customer that can open an account

Integration Steps

  1. Create a personal customer
  2. Create a KYC data collection disclosure
  3. Verify the customer

1. Create a personal customer

First we start by creating a record for our new customer. We'll use the POST /persons endpoint to create a person.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/persons \
  --data-binary '
  {
    "first_name": "Christopher",
    "middle_name": "James",
    "last_name": "Albertson",
    "dob": "1985-06-14",
    "email": "[email protected]",
    "phone_number": "+16045551212",
    "ssn": "456-78-9999",
    "legal_address": {
      "address_line_1": "123 Main St.",
      "city": "Beverly Hills",
      "state": "CA",
      "postal_code": "90210",
      "country_code": "US"
    },
    "is_customer": true,
    "status": "ACTIVE"
  }'

For more information about creating and managing people consult the person guide.

2. Create a KYC data collection disclosure

Once we have our created customer, you will need to display a disclosure to your customer that you are collecting personal data that will be shared with a third-party for the purpose of verifying their identity. For this we use the disclosures resource.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/disclosures \
  --data-binary '
  {
    "person_id": "7ef75751-e372-4c12-9b02-b9e4b1faaac9",
    "type": "KYC_DATA_COLLECTION",
    "version": "1.0",
    "event_type": "ACKNOWLEDGED",
    "disclosure_date": "2022-03-17T17:04:34Z"
  }'

For more information about creating and managing disclosures consult the disclosure guide.

3. Verify the customer

Now that we have a customer, and consent to collect and share their data we can verify this customer.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/verifications/verify \
  --data-binary '
  {
    "person_id": "7ef75751-e372-4c12-9b02-b9e4b1faaac9",
    "customer_ip_address": "184.233.47.237",
    "customer_consent": true
  }'

πŸ“˜

Consent must come directly from the customer.

Response

The response will contain:

  • an overall outcome, called verification_status
  • an array of all of the verifications performed, each with a result
{
  "verification_status": "ACCEPTED",
  "verifications": [
    {
      "id": "05e2ddf3-d172-450e-9cf3-7a34f76a414f",
      "person_id": "7ef75751-e372-4c12-9b02-b9e4b1faaac9",
      "verification_type": "IDENTITY",
      "result": "ACCEPTED",
      "details": [
        {
          "description": "Full name, address, and SSN/ITIN can be resolved to the individual",
          "label": "Customer Identification Program (CIP)",
          "result": "PASS"
        },
        {
          "description": "Address can be resolved to the individual",
          "label": "Address",
          "result": "PASS"
        },
        {
          "description": "Email address is more than 2 years old",
          "label": "Email",
          "result": "PASS"
        }
      ],
      "verification_time": "2022-03-14T18:34:59.91272Z",
      "creation_time": "2022-03-14T18:34:59.918188Z",
      "last_updated_time": "2022-03-14T18:34:59.918188Z"
    },
    {
      "id": "a24a16a2-4711-4486-8049-787462c61ffc",
      "person_id": "7ef75751-e372-4c12-9b02-b9e4b1faaac9",
      "verification_type": "WATCHLIST",
      "result": "ACCEPTED",
      "details": [
        {
          "description": "Global Watchlist sources selected are not correlated with the input identifiers",
          "label": "Watchlist",
          "result": "PASS"
        }
      ],
      "verification_time": "2022-03-14T18:34:59.91272Z",
      "creation_time": "2022-03-14T18:34:59.918188Z",
      "last_updated_time": "2022-03-14T18:34:59.918188Z"
    }
  ]
}

See the API reference for more information about customer verifications.

Great! We have successfully created and verified a personal customer. You can now visit our account creation guide.

Example: Create a business customer that can open an account

Before we create an account, we must first complete our due diligence on the business. In this guide, we'll focus on modeling the example flow for the example corporation below, "Your New Business".

Example corporation

%%{init: {"fontFamily": "sans-serif"}}%%
graph TD
    A[Beneficial Owner] -->B(Your New Business)

Integration Steps

  1. Create a business customer: Your New Business
  2. Create a beneficial owner
  3. Create all necessary disclosures
  4. Verify the business

1. Create a business customer: Your New Business

First we start by creating a record for our new business customer. We'll use the POST /businesses endpoint to create a business.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/businesses \
  --data-binary '
  {
    "entity_name": "Your New Business",
    "website": "https://example.com",
    "phone_number": "+16045551212",
    "legal_address": {
      "address_line_1": "123 Main St.",
      "city": "San Francisco",
      "state": "CA",
      "postal_code": "94105",
      "country_code": "US"
    },
    "structure": "CORPORATION",
    "formation_date": "2000-01-01",
    "formation_state": "DE",
    "ein": "99-9999999",
    "is_customer": true,
    "status": "ACTIVE"
  }'

2. Create a beneficial owner

Next, we need to represent the beneficial owner of the business. To do this, we'll create a new person using the POST /persons endpoint.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/persons \
  --data-binary '
  {
    "first_name": "Christopher",
    "middle_name": "James",
    "last_name": "Albertson",
    "dob": "1985-06-14",
    "email": "[email protected]",
    "phone_number": "+16045551212",
    "ssn": "456-78-9999",
    "legal_address": {
      "address_line_1": "456 Main St.",
      "city": "San Francisco",
      "state": "CA",
      "postal_code": "94105",
      "country_code": "US"
    },
    "is_customer": false,
    "status": "ACTIVE"
  }'

The response body to this request will contain the id of the newly created person. Use this id to create a relationship between the person and the original business by calling the POST /relationships endpoint using the BENEFICIAL_OWNER_OF relationship type.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/relationships \
  --data-binary '
  {
    "from_person_id": <ID of beneficial owner>,
    "relationship_type": "BENEFICIAL_OWNER_OF",
    "to_business_id": <ID of Your New Business>,
    "additional_data": {
      "percent_ownership": 50
    }
  }'

3. Create all necessary disclosures

Prior to verifying our business and related owners we must create KYC data collection disclosures for each of the owners.

For more information about creating and managing disclosures, see the disclosure guide.

4. Verify the business

At this point we have collected all of the required information to verify our original business and all of the related officers and owners.

Verifying our business and all of the related entities is as easy as making a request to POST /v0/verifications/verify that specifies the business to verify:

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/verifications/verify \
  --data-binary '
  {
    "business_id": <ID of Your New Business>,
    "customer_consent": true
  }'

πŸ“˜

Verifying a business customer using the POST /verifications/verify endpoint initiates the KYC and KYB process for all entities: the original business and the beneficial owner.

See the API reference for more information about business verifications.

Great! We have successfully created and verified a business customer. You can now visit our account creation guide.

Example: Create a business customer with a more complex ownership structure

​To satisfy regulatory requirements, we must collect business registration information and the ownership structure including: beneficial owners, holding corporations, officers, and directors of the business.

Before we create an account, we must first complete our due diligence on the business. In this guide, we'll focus on modeling the example flow for the example corporation below, "Your New Business".

Example corporation

%%{init: {"fontFamily": "sans-serif"}}%%
graph TD
    D[Owner] --> C
    A[Officer] -->B(Holding Company)
    B --> C(Your New Business)

Integration Steps

  1. Create a business customer: Your New Business
  2. Create a beneficial owner
  3. Create Holding Company (another business, but not a customer)
  4. Create an officer of Holding Company
  5. Create all necessary disclosures
  6. Verify the business

1. Create a business customer: Your New Business

First we start by creating a record for our new business customer. We'll use the POST /businesses endpoint to create a business.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/businesses \
  --data-binary '
  {
    "entity_name": "Your New Business",
    "website": "https://example.com",
    "phone_number": "+16045551212",
    "legal_address": {
      "address_line_1": "123 Main St.",
      "city": "San Francisco",
      "state": "CA",
      "postal_code": "94105",
      "country_code": "US"
    },
    "structure": "CORPORATION",
    "formation_date": "2000-01-01",
    "formation_state": "DE",
    "ein": "99-9999999",
    "is_customer": true,
    "status": "ACTIVE"
  }'

πŸ“˜

We indicate that this business is intended to be a customer by setting the "is_customer" parameter to true.

For more information about creating and managing businesses consult the business guide.

2. Create a beneficial owner

Next, we need to represent the beneficial owner of the business. To do this, we'll create a new person using the POST /persons endpoint.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/persons \
  --data-binary '
  {
    "first_name": "Christopher",
    "middle_name": "James",
    "last_name": "Albertson",
    "dob": "1985-06-14",
    "email": "[email protected]",
    "phone_number": "+16045551212",
    "ssn": "456-78-9999",
    "legal_address": {
      "address_line_1": "456 Main St.",
      "city": "San Francisco",
      "state": "CA",
      "postal_code": "94105",
      "country_code": "US"
    },
    "is_customer": false,
    "status": "ACTIVE"
  }'

The response body to this request will contain the id of the newly created person. Use this id to create a relationship between the person and the original business by calling the POST /relationships endpoint using the BENEFICIAL_OWNER_OF relationship type.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/relationships \
  --data-binary '
  {
    "from_person_id": <ID of beneficial owner>,
    "relationship_type": "BENEFICIAL_OWNER_OF",
    "to_business_id": <ID of Your New Business>,
    "additional_data": {
      "percent_ownership": 50
    }
  }'

3. Create Holding Company (another business, but not a customer)

To represent the ownership structure of a business partially owned by another business, create another business using the POST /businesses endpoint.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/businesses \
  --data-binary '
  {
    "entity_name": "Holding Company",
    "website": "https://example.com",
    "phone_number": "+16045551212",
    "legal_address": {
      "address_line_1": "789 Main St.",
      "city": "San Francisco",
      "state": "CA",
      "postal_code": "94105",
      "country_code": "US"
    },
    "structure": "CORPORATION",
    "formation_date": "2000-01-01",
    "formation_state": "DE",
    "ein": "99-9999999",
    "is_customer": false,
    "status": "ACTIVE"
  }'

Next, you'll create an OWNER_OF relationship which represents one business owning another business.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/relationships \
  --data-binary '
  {
    "from_business_id": <ID of Holding Company>,
    "relationship_type": "OWNER_OF",
    "to_business_id": <ID of Your New Business>,
    "additional_data": {
      "percent_ownership": 50
    }
  }'

4. Create an officer of Holding Company

Because Holding Company owns a controlling portion of Your New Business, we must also model the relationship of the officers. Once again, we'll create a person using /persons with the information of the officer.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/persons \
  --data-binary '
  {
    "first_name": "Carol",
    "middle_name": "Ann",
    "last_name": "Albertson",
    "dob": "1985-06-14",
    "email": "[email protected]",
    "phone_number": "+16045551212",
    "ssn": "789-45-9999",
    "legal_address": {
      "address_line_1": "456 Main St.",
      "city": "San Francisco",
      "state": "CA",
      "postal_code": "94105",
      "country_code": "US"
    },
    "is_customer": false,
    "status": "ACTIVE"
  }'

The response body to this request will contain the id of the newly created officer. Use this id to create a relationship between the person and the original business by calling the POST /relationships endpoint using the MANAGING_PERSON_OF relationship type.

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/relationships \
  --data-binary '
  {
    "from_person_id": {ID of the officer},
    "relationship_type": "MANAGING_PERSON_OF",
    "to_business_id": {ID of Holding Company};,
    "additional_data": {
      "title": "OFFICER"
    }
  }'

5. Create all necessary disclosures

Prior to verifying our business and related owners we must create KYC data collection disclosures for each of the owners.

For more information about creating and managing disclosures, see the disclosure guide.

6. Verify the business

At this point we have collected all of the required information to verify our original business and all of the related officers and owners.

Verifying our business and all of the related entities is as easy as making a request to POST /v0/verifications/verify that specifies the business to verify:

curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/verifications/verify \
  --data-binary '
  {
    "business_id": <ID of Your New Business>,
    "customer_consent": true
  }'

πŸ“˜

Verifying a business customer using the POST /verifications/verify endpoint initiates the KYC and KYB process for all entities: the original business, holding company, officers, and the beneficial owners.

Response

The response will contain:

  • an overall outcome, called verification_status
  • an array of all of the verifications performed, each with a result
  • a RELATED_ENTITIES verification to represent the outcomes for the beneficial owner, holding company, and its officer.
{
  "verification_status": "ACCEPTED",
  "verifications": [
    {
      "id": "598dd41e-733c-4fee-b8e7-a71de41881ef",
      "business_id": "eaa9807f-8cda-4308-8244-90c11b1b43a5",
      "verification_type": "RELATED_ENTITIES",
      "result": "ACCEPTED",
      "verification_time": "2022-03-14T18:34:59.91272Z",
      "creation_time": "2022-03-14T18:34:59.918188Z",
      "last_updated_time": "2022-03-14T18:34:59.918188Z"
    },
    {
      "id": "05e2ddf3-d172-450e-9cf3-7a34f76a414f",
      "business_id": "eaa9807f-8cda-4308-8244-90c11b1b43a5",
      "verification_type": "IDENTITY",
      "result": "ACCEPTED",
      "details": [
        {
          "description": "Match identified to the submitted Business Name",
          "label": "Business Name",
          "result": "PASS"
        },
        {
          "description": "Match identified to the submitted Office Address",
          "label": "Office Address",
          "result": "PASS"
        }
      ],
      "verification_time": "2022-03-14T18:34:59.91272Z",
      "creation_time": "2022-03-14T18:34:59.918188Z",
      "last_updated_time": "2022-03-14T18:34:59.918188Z"
    },
    {
      "id": "a24a16a2-4711-4486-8049-787462c61ffc",
      "business_id": "eaa9807f-8cda-4308-8244-90c11b1b43a5",
      "verification_type": "WATCHLIST",
      "result": "ACCEPTED",
      "details": [
        {
          "description": "No Watchlist hits were identified",
          "label": "Watchlist",
          "result": "PASS"
        }
      ],
      "verification_time": "2022-03-14T18:34:59.91272Z",
      "creation_time": "2022-03-14T18:34:59.918188Z",
      "last_updated_time": "2022-03-14T18:34:59.918188Z"
    }
  ]
}

We have successfully created and verified a business customer with a more complex ownership structure. See the account creation guide for next steps.