/check_kyc

Returns whether entity attached to user handle is verified, not valid, or still pending.

This endpoint should be run after successfully completing /register and /request_kyc calls.

Since ID verification can take some time (on average it takes 33 seconds, but occasionally it can take longer), /request_kyc will never confirm in its response that an entity was verified. We recommend configuring a webhook in the developer console to be notified of state changes, as the /check_kyc endpoint should never be polled.

For more information about how to take advantage Sila's webhooks, visit KYC Status Update Event.

🚧

Triaging KYC Failures

Some users will fail their KYC or KYB evaluation. If you intend to help these users become transactional on your platform you will need to implement a KYC or KYB flow that enables you and them to triage the failures. For more details on that see Triaging KYC Failures

Requests

The request body at this endpoint is the header_msg JSON object.

The handle for which KYC confirmation is being checked should be in the header.user_handle field.

The optional kyc_level field is used to filter for verifications which only match the specified KYC level. When this filter is not present in /check_kyc, the overall top-level verification status reflects the last non-pending verification status for the current user, regardless of KYC level. If your application is approved for multiple KYC levels, you can check overall KYC results for a single level of KYC with:

"kyc_level": "YOUR_KYC_LEVEL_NAME"

as an optional key in your request. You don't need to use this if you only ever use one KYC level in your application or per user.

To view a user's full KYC verifications flow, you can request:

"kyc_level": "KYC-STANDARD"

Authorization / Authentication

Apps using Access Token Authorization

Use a valid access token in a Authorization: Bearer request header.

See Authenticating with an Access Token for more details.

Apps using ECDSA Authentication

Both authsignature and usersignature headers are required for this request. The usersignature header should be generated with a keypair registered to the user (either registered from the /register endpoint or the /register_wallet endpoint).

See the section on ECDSA Authentication for more detail about ECDSA signature generation.

Note - We recently renamed the field auth_handle to app_handle. For backward compatibility, auth_handle is still valid but has been removed from our documentation.

POST /0.2/check_kyc HTTP/1.1
sandbox.silamoney.com
Content-Type: application/json
// if using OAuth2
Authorization: Bearer [GENERATED JWT TOKEN HERE]
// if using ECDSA
authsignature: [GENERATED AUTHSIGNATURE HEX STRING HERE]
usersignature: [GENERATED USERSIGNATURE HEX STRING HERE]

{
  "header": {
    "created": 1234567890, 
    "app_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "<your unique id>"
  }, 
  "message": "header_msg"
}

***

HTTP/1.1 200 OK

{
  "success": true,
  "status": "SUCCESS",
  "message": "user has passed ID verification!",
  "response_time_ms": "171",
  "reference": "<your unique id>",
  "entity_type": "individual",
  "verification_status": "passed",
  "documents_required_verification_ids": [
        "616e7d20-1f65-4318-8f1c-880f191cefab",
        "616e7d20-1f65-4318-8f1c-880f191cefac",
    ],  
  "verification_history": [
    {
      "verification_id": "616e7d20-1f65-4318-8f1c-880f191cefab",
      "verification_status": "passed",
      "kyc_level": "KYC-STANDARD",
      "requested_at": 1592339985,
      "updated_at": 1592340016,
      "reasons": [],
      "tags": [
        "KYC Name Match",
        "KYC SSN Match",
        "KYC DOB Match",
        "Phone Match",
        "KYC Address Match"
      ],
      "score": 0.99,
      "parent_verification": null
    }
  ],
  "valid_kyc_levels": [
      "KYC-STANDARD"
  ]
}

---

{
  "success": false,
  "status": "FAILURE",
  "message": "ID verification was not requested for user.",
  "reference": "ref",
  "entity_type": "individual",
  "verification_status": "unverified",
  "verification_history": [],
  "valid_kyc_levels": [
    "KYC-STANDARD"
  ]
}

---

{
  	"success": false,
    "status": "FAILURE",
    "message": "user is pending ID verification.",
    "reference": "ref",
    "entity_type": "individual",
    "verification_status": "pending",
    "documents_required_verification_ids": [],
    "verification_history": [
        {
            "verification_id": "9137dc67-978f-48cb-a44b-f6805f6954c4",
            "verification_status": "pending",
            "kyc_level": "KYC-STANDARD",
            "requested_at": 1592338961,
            "updated_at": 1592338961,
            "reasons": [],
            "tags": [],
            "documents_required_details_url": null,
            "score": null,
            "parent_verification": null
        }
    ],
    "valid_kyc_levels": [
        "KYC-STANDARD"
    ]
}

