Complete Know Your Customer (KYC) Verification
Overview
The Know Your Customer (KYC) API enables you to programmatically verify the information of users onboarding to your platform and ensure regulatory compliance. KYC verification of your users is required before they can use BitGo products on your platform.
KYC Webhooks
You can set up webhooks to keep you informed throughout the KYC process. See the Create Enterprise Webhooks guide for more information.
Prerequisites
1. Submit KYC
Submit basic KYC information for your user. If necessary, uploading supporting documents occurs in the next step.
Endpoint: Create Identity
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
curl -X POST \
"https://app.bitgo-test.com/api/evs/v1/identity" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"enterpriseId": "string",
"userId": "string",
"organizationId": "string",
"nameFirst": "string",
"nameLast": "string",
"nameMiddle": "string",
"debugStatus": "string",
"debugFailureReason": "string",
"phoneNumber": "string",
"birthdate": "string",
"occupation": "Agriculture",
"countryOfCitizenship": "string",
"countryOfResidence": "string",
"govIdCountryOfIssuance": "string",
"politicallyExposedPerson": "string",
"addressStreet1": "string",
"addressCity": "string",
"addressSubdivision": "string",
"country": "string",
"identificationNumber": "string",
"transactionType": "institutionalIndividual",
"addressStreet2": "string",
"addressPostalCode": "string",
}'
import superagent from 'superagent';
const ACCESS_TOKEN = '<YOUR_ACCESS_TOKEN>';
const organizationId = '<YOUR_ORGANIZATION_ID>';
const apiUrl = 'https://app.bitgo-test.com/api/evs/v1/identity/';
const params = {
birthdate: new Date().toISOString(),
country: 'USA',
countryOfIncorporation: 'USA',
countryOfCitizenship: 'USA',
countryOfResidence: 'USA',
govIdCountryOfIssuance: 'USA',
addressStreet1: 'Street 1',
addressCity: 'City',
addressSubdivision: 'state',
addressPostalCode: '33604',
dateOfIncorporation: '2025-03-13T00:00:00Z',
debugFailureReason: 'expired',
debugStatus: 'passed',
enterpriseId: '67d28e40ea178ede86f296ac90032286',
userId: '67d28e3dea178ede86f2962e959865a0',
nameFirst: 'John',
nameMiddle: 'F',
nameLast: 'Doe',
phoneNumber: '+442083661173',
occupation: 'Other - Default',
politicallyExposedPerson: false,
organizationId,
transactionType: 'institutionalIndividual',
};
response = await superagent
.post(apiUrl)
.set('Authorization', `Bearer ${ACCESS_TOKEN}`)
.set('Accept', 'application/json')
.send(params);
Step Result
You created an identity for KYC purposes and BitGo returns one of the following statuses:
initiating
- BitGo receives the user's KYC information and asynchronously progresses the status toevaluating submission
.awaiting document upload
- BitGo receives the user's KYC information, but requires supporting documents to continue. To proceed, see the next step.
{
"id": "12345678",
"status": "initiating"
}
When the user's KYC Verification is in evaluating submission
- it is being initially reviewed by automated checks. Then the status is updated to in review
for manual reviews by BitGo. Once verification is approved, status will update to awaiting signature
.
You can check the status of a user's KYC verification by calling the Get Identity endpoint.
2. Submit Documents
If a user is a United States citizen, you don't need to submit documentation unless BitGo requests it. If a user isn't a United States citizen, you must submit additional identity verification documents.
BitGo recommends submitting all the necessary documents for a user in a single API call. Documents must not exceed 15MB in size and must be minimum 200x200px.
Endpoint: Create Identity Document
export INTENTY_ID="<USER_INTENTY_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export ID_CLASS="<DOCUMENT_ID_CLASS>"
curl -X POST \
"https://app.bitgo-test.com/api/evs/v1/identity/$INTENTY_ID/document" \
-H "Content-Type: multipart/form-data" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"selectedIdClass": "'"$ID_CLASS"'",
"frontPhoto": null,
"backPhoto": null,
"proofOfResidency": null
}'
Step Result
BitGo receives the supporting documents and validates them to complete KYC verification. The users's KYC status updates to evalutating submission
. BitGo asynchronously progresses the status to in review
and manually reviews the information. Once approved, the status updates to awaiting signature
.
{
"id": "string",
"status": "evalutating submission",
"selectedIdClass": "cct",
"fileUploads": [
{
"fileName": "string",
"fileSize": 0,
"uploadStatus": "string",
"documentType": "frontPhoto"
}
]
}
4. Sign Completed KYC
Once BitGo approves the user's KYC verification, the user must sign to confirm their verification. You can check the status of KYC verifications using the Get Identity endpoint. To complete this step, the status must be awaiting signature
.
Endpoint: Submit KYC Signatures
export IDENTITY_ID="<USER_IDENTITY_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
curl -X POST \
"https://app.bitgo-test.com/api/evs/v1/identity/$IDENTITY_ID/signatures" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '[
{
"contractSignerNameFull": "John Smith",
"contractSignedDate": "2025-03-13 13:14:09.767480+00:00",
"contractSignedIPAddress": "123.123.123.123",
"contractVersion": "1.0",
"contractType": "csa",
"userAgreesToTerms": true
},
{
"contractSignerNameFull": "John Smith",
"contractSignedDate": "2025-03-13 13:14:09.767480+00:00",
"contractSignedIPAddress": "123.123.123.123",
"contractVersion": "1.0",
"contractType": "mpa",
"userAgreesToTerms": true
},
{
"contractSignerNameFull": "Jerry Smith",
"contractSignedDate": "2025-03-13 13:14:09.767480+00:00",
"contractSignedIPAddress": "123.123.123.123",
"contractVersion": "1.0",
"contractType": "mic",
"userAgreesToTerms": true
}
]'
import superagent from 'superagent';
const ACCESS_TOKEN = '<YOUR_ACCESS_TOKEN>';
const IDENTITY_ID = '<USER_IDENTITY_ID>';
const apiUrl = `https://app.bitgo-test.com/api/evs/v1/identity/${IDENTITY_ID}/signatures`;
const params = [
{
"contractSignerNameFull": "John Smith",
"contractSignedDate": "2025-03-13 13:14:09.767480+00:00",
"contractSignedIPAddress": "123.123.123.123",
"contractVersion": "1.0",
"contractType": "csa",
"userAgreesToTerms": true
},
{
"contractSignerNameFull": "Jay Smith",
"contractSignedDate": "2025-03-13 13:14:09.767480+00:00",
"contractSignedIPAddress": "123.123.123.123",
"contractVersion": "1.0",
"contractType": "mpa",
"userAgreesToTerms": true
},
{
"contractSignerNameFull": "Jerry Smith",
"contractSignedDate": "2025-03-13 13:14:09.767480+00:00",
"contractSignedIPAddress": "123.123.123.123",
"contractVersion": "1.0",
"contractType": "mic",
"userAgreesToTerms": true
}
];
response = await superagent
.post(apiUrl)
.set('Authorization', `Bearer ${ACCESS_TOKEN}`)
.set('Accept', 'application/json')
.send(params);
Step Result
{
"id": "cf5d766d-bef1-4874-8b02-54ded0e8333e",
"status": "signature submitted",
"organizationId": "6573806ef79cafdd1aff42fbffc2ab20",
"enterpriseId": "67d28e40ea178ede86f296ac90032286",
"userId": "67d28e3dea178ede86f2962e959865a0",
"updatedAt": "2025-03-13T07:59:52.564Z",
"createdAt": "2025-03-13T07:54:18.842Z",
"errorDescription": "",
"signaturesSubmitted": ["csa", "mpa", "mic"],
"signaturesRequired": []
}
Next Steps
Create Go Accounts for your users.
See Also
Updated about 9 hours ago