4. Performing KYC

What is KYC and why do you need it.

1127

After your Customer has provided the information to complete onboarding, you must authenticate and verify the information they've provided. This is a critical step, known as KYC, in which you validate your customer's identity and documents, and ensure they're compliant with federal regulations. This is performed using the KYC API.

To run the KYC process, you need the customer_id, your own authorization headers, and various personal information related to the customer.

Idempotency

📘

Note

The KYC endpoint is idempotent and repeated requests using the same Idempotency-Key within a 24 hour period will fail.

Once a customer has successfully passed the KYC process, no further KYC attempts are allowed. You are also not able to PATCH a customer's information once the KYC has passed. Any further call for KYC authentication responds with an error and returns the timestamp of the previously successful KYC process.

Idempotency is a Web API design principle that prevents you from running the same operation multiple times. Because a certain amount of intermittent failure is to be expected, you need a way to reconcile failed requests with a server, and idempotency provides a mechanism for that. Including an idempotency key (an optional string) makes POST requests idempotent, which prompts the API to do the record keeping required to prevent duplicate operations. You can safely retry requests that include an idempotency key as long as the second request occurs within 24 hours from when you first receive the key (keys expire after 24 hours).

KYC workflow

  1. Create a webhook to listen to KYC events.
  2. Submit a KYC request, an example of which is shown below.
curl  
--request POST \ 
--url 'https://sandbox.bond.tech/api/v0.1/customers/{CUSTOMER_ID}/verification-kyc' \
--header 'Identity: YOUR-IDENTITY' \
--header 'Authorization: YOUR-AUTHORIZATION' \
--header 'Content-Type: application/json' \
--data-raw '{
    "program_id": "b50063df-0b39-43f7-9458-25b08a75d42a",
    "ssn": "000-00-0000",
    "phone": "555-555-5555",
    "phone_country_code": "1",
    "email": "[email protected]",
    "ip": "127.1.1.1"
}
require "uri"
require "net/http"

url = URI("https://sandbox.bond.tech/api/v0.1/customers/{CUSTOMER_ID}/verification-kyc")

http = Net::HTTP.new(url.host, url.port);
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["Identity"] = YOUR-IDENTITY
request["Authorization"] = YOUR-AUTHORIZATION
request["Content-Type"] = "application/json"
request.body = "{\n    \"program_id\": \"b50063df-0b39-43f7-9458-25b08a75d42a\",\n    \"ssn\": \"000-00-0000\",\n    \"phone\": \"555-555-5555\",\n    \"phone_country_code\": \"1\",\n    \"email\": \"[email protected]\",\n    \"ip\": \"127.1.1.1\"\n}"

response = http.request(request)
puts response.read_body
const options = {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Identity: 'YOUR-IDENTITY',
    Authorization: 'YOUR-AUTHORIZATION'
  },
  body: JSON.stringify({
    program_id: '72585109-8222-4221-b15b-48e87ffed790',
    ssn: '123-45-6789',
    phone: '555-111-2222',
    phone_country_code: '1',
    email: '[email protected]',
    ip: '257.134.1.57'
  })
};

fetch('https://sandbox.bond.tech/api/v0.1/customers/931e2341-c3eb-4681-97d4-f6e09d90da14/verification-kyc', options)
  .then(response => response.json())
  .then(response => console.log(response))
  .catch(err => console.error(err));
import requests

url = "https://sandbox.bond.tech/api/v0.1/customers/{CUSTOMER_ID}/verification-kyc"

payload="{\n    \"program_id\": \"b50063df-0b39-43f7-9458-25b08a75d42a\",\n    \"ssn\": \"000-00-0000\",\n    \"phone\": \"555-555-5555\",\n    \"phone_country_code\": \"1\",\n    \"email\": \"[email protected]\",\n    \"ip\": \"127.1.1.1\"\n}"
headers = {
  'Identity': YOUR-IDENTITY,
  'Authorization': YOUR-AUTHORIZATION,
  'Content-Type': 'application/json'
}

response = requests.request("POST", url, headers=headers, data = payload)

print(response.text.encode('utf8'))
var client = new RestClient("https://sandbox.bond.tech/api/v0.1/customers/{CUSTOMER_ID}/verification-kyc");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Identity", "e6b234b4-650e-48e4-93eb-6550a07cc075");
request.AddHeader("Authorization", "sasAXw8ElVJihL3+3mzItCsVtKzh4Kqa0xdECC/F1GbwA6LQTAs/KxkZ9QFYST3l");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n    \"program_id\": \"b50063df-0b39-43f7-9458-25b08a75d42a\",\n    \"ssn\": \"000-00-0000\",\n    \"phone\": \"555-555-5555\",\n    \"phone_country_code\": \"1\",\n    \"email\": \"[email protected]\",\n    \"ip\": \"127.1.1.1\"\n}",  ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://sandbox.bond.tech/api/v0.1/customers/{CUSTOMER_ID}/verification-kyc")
  .header("Identity", "e6b234b4-650e-48e4-93eb-6550a07cc075")
  .header("Authorization", "sasAXw8ElVJihL3+3mzItCsVtKzh4Kqa0xdECC/F1GbwA6LQTAs/KxkZ9QFYST3l")
  .header("Content-Type", "application/json")
  .body("{\n    \"program_id\": \"b50063df-0b39-43f7-9458-25b08a75d42a\",\n    \"ssn\": \"000-00-0000\",\n    \"phone\": \"555-555-5555\",\n    \"phone_country_code\": \"1\",\n    \"email\": \"[email protected]\",\n    \"ip\": \"127.1.1.1\"\n}")
  .asString();
  1. The Bond platform responds with a POST request containing submitted to your callback URL, as in the example below. The result of the KYC request comes via the webhook.
  {
      "customer_id": "2df10ec1-130f-41bb-b0cf-f3af48350eb7",
      "kyc_status": "submitted"
  }

Once the KYC process is successful, you receive a webhook containing customer_id and an event of kyc.verification.success, as shown in the example below:

   {
       "event": "kyc.verification.success",
       "customer_id": "a5bcf5a8-c4e0-4025-8183-5346176ee3db",
       "occurred_at": "2021-02-02-00:50:58.484840+00:00"
   }

📘

Note

Most of a customer's details can't be updated after they've passed KYC as the new information needs to be verified before the update can occur. If you need to update information for a customer that has passed KYC, contact Bond directly.
For details, see Updating a customer.

Invalid requests to run KYC

An example of a repeat request made with the same idempotency key within a 24 period, and an example of a request with missing fields is shown below.

409
{
       "type": "RESOURCE_CONFLICT",
       "code": "idempotency_key_exists",
       "message": "A request was made with this idempotency key in the past 24 hours",
   }
400
{
'Message': {ssn: ['Missing data for required field.']},
 'Status': 400,
 'Code': 'kyc_post_schema',
 'Type': 'Request Error'
}