---

{
  	"success": false,
    "status": "FAILURE",
    "message": "user has failed ID verification.",
    "reference": "",
    "entity_type": "individual",
    "verification_status": "failed",
    "documents_required_verification_ids": ["2f5dc7de-5268-40e3-b39e-ac50535ef879"],
    "verification_history": [
        {
            "verification_id": "2f5dc7de-5268-40e3-b39e-ac50535ef879",
            "verification_status": "failed",
            "kyc_level": "KYC-STANDARD",
            "requested_at": 1592341803,
            "updated_at": 1592341815,
            "reasons": [],
            "tags": [
              "Address Not Matched", "Address Not Verified",
              "Name Mismatch","Name Not Verified",
              "DOB Miskey", "DOB Not Verified",
              "SSN Miskey", "SSN Not Verified"
            ],
            "documents_required_details_url": "https://api.silamoney.com/0.2/check_kyc/2f5dc7de-5268-40e3-b39e-ac50535ef879/required_document_types",
            "score": 0.10,
            "parent_verification": null
        }
    ],
    "valid_kyc_levels": [
        "KYC-STANDARD"
    ]
}
***
POST /0.2/check_kyc HTTP/1.1
Host: sandbox.silamoney.com
authsignature: [GENERATED AUTHSIGNATURE HEX STRING HERE]
usersignature: [GENERATED USERSIGNATURE HEX STRING HERE]
Content-Type: application/json

{
  "header": {
    "created": 1234567890, 
    "app_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "<your unique id>"
  }, 
  "message": "header_msg",
  "kyc_level": "KYC-STANDARD"
}

HTTP/1.1 200 OK
***
{
    "success": true,
    "message": "user has passed ID verification!",
    "reference": "23e74fa4-9419-429d-9365-85a4d27d0406",
    "entity_type": "individual",
    "verification_status": "passed",
    "documents_required_verification_ids": [],
    "verification_history": [
        {
            "verification_id": "2881d961-66c8-43a7-8319-03b06e21fb82",
            "verification_status": "passed",
            "kyc_level": "KYC-STANDARD",
            "requested_at": 1637140009,
            "updated_at": 1637140009,
            "reasons": [],
            "tags": [],
            "documents_required_details_url": null,
            "score": null,
            "parent_verification": null
        }
    ],
    "valid_kyc_levels": [
        "KYC-STANDARD"
    ],
    "status": "SUCCESS"
}
***

HTTP/1.1 200 OK
***
{
    "success": false,
    "message": "ID verification was not requested for user.",
    "reference": "fedb0464-5a66-4ceb-a789-bd5e3833943d",
    "entity_type": "individual",
    "verification_status": "unverified",
    "documents_required_verification_ids": [],
    "verification_history": [],
    "valid_kyc_levels": [
        "KYC-STANDARD",
        "KYB-STANDARD",
    ],
    "status": "FAILURE"
}
POST /0.2/check_kyc HTTP/1.1
Host: sandbox.silamoney.com
authsignature: [GENERATED AUTHSIGNATURE HEX STRING HERE]
Content-Type: application/json

{
  "header": {
    "created": 1234567890,
    "auth_handle": "your_app_handle.silamoney.eth",
    "user_handle": "your_business_user.silamoney.eth"
  }
}

***

{
    "status": "FAILURE",
    "message": "your_business_user is pending ID verification.",
    "reference": "ref",
    "entity_type": "business",
    "verification_status": "pending",
    "verification_history": [
        {
            "verification_id": "1802c2a5-1d1e-48a3-9af4-d7189934de9e",
            "verification_status": "pending",
            "kyc_level": "KYB-STANDARD",
            "requested_at": 1592946326,
            "updated_at": 1592946334,
            "reasons": [],
            "tags": [
                "Address Matched",
                "FEIN Found",
                "Company Name Verified",
                "Phone Matched",
                "Representative Match"
            ],
            "score": 0.9,
            "parent_verification": null
        }
    ],
    "valid_kyc_levels": [
        "KYB-STANDARD"
    ],
    "certification_status": "certification_pending",
    "certification_history": [],
    "members": [
        {
            "user_handle": "your_individual_user",
            "first_name": "Individual",
            "last_name": "User",
            "role": "controlling_officer",
            "details": "CEO",
            "ownership_stake": null,
            "verification_status": "passed",
            "verification_required": true,
            "verification_id": "e72e7961-5924-4534-98d7-09d89f804762",
            "beneficial_owner_certification_status": "certification_not_required",
            "business_certification_status": "certification_not_required"
        },
        {
            "user_handle": "your_individual_user",
            "first_name": "Individual",
            "last_name": "User",
            "role": "beneficial_owner",
            "details": "Private investor",
            "ownership_stake": 66.7,
            "verification_status": "passed",
            "verification_required": true,
            "verification_id": "e72e7961-5924-4534-98d7-09d89f804762",
            "beneficial_owner_certification_status": "certification_pending",
            "business_certification_status": "certification_pending"
        }
    ]
}

---

{
    "status": "SUCCESS",
    "message": "your_business_user has passed ID verification!",
    "reference": "",
    "entity_type": "business",
    "verification_status": "passed",
    "verification_history": [
        {
            "verification_id": "1802c2a5-1d1e-48a3-9af4-d7189934de9e",
            "verification_status": "passed",
            "kyc_level": "KYB-STANDARD",
            "requested_at": 1592946326,
            "updated_at": 1592949479,
            "reasons": [],
            "tags": [
                "Address Matched",
                "FEIN Found",
                "Company Name Verified",
                "Phone Matched",
                "Representative Match"
            ],
            "score": 0.9,
            "parent_verification": null
        }
    ],
    "valid_kyc_levels": [
        "KYB-STANDARD"
    ],
    "certification_status": "certified",
    "certification_history": [
        {
            "administrator_user_handle": "your_individual_user",
            "created": "2020-06-23T21:57:59.322388+00:00",
            "created_epoch": 1592949479.322388,
            "expires_after": null,
            "expires_after_epoch": null,
            "beneficial_owner_certifications": [
                "kyb-test-1-individual"
            ]
        }
    ],
    "members": [
        {
            "user_handle": "your_individual_user",
            "first_name": "Individual",
            "last_name": "User",
            "role": "controlling_officer",
            "details": null,
            "ownership_stake": null,
            "verification_status": "passed",
            "verification_required": true,
            "verification_id": "e72e7961-5924-4534-98d7-09d89f804762",
            "beneficial_owner_certification_status": "certification_not_required",
            "business_certification_status": "certification_not_required"
        },
        {
            "user_handle": "your_individual_user",
            "first_name": "Individual",
            "last_name": "User",
            "role": "beneficial_owner",
            "details": "Private investor",
            "ownership_stake": 66.7,
            "verification_status": "passed",
            "verification_required": true,
            "verification_id": "e72e7961-5924-4534-98d7-09d89f804762",
            "beneficial_owner_certification_status": "certified",
            "business_certification_status": "certified"
        }
    ]
}
const kycLevel = 'DOC_KYC' //Alternative kyc_leve if approved for iACH product:  INSTANT-ACHV2 - see KYC/KYB level docs

const res = await Sila.checkKYC(userHandle, walletPrivateKey, kycLevel);

// Success Response Object
console.log(res.statusCode); // 200
console.log(res.data.reference); // Random reference number
console.log(res.data.status); // SUCCESS
console.log(res.data.message); // User has passed ID verification
payload={

        "user_handle": "user.silamoney.eth"    #Required
    }

User.checkKyc(silaApp,payload,user_private_key)

### Success Response Object
{
    status: 'SUCCESS',
    message: 'Kyc passed for user.silamoney.eth',
}

### Failure Response Object
{
    status: 'FAILURE',
    message: 'error',
}
String kycLevel="DOC_KYC"; //Alternative kyc_leve if approved for iACH product:  INSTANT-ACHV2 - see KYC/KYB level docs
ApiResponse response = api.checkKYC("user handle", "user private key",kycLevel);

CheckKycResponse parsedResponse = (CheckKycResponse) response.getData();

parsedResponse.getStatus();
parsedResponse.getEntityType();
parsedResponse.getVerificationStatus();
parsedResponse.getVerificationHistory();
parsedResponse.getCertificationStatus();
parsedResponse.getCertificationHistory();
parsedResponse.getMembers();
$userHandle = 'user.silamoney.eth';
$userPrivateKey = 'some private key'; // Hex format
$kycLevel = 'DOC_KYC'; // Alternative kyc_leve if approved for iACH product:  INSTANT-ACHV2 - see KYC/KYB level docs
$response = $client->checkKYC($userHandle, $userPrivateKey);

//or with $kycLevel
$response = $client->checkKYC($userHandle, $userPrivateKey, $kycLevel);

// Success 200
echo $response->getStatusCode(); // 200
echo $response->getData()->reference; // Random reference number
echo $response->getData()->status; // SUCCESS
echo $response->getData()->message; // User has passed ID verification!
echo $response->getData()->entity_type; // individual
echo $response->getData()->verification_status; // passed
echo $response->getData()->verification_history; // An array of all the verifications executed for the user (verification status, kyc level...)
echo $response->getData()->valid_kyc_levels; // An array of kyc levels valid for the user

// Additional business values
echo $response->getData()->certification_status; // certified
echo $response->getData()->certification_history; // An array of all the certifications executed for the business (administrator user handle, created, expires after...)
echo $response->getData()->members; // An array of users linked to the business and their verification and certification status (user handle, role, beneficial owner certification status...)
string kycLevel = "DOC_KYC"; // Alternative kyc_leve if approved for iACH product:  INSTANT-ACHV2 - see KYC/KYB level docs
ApiResponse<object> response = api.CheckKYC(userHandle, walletPrivateKey, kycLevel);

// Success Response Object
Console.WriteLine(response.StatusCode); // 200
var parsedResponse = (CheckKYCResponse)response.Data;
Console.WriteLine(parsedResponse.Reference); // Random reference number
Console.WriteLine(parsedResponse.Status); // SUCCESS
Console.WriteLine(parsedResponse.Message); // user has passed ID verification!
Console.WriteLine(parsedResponse.EntityType); // individual|business
Console.WriteLine(parsedResponse.VerificationStatus); // passed
Console.WriteLine(parsedResponse.VerificationHistory); // A list of verification results
Console.WriteLine(parsedResponse.VerificationHistory[0].KYCLevel); // INSTANT-ACHv2
Console.WriteLine(parsedResponse.ValidKYCLevels); // List of KYC levels [DEFAULT, ...]
KeyTypeDescription
headerJSON objectRequired. Requires these keys in JSON format: created, app_handle, user_handle. See the /check_handle endpoint for the complete list of fields in this object.
entity_typeStringOptional. The optional entity_type field is used to filter. Choose 'individual' or 'business' only. Example: individual
kyc_levelStringOptional. The kyc_level field is used to filter for verifications which only match the specified KYC level.

Responses

There are several new keys in the /check_kyc response:

  • entity_type: Value will always be "individual" for individual users.
  • verification_status: Describes the current state of an entities KYC evaluation. For instance, "passed" or "review". There are descriptions of these statuses in the table below. NOTE: More verification statuses than these may be added in the future, so please implement accordingly.
  • documents_required_verification_ids: A list of verification ids of records that need documents submitted to pass KYC/KYB.
  • verification_history: The value at this key is an array of 0 or more verification objects. All objects in this array have the following keys:
    • verification_id: A UUID identifying the verification run for this user.
    • verification_status: The same values are allowed here as in the overall verification status, which aggregates results from 0 or more verifications. (The overall top-level verification status reflects the last non-pending verification status for the current user.)
    • kyc_level: The level of verification used. By default, this is "DEFAULT" for individuals; if a custom KYC level was requested, that value will be here instead.
    • requested_at: An epoch timestamp (integer value in seconds) describing when this verification was requested.
    • updated_at: An epoch timestamp (integer in seconds) describing when this verification was last updated with new data or a new status.
    • reasons: An array of reason codes (strings) for failing a verification; this is usually empty if the user has passed.
    • tags: An array of descriptive tags (strings) about the verification results.
    • documents_required_details_url: The URL to which a request can be sent to get a list of documents needed for submission to pass KYC/KYB.
      Note - This url is current not compatible with any Sila SDKs. Please use the /document_types endpoint as an alternative to the documents_required_details_url.
    • score: A nullable float value between 0 and 1. If null, no score has yet been computed.
    • parent_verification: Always null for now; reserved for future use.
    • valid_kyc_levels: An array of KYC level names that can be requested for this user. All verifications with any of these KYC levels for the current user will be included in the verification history and used to compute the overall verification status.

❗️

/check_kyc response tags for failures

When entities fail KYC some portion of the identity needs to be verified (so-called IDV). Below are links to which documents your users must provide in order to verify their identity based on the failure response attribute, tags.
See Triaging KYC Failures for more details.

Indviduals:

Businesses:

📘

Testing the triaging KYC failures flow in SANDBOX

In sandbox only, you can test out the triaging KYC failure flow by registering a user with specific mock KYC data that will trigger a certain KYC failure tag. See the the testing docs for more information.

The /check_kyc response for business end-users has additional keys when compared to the response for individual end-users: certification_status, certification_history, and members.

  • certification_status: A string; value can be any of [“certified”, “certification_not_required”, “certification_pending”].
  • certification_history: An array of certification objects.
  • members: An array of members objects.

Each object in the certification_history array has keys like so:

KeyTypeDescription
administrator_user_handlestringThe handle of the linked administrator business member that requested the business certification.
createdstring (RFC3339-formatted timestamp)Timestamp of when business certification was created.
created_epochfloatEpoch timestamp of when business certification was created.
expires_afterstring (RFC3339-formatted timestamp, nullable)Timestamp of when business certification will expire. To be able to continue to transact, all linked beneficial owners need to be certified (/certify_beneficial_owner) and a new business certification will need to be created (/certify_business).
expires_after_epochfloatEpoch timestamp of when business certification will expire. To be able to continue to transact, all linked beneficial owners need to be certified (/certify_beneficial_owner) and a new business certification will need to be created (/certify_business).
beneficial_owner_certificationsarray of stringsArray of handles of beneficial owners that were individually certified and included in the latest business certification.

Each object in the members array has keys like so:

KeyTypeDescription
user_handlestringThe handle of the linked business member.
first_namestringThe first name of the linked business member as registered.
last_namestringThe last name of the linked business member as registered.
rolestringThe machine-readable business role name of this member. (If one member has multiple roles, then the same user will be in multiple objects in the members array).
detailsstring (nullable)The optional details string as sent in the original /link_business_member request.
ownership_stakefloat (nullable)The ownership stake (valid value 0 < value <= 100) as registered in the original /link_business_member request. This will only be non-null for beneficial owners.
verification_statusstringVerification status for individual, can be any one of [“passed”, “pending”, “unverified”, "review", or “failed”] for KYC Level STANDARD
and [“passed”, “pending”, “unverified”, "documents_required", or "documents_received"] for KYC Level DOC_KYC.
verification_requiredbooleanTrue if individual verification must be “passed” for the business to transition to “passed” (if not already “passed”), false otherwise. Verification is not required for users that only have the “administrator” role.
verification_idstring (UUID4)Unique identifier of the linked individual verification.
beneficial_owner_certification_statusstringCan be any one of [“certified”, “certification_pending”, “certification_not_required”]. Indicates that /certify_beneficial_owner has been successfully requested for this user.
business_certification_statusstringCan be any one of [“certified”, “certification_pending”, “certification_not_required”]. Indicates that the business certification generated in /certify_business includes the individual certification generated from /certify_beneficial_owner.

Verification Statuses

Verification StatusDescription
'unverified'entity has not had a KYC evaluation
'passed'entity has passed KYC
'pending'an entity's KYC evaluation is in progress
'review'documents are required to verify the entity.
'failed'documents are required to verify the entity. More likely to be fraud
'member_unverified'business member(s) has user has not had a KYC evaluation
'member_failed'documents are required to verify business members. More likely to be fraud
'member_review'documents are required to verify business members.
'member_pending'a business member's KYC evaluation is in progress
'documents_required'documents are required to verify the entity. Only applies to kyc_level: DOC_KYC
'documents_received'documents were received but not reviewed. Only applies to kyc_level: DOC_KYC
'webhook_pending'a webhook has not been received for an in-progress KYC evaluation
Status Codesuccess Attributeverification_status AttributeDescription
200true"passed"The user handle has successfully passed KYC verification.
200false"unverified"Verification has not been requested for this user.
200false"pending"The user is still pending KYC verification.
200false"failed"The user has failed KYC verification.
200false"documents_required"We require documents to be approved before passing verification.
200false"webhook_pending"Awaiting additional verification.
400falseN/ABad request - check message and/or validation_details keys for more information.
401falseN/Aauthsignature or usersignature header was absent or incorrect.