Crypto-as-a-Service

Complete Know Your Business (KYB) Verification

Overview

BitGo must verify the legitimacy of businesses you onboard to your platform to ensure regulatory compliance. The Know Your Business (KYB) API enables you to submit all required documentation to prove corporate existence, physical operational footprint, legal signing delegation, and identity verification for key stakeholders. You must complete KYB verification for each entity before they can use BitGo products on your platform.

Required Documents

Required documents for KYB verification are determined by four factors:

  1. Universal Requirements - Core identification documents that you must submit for every business and business owner on your platform.
  2. Legal Entity Structure - Documents that are specific to the legal structure of the business.
  3. Jurisdiction & Tax - Documents that are specific to jurisdiction and include tax documents.
  4. Business Types & BitGo Products - Documents that are specific to the business type and the BitGo products they'll use on your platform.

When you create a business or associated individual identity, BitGo returns the exact documents required to complete the KYB verification. However, you can expand the following to learn more now:

Universal

Entity Requirements

Requirement Document Type (documentType) Description
Authorized Signer authorizedSigner Authorized signatory name, email, phone.
Billing Address billingAddress Billing address.
Billing Contact billingContact Billing contact name, email, phone.
Business Name businessName Legal registered name.
Company Website Address companyWebsiteAddress Official website URL.
Customer Base Locations customerBaseLocations Countries/regions of customer base.
DBA Name dbaName Doing-Business-As name.
Description of Business Activities descriptionBusinessActivities What the business does.
EIN/TIN Identification Number einTinIdentificationNumber EIN or Tax ID Number.
Formation Date formationDate Date formed (YYYY-MM-DD).
Has Auditor hasAuditor Has external auditor?
Has Legal Counsel hasLegalCounsel Has legal counsel?
Incorporation Country Code incorporationCountryCode Country of incorporation (e.g. USA).
Legal Entity Structure legalEntityStructure Entity type (e.g. corporationCAndS, LLC, trusts).
Mailing Address mailingAddress Mailing address (if different).
Other Entity ID otherEntityId Secondary entity ID (state registration, etc.).
Physical Business Address physicalBusinessAddress Principal business address.
Primary Business Type primaryBusinessType Category of business activity.
Primary Operations Country Code primaryOperationsCountryCode Country of primary operations.
Proof of Authorized Signatories
  • authorizedSignerForm
  • proofOfAuthorizedSignatories
Completed BitGo Authorized Signer Form or official corporate document confirming the designated individual has legal authority to execute contracts on behalf of the entity.
Proof of Principal Place of Business proofOfPrincipalPlaceOfBusiness Recent utility bill, lease agreement, or bank statement (issued within the last 3 months) confirming the business's physical operating address. PO Boxes are not accepted.
Retail/Institutional Diligence diligenceRetailInstitutional Retail vs institutional proportion (enum).
Sanction Affiliates sanctionAffiliates Sanction-related affiliates?
Wallet Address walletAddress Business blockchain wallet address.

Individual Requirements

For each business, you must identify one control person (controlPerson). If there are other individuals who hold a 10% or more share of the business, then you must add them as a beneficial owner (beneficialOwner).

Requirement Document Type (documentType) Description
Address address Residential address.
Birthdate birthdate Date of birth (month, day, year).
Country of Citizenship countryOfCitizenship Country of citizenship.
Country of Residence countryOfResidence Country of residence — submit first.
Email email Email address of the individual.
First Name nameFirst First name.
Government-Issued Photo ID governmentId Valid, unexpired government-issued photo ID (passport, driver's license, or national identity card) for every individual listed under associatedPeople (beneficial owners, control persons, and platform admins).
Identification Number identificationNumber Government ID or SSN.
Last Name nameLast Last name.
Occupation occupation Current occupation.
PEP Status politicallyExposedPerson PEP status (true/false).
Phone Number phoneNumber Phone with country code.
Residential Proof of Address proofOfAddress Utility bill, residential bank statement, or government correspondence dated within the last 3 months verifying the primary residential address for each associated person.
Legal Entity Structure

Defined with the legalEntityStructure field on the Create KYB Identity endpoint.

Legal Structure Schema Enum (legalEntityStructure) Document Type (documentType) Description
Corporation (C Corporation and S Corporation) corporationCAndS
  • certificateOfIncorporation
  • articlesOfAssociation or bylawsOrOperatingAgreement
  • evidenceOfLegalStatus
  • Certificate of Incorporation: Official government-issued certificate legally recognizing entity existence.
  • Bylaws / Articles of Association: Governing rules establishing internal operations, share capital, and director powers.
  • Evidence of Legal Status: Certificate of Good Standing or registry extract issued within the last 12 months.
General Partnerships generalPartnership
  • partnershipAgreement
  • evidenceOfLegalStatus
  • Partnership Agreement: Formal agreement establishing partner roles, liabilities, and governance.
  • Evidence of Legal Status: Registry excerpt or equivalent proof of active operational existence.
Government / State Owned governmentOwned
  • evidenceOfGovernmentOrStateOwnership
  • evidenceOfLegalStatus
  • Evidence of Government Ownership: Legislative charter, statutory decree, or sovereign ownership register confirming state status.
  • Evidence of Legal Status: Official governmental decree or registry extract evidencing active authorization.
Limited Liability Company (LLC) llc
  • articlesOfOrganization
  • operatingAgreement or bylawsOrOperatingAgreement
  • evidenceOfLegalStatus
  • Articles of Organization: Official filed formation document registered with the state or province.
  • Operating Agreement: Internal governing agreement defining ownership, membership percentages, and operational procedures.
  • Evidence of Legal Status: Certificate of Good Standing or registry extract issued within the last 12 months confirming active status.
Partnership (Limited Partnerships and Limited Liability Partnerships) partnershipLimitedAndLLP
  • partnershipAgreement
  • certificateOfIncorporation (or businessLicenseOrRegistration)
  • evidenceOfLegalStatus
  • Partnership Agreement: Executed agreement defining general and limited partners and profit distribution.
  • Certificate of Limited Partnership: Official filing evidencing legal registration of the LP/LLP.
  • Evidence of Legal Status: Registry excerpt or status certificate issued within the last 12 months.
Private Investment Company / Private Foundation privateInvestmentOrFoundation
  • certificateOfIncorporation (or organizationDocument)
  • operatingAgreement or bylawsOrOperatingAgreement
  • evidenceOfLegalStatus
  • Certificate of Incorporation / Formation: Official certificate or foundation charter recognizing legal existence.
  • Bylaws / Operating Agreement: Constitutional documents governing foundation/company operations.
  • Evidence of Legal Status: Certificate of Good Standing or registry extract issued within the last 12 months.
Publicly Traded Company (or 100% owned subsidiary) publiclyTraded
  • certificateOfIncorporation
  • articlesOfAssociation or bylawsOrOperatingAgreement
  • secFilingsAsEvidenceOfPublicTradingStatus
  • Certificate of Incorporation: Official document legally recognizing corporate existence.
  • Bylaws: Internal corporate bylaws and operating governance documents.
  • SEC Filings: Form 10-K, annual report, or national exchange extract confirming active public listing.
Sole Proprietorship soleProprietorship
  • businessLicenseOrRegistration
  • evidenceOfLegalStatus
  • Business License or Registration: Active municipal, state, or national business license, trade certificate, or DBA filing.
  • Evidence of Legal Status: Document confirming legal authorization to operate (issued within the last 12 months).
Special Purpose Vehicle (SPV) / Segregated Portfolio Company (SPC)
  • specialPurposeVehicle
  • segregatedPortfolioCompany
  • organizationDocument
  • certificateOfIncumbencyOrShareRegister
  • Organization Document: Statutory formation filing, memorandum, or SPV offering supplement.
  • Incumbency / Share Register: Certified register detailing directors, officers, and segregated portfolio/cell allocations.
Supranational Bodies supranationalBodies foundingTreatyOrEquivalent Founding Treaty: Intergovernmental convention, founding treaty, or bilateral charter establishing the body.
Trusts trusts certificateOfTrust Certificate of Trust: Formal legal instrument or trust deed verifying trust existence, identifying trustees, and defining trustee powers.
Unincorporated Business (including pooled investment vehicles) unincorporatedBusiness
  • organizationDocument
  • evidenceOfLegalStatus
  • Organization Document: Constitutional instrument or charter establishing the entity or pooled investment vehicle.
  • Evidence of Legal Status: Official evidence demonstrating active legal/operational standing.
Jurisdiction & Tax

Defined with the incorporationCountryCode and primaryOperationsCountryCode fields on the Update KYB Identity endpoint.

Note

Every business must submit either an IRS Form W-8 (w8) or Form W-9 (w9).

Jurisdiction / Contracting Entity Trigger Conditions Document Type (documentType) Description
Japan
  • Headquartered in Japan (JPN)
  • Regulated in Japan (JPN)
proofOfJfsaLicense JFSA Proof of License: Official registration certificate issued by the Japanese Financial Services Agency.
Non-US / International incorporationCountryCode != "USA" w8 Form W-8: Completed and signed IRS Form W-8BEN-E certifying foreign status for US tax withholding.
Non-US / International Non-US registered entities commercialRegister Commercial Register Extract: Official excerpt from national trade/company registry issued within the last 12 months.
Non-US / Offshore Jurisdictions without public shareholder registries certificateOfIncumbency Certificate of Incumbency: Document issued by registered agent/corporate secretary listing current directors and officers.
Singapore Contracting with BitGo Singapore resolutionToOpenBitgoSingaporeAccount Singapore Corporate Resolution: Board resolution formally authorizing onboarding and account opening with BitGo Singapore.
United Arab Emirates (UAE)
  • Contracting with BitGo Mena Fze
  • Contracting with BitGo Custody MENA FZE
  • activeTradeLicense
  • resolutionToOpenBitgoUaeAccount
  • Active Trade License: Commercial license issued by relevant UAE authority (VARA, DED, or Free Zone).
  • UAE Corporate Resolution: Board resolution explicitly approving opening and operating an account with BitGo UAE.
United States US entity incorporated > 12 months prior certificateOfGoodStanding Certificate of Good Standing: State secretary extract dated within the last 12 months confirming active legal status.
United States
  • US Incorporation (USA)
  • US Operations (USA)
w9 Form W-9: Completed and signed IRS Form W-9 confirming US legal entity name and EIN/TIN.
Business Types & BitGo Products

Defined with the primaryBusinessType and requestedProducts fields on the Create KYB Identity and Update KYB Identity endpoints.

Business Activity / Product Trigger Field & Value Document Type (documentType) Description
Casinos & Gambling primaryBusinessType: "Casinos and Gambling Establishments" proofOfGamingLicense Gaming License: Official gambling or gaming license issued by the jurisdictional regulatory authority.
Custom Case Reviews Ad-hoc compliance referral triggered during manual review caseRequiredDocuments Case Required Documents: Dynamically created file slots assigned per-instance for specific transaction or compliance requests.
Enhanced Due Diligence (EDD)
  • High-risk customer evaluation
  • requestedProducts: "Borrowing"
  • requestedProducts: "Margin Trading"
sourceOfWealth Source of Wealth: Audited financial statements, tax records, or banking documentation evidencing economic origin of capital.
Foreign Banking
  • primaryBusinessType: "Bank"
  • Foreign incorporation (incorporationCountryCode != "USA")
correspondentAccountCertification Correspondent Account Certification: Completed and signed FinCEN certification regarding correspondent accounts for foreign banks.
Regulated MSB / High-Risk FinTech
  • primaryBusinessType: "Money Services Business (MSB)"
  • primaryBusinessType: "Crypto Services"
  • primaryBusinessType: "NBFI"
financialCrimeComplianceQuestionnaire Compliance Questionnaire: BitGo AML/CFT compliance questionnaire detailing AML controls, transaction monitoring, and policies.
Trade / Go Account Products
  • requestedProducts: "Trade"
  • requestedProducts: "Go Account"
  • tradeStrategy
  • activeCoinTokens
  • tradeVolumeUsd
  • activeExchanges
  • Trade Strategy: Description of trading approach.
  • Active Coin Tokens: Cryptos actively traded (e.g. BTC, ETH).
  • Trade Volume USD: Estimated annual trade volume in USD.
  • Active Exchanges: Exchanges currently used.

Prerequisites

  • Get Started
  • Set Up Organization
  • You must be the service user.
  • (Optional) Set up webhooks to follow the KYB process. Use the identityStatus organization webhook and listen for the productRequestApproved and productRequestRejected events. To learn more, see Create Organization Webhook.

Cookbook

Need just the steps? Expand the cookbook below to get started:

Complete KYB VerificationOpen Cookbook

1. Create Enterprise and Primary User

Endpoint: Create an Enterprise for an Organization

export ORGANIZATION_ID="<YOUR_ORGANIZATION_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export EMAIL="<YOUR_USER'S_EMAIL>"
export IDEMPOTENCY_KEY="<UUID_V4>"

curl -X POST \
  "https://app.bitgo-test.com/api/v2/organization/$ORGANIZATION_ID/enterprise" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "email": "$EMAIL",
    "idempotencyKey": "$IDEMPOTENCY_KEY",
    "additionalAdmins": [],
    "accountType": "entity" # This creates a business enterprise instead of an individual enterprise.
}'

Note

Generate a fresh UUID for each new request. Reuse the same key when you retry the same request, so BitGo recognizes the duplicate.

Step Result

The request does the following:

  • Creates a new child enterprise within your parent organization.
  • Creates a user for the child enterprise, who serves as the primary contact for the business.
  • Assigns the service user to the child enterprise.
  • Assigns organization admins to the child enterprise.
{
  "enterpriseId": "68cc1b65564dc0f83892a49d1ee75626",
  "userId": "68cc1b63564dc0f83892a32072a8b5c7"
}

2. Create Users for Associated Persons

Repeat this step for every beneficial owner, control person, and platform admin of the business.

Endpoint: Add a User to an Enterprise Within an Organization

export ORGANIZATION_ID="<YOUR_ORGANIZATION_ID>"
export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export EMAIL="<YOUR_USER'S_EMAIL>"

curl -X POST \
  "https://app.bitgo-test.com/api/v2/organization/$ORGANIZATION_ID/enterprise/{enterpriseId}/user" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
        "email": "$EMAIL"
}'

Step Result

You receive a user ID for each person. Save these IDs for use in Step 4.

{
  "userId": "68cc1bc8b1b5017f12c5c1e3c04cd1d4"
}

3. Set Up Business Identity

Complete these sub-steps to create and populate the business identity.

3.1 Create Business Identity

Create the business identity and request the BitGo products they intend to use.

Choose Products

The products you request drive the KYB requirements. You can add additional later as your platform grows. Most platforms start with Trade and Go Account.

Endpoint: Create KYB Identity

export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"
export ORGANIZATION_ID="<YOUR_ORGANIZATION_ID>"

curl -X POST \
  "https://app.bitgo-test.com/api/identity-service/v1/identities" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
  "type": "business",
  "enterpriseId": "$ENTERPRISE_ID",
  "organizationId": "$ORGANIZATION_ID",
  "requestedProducts": [
    {
      "name": "Trade",
      "bitgoOrg": "BitGo Trust"
    },
    {
      "name": "Go Account",
      "bitgoOrg": "BitGo Trust"
    }
  ]
}
}'

Step Result

Save the identity id. This is the business identity ID.

{
  "type": "business",
  "organizationId": "659706890515c624f4f0871b879b00a6",
  "enterpriseId": "68cc1b65564dc0f83892a49d1ee75626",
  "business": {},
  "associatedPeople": [],
  "id": "c1ecba6b-0914-4bc3-ae67-4188e061aa3e",
  "requestedProducts": [
    {
      "id": "1a595191-b22d-48f9-b816-4ca311a3f5a4",
      "name": "Trade",
      "bitgoOrg": "BitGo Trust",
      "status": "missingLocation"
    },
    {
      "id": "81948454-f74e-438e-b51e-75e3fdbac1d3",
      "name": "Go Account",
      "bitgoOrg": "BitGo Trust",
      "status": "missingLocation"
    }
  ],
  "requirements": [],
  "documents": [],
  "finalizeSubmission": false
}

Endpoint: Update KYB Identity

export BUSINESS_IDENTITY_ID="<BUSINESS_IDENTITY_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"

curl -X PATCH \
  "https://app.bitgo-test.com/api/identity-service/v1/identities/$BUSINESS_IDENTITY_ID" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "business": {
      "physicalBusinessAddress": {
        "street1": "123 4th St",
        "city": "San Francisco",
        "subdivision": "CA",
        "zip": "94103",
        "country": "USA"
      },
      "legalEntityStructure": "corporationCAndS",
      "primaryBusinessType": "Crypto Services (Exchange, ATM, Borrow/Lend)",
      "incorporationCountryCode": "USA",
      "primaryOperationsCountryCode": "USA"
    }
  }'

Step Result

The requirements array returns all the KYB information that you must submit in Step 5. Requirements vary based on legal entity structure, location, and selected BitGo products. The following example is for a Corporation (C Corporation and S Corporation):

{
  "type": "business",
  "id": "c1ecba6b-0914-4bc3-ae67-4188e061aa3e",
  "business": {
    "physicalBusinessAddress": {
      "street1": "123 4th St",
      "city": "San Francisco",
      "subdivision": "CA",
      "zip": "94103",
      "country": "USA"
    },
    "legalEntityStructure": "corporationCAndS",
    "primaryBusinessType": "Crypto Services (Exchange, ATM, Borrow/Lend)",
    "incorporationCountryCode": "USA",
    "primaryOperationsCountryCode": "USA"
  },
  "requestedProducts": [
    {
      "name": "Trade",
      "bitgoOrg": "BitGo Trust",
      "status": "missingRequirements"
    },
    {
      "name": "Go Account",
      "bitgoOrg": "BitGo Trust",
      "status": "missingRequirements"
    }
  ],
  "requirements": [
    {
      "kind": "document",
      "name": "certificateOfIncorporation",
      "status": "missing"
    },
    {
      "kind": "document",
      "name": "evidenceOfLegalStatus",
      "status": "missing"
    },
    {
      "kind": "document",
      "name": "bylaws",
      "status": "missing"
    },
    {
      "kind": "document",
      "name": "proofOfAuthorizedSignatories",
      "status": "missing"
    },
    {
      "kind": "document",
      "name": "w9",
      "status": "missing"
    },
    {
      "kind": "businessInformation",
      "name": "businessName",
      "status": "missing"
    },
    {
      "kind": "businessInformation",
      "name": "einTinIdentificationNumber",
      "status": "missing"
    },
    {
      "kind": "businessInformation",
      "name": "fundsSource",
      "status": "missing"
    },
    {
      "kind": "businessInformation",
      "name": "amlAttestation",
      "status": "missing"
    },
    {
      "kind": "businessInformation",
      "name": "legalEntityStructure",
      "status": "submitted"
    }
  ],
  "finalizeSubmission": false
}

Track Product Status

The requestedProducts array returns a status that provides more information about the required KYB documents.

Statuses
Status Description Action
missingLocation BitGo needs the business location. Redo Step 3.2.
missingEntityStructure BitGo needs the four structural fields. Redo Step 3.2.
missingRequirements Fields or documents are still missing. Submit the items in requirements.
readyForSubmission You submitted everything. Finalize business identity Step 8.
inReview BitGo is reviewing the identity. Wait for the decision from BitGo.
approved or rejected BitGo made a final decision. Listen for the webhook event.

4. Set Up Associated Persons

Complete these sub-steps to create and populate an individual identity for each beneficial owner and control person.

Role Rule
controlPerson Exactly one. No more, no less.
beneficialOwner Required for each person who holds 10% or more of the business.

4.1 Create Individual Identities for Associated Persons

Using the userId from Step 2, create an individual identity for each control person and beneficial owner. You don't need to request products for associated persons.

Endpoint: Create KYB Identity

export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export ASSOCIATED_PERSON_USER_ID="<USER_ID_FOR_THIS_ASSOCIATED_PERSON>"

curl -X POST \
  "https://app.bitgo-test.com/api/identity-service/v1/identities" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "type": "individual",
    "userId": "'"$ASSOCIATED_PERSON_USER_ID"'",
    "requestedProducts": []
  }'

Step Result

Save the identity id for each person.

{
  "type": "individual",
  "userId": "68cc1bc8b1b5017f12c5c1e3c04cd1d4",
  "individual": {},
  "id": "df114ee7-7dc9-431e-aeae-fe4294f789cc",
  "requestedProducts": [],
  "requirements": [],
  "documents": [],
  "finalizeSubmission": false
}

4.2 Add Associated Persons to Business Identity

BitGo generates the KYB requirements for each person once you link them to the business identity.

If no one holds 10% or more of the business, the beneficial owner requirement defaults to submitted. You can still add beneficial owners.

Endpoint: Update KYB Identity

export BUSINESS_IDENTITY_ID="<BUSINESS_IDENTITY_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export BENEFICIAL_OWNER_USER_ID="<BENEFICIAL_OWNER_USER_ID>"
export CONTROL_PERSON_USER_ID="<CONTROL_PERSON_USER_ID>"

curl -X PATCH \
  "https://app.bitgo-test.com/api/identity-service/v1/identities/$BUSINESS_IDENTITY_ID" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "associatedPeople": [
      {
        "role": "beneficialOwner",
        "identityId": "'"$BENEFICIAL_OWNER_USER_ID "'",
        "percentageOwnership": 25
      },
      {
        "role": "controlPerson",
        "identityId": "'"$CONTROL_PERSON_USER_ID"'"
      }
    ]
  }'

Step Result

For each person, BitGo returns an associatedPersonId, a status, and a missingRequirements array, which specifies their required KYB information.

{
  "type": "business",
  "id": "c1ecba6b-0914-4bc3-ae67-4188e061aa3e",
  "associatedPeople": [
    {
      "associatedPersonId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "role": "beneficialOwner",
      "identityId": "f56a207c-0c96-4e5d-b59d-5bcf8092580a",
      "userId": "68cc1bc8b1b5017f12c5c1e3c04cd1d4",
      "percentageOwnership": 25,
      "status": "missingRequirements",
      "missingRequirements": [
        { "kind": "data", "name": "countryOfResidence", "status": "missing" }
      ]
    },
    {
      "associatedPersonId": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
      "role": "controlPerson",
      "identityId": "df114ee7-7dc9-431e-aeae-fe4294f789cc",
      "userId": "68cc1bca2f1d047e21d6c2f4d15de2e5",
      "status": "missingRequirements",
      "missingRequirements": [
        { "kind": "data", "name": "countryOfResidence", "status": "missing" }
      ]
    }
  ]
}

4.3 Update Associated Persons with Location Information

Submit each person's location before any other personal information. BitGo uses countryOfResidence or countryOfCitizenship to generate the requirements for that person.

Repeat this step for each associated person.

Endpoint: Update KYB Identity

export INDIVIDUAL_IDENTITY_ID="<YOUR_INDIVIDUAL_IDENTITY_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"

curl -X PATCH \
  "https://app.bitgo-test.com/api/identity-service/v1/identities/$INDIVIDUAL_IDENTITY_ID" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "individual": {
      "countryOfResidence": "USA",
      "countryOfCitizenship": "USA"
    }
  }'

Step Result

The requirements array returns all the KYB information that you must submit in the following step.

{
  "type": "individual",
  "userId": "68cc1bc8b1b5017f12c5c1e3c04cd1d4",
  "id": "df114ee7-7dc9-431e-aeae-fe4294f789cc",
  "individual": {
    "countryOfResidence": "USA",
    "countryOfCitizenship": "USA"
  },
  "requirements": [
    { "kind": "data", "name": "nameFirst", "status": "missing" },
    { "kind": "data", "name": "nameLast", "status": "missing" },
    { "kind": "data", "name": "birthdate", "status": "missing" },
    { "kind": "data", "name": "identificationNumber", "status": "missing" },
    { "kind": "data", "name": "phoneNumber", "status": "missing" },
    { "kind": "data", "name": "occupation", "status": "missing" },
    { "kind": "data", "name": "address", "status": "missing" },
    { "kind": "data", "name": "politicallyExposedPerson", "status": "missing" }
  ],
  "finalizeSubmission": false
}

4.4 Update Individual Identities with Required Information

TODO: Is this the associatedPersonId from the associatedPeople array, or the identityId?

Using the individual identity ID, submit the following personal information for each associated person:

Required Identity Fields
Field Description
nameFirst, nameLast Legal name
email Email address
birthdate Month, day, and year. Zero-pad single digits, for example "01".
identificationNumber Government ID or Social Security number
phoneNumber Phone number with country code
occupation Current occupation
countryOfResidence Country of residence
countryOfCitizenship Country of citizenship
address Residential address
politicallyExposedPerson Politically exposed person status (true or false)

Endpoint: Update KYB Identity

export INDIVIDUAL_IDENTITY_ID="<INDIVIDUAL_IDENTITY_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"

curl -X PATCH \
  "https://app.bitgo-test.com/api/identity-service/v1/identities/$INDIVIDUAL_IDENTITY_ID" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "individual": {
      "nameFirst": "John",
      "nameLast": "Doe",
      "email": "john.doe@acme.com",
      "birthdate": {
        "month": "01",
        "day": "01",
        "year": "2000"
      },
      "identificationNumber": "12345678",
      "phoneNumber": {
        "countryCode": "1",
        "phoneNumber": "5559876543"
      },
      "occupation": "Other",
      "countryOfResidence": "USA",
      "countryOfCitizenship": "USA",
      "address": {
        "street1": "123 4th St",
        "city": "San Francisco",
        "subdivision": "CA",
        "zip": "94103",
        "country": "USA"
      },
      "politicallyExposedPerson": false
    }
  }'

Step Result

{
  "type": "individual",
  "userId": "68cc1bc8b1b5017f12c5c1e3c04cd1d4",
  "id": "df114ee7-7dc9-431e-aeae-fe4294f789cc",
  "requestedProducts": [],
  "requirements": [
    {
      "kind": "data",
      "name": "nameFirst",
      "status": "submitted"
    },
    {
      "kind": "data",
      "name": "nameLast",
      "status": "submitted"
    },
    {
      "kind": "data",
      "name": "birthdate",
      "status": "submitted"
    },
    {
      "kind": "data",
      "name": "identificationNumber",
      "status": "submitted"
    },
    {
      "kind": "data",
      "name": "politicallyExposedPerson",
      "status": "submitted"
    }
  ],
  "finalizeSubmission": false
}

4.5 Remove an Associated Person (Optional)

You can remove an associated person before finalizing the KYB submission if both of the following are true:

  • The business status for requestedProducts isn't inReview, approved, or rejected.
  • The individual's status isn't inReview, verified, or rejected.

Endpoint: Remove Associated Person

export BUSINESS_IDENTITY_ID="<BUSINESS_IDENTITY_ID>"
export ASSOCIATED_PERSON_ID="<ASSOCIATED_PERSON_ID>" # associatedPersonId from associatedPeople array - not identityId
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"

curl -X DELETE \
  "https://app.bitgo-test.com/api/identity-service/v1/identities/$BUSINESS_IDENTITY_ID/associated-people/$ASSOCIATED_PERSON_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Step Result

Returns the updated business identity with the removed person no longer present in the associatedPeople array and product statuses recalculated to reflect the updated associated person set.

{
  "type": "business",
  "id": "c1ecba6b-0914-4bc3-ae67-4188e061aa3e",
  "associatedPeople": [
    {
      "associatedPersonId": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
      "role": "controlPerson",
      "identityId": "df114ee7-7dc9-431e-aeae-fe4294f789cc"
    }
  ],
  "requestedProducts": [
    {
      "name": "Trade",
      "bitgoOrg": "BitGo Trust",
      "status": "missingRequirements"
    }
  ]
}

5. Upload Required Documents

Upload the required documents for KYB verification. For each required document you must generate an upload URL, upload the document, and then verify it.

Note

Evidence of legal status must be issued within the last 12 months. Accepted examples include a Certificate of Good Standing, a business registration or trade license, and a company registry extract.

5.1 Identify Business Type and Documents

For the exact documents you must upload, see the requirements array you received in Step 3.2, specifically, entries with kind: "document".

Every file must be a PDF, JPEG, PNG, HEIC, HEIF, or TIFF. When a document has more than one possible documentType, the requirements array specifies the exact file type to use.

5.2 Generate Document Upload URL

Generate an upload URL for each document.

Endpoint: Generate KYB Document Upload URL

export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"

curl -X POST \
  "https://app.bitgo-test.com/api/document-service/v1/documents" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "documentType": "w9"
  }'

Step Result

Save the documentId and the uploadUrl.

Note

The uploadUrl points to the BitGo managed document storage provider, not to the BitGo API host. This is expected. The URL is single-use and expires at expiresAt. Upload directly to it.

{
  "documentId": "c7c00bb6-0ad3-470d-83f3-a96ce043d812",
  "documentType": "w9",
  "documentTypeLabel": "W9 Form",
  "subType": null,
  "status": "awaitingUpload",
  "files": [
    {
      "fileId": "c6c8651e-dbd3-4f35-ad4d-b3ed1c742a6b",
      "fileView": "full",
      "label": "W9 Form Document",
      "required": true,
      "uploadUrl": "https://api.withcortex.ai/public/apps/files/uploads/up_6B1Re7PtUzgzSimXdygEx3",
      "expiresAt": "2025-10-18T16:09:23.973Z"
    }
  ]
}

5.3 Upload Document

Upload your file to the URL from the previous step.

The CONTENT_TYPE value is optional. If you pass it, the file must resolve to one of the allowed types: application/pdf, image/jpeg, image/png, image/heic, image/heif, or image/tiff. You can't pass application/octet-stream.

export UPLOAD_URL="<DOCUMENT_UPLOAD_URL>"
export FILE_PATH="</path/to/your/document.pdf>"
export CONTENT_TYPE="application/pdf"

curl -X POST "$UPLOAD_URL" \
  -F "file=@$FILE_PATH;type=$CONTENT_TYPE"

Step Result

{
  "id": "afile_1jGYRK9FwcQ7mrPETfS3o6",
  "file_id": "486674b3064254a7e3fa45f4314dbef7-fd377b79ef89f05782976d41f3f5aa9",
  "file_filename": "w9.pdf",
  "file_size": 140815,
  "file_mimetype": "application/pdf",
  "file_status": "PROCESSED",
  "created_at": "2025-09-18T16:19:07.894Z"
}

5.4 Verify Document

Verify the document with its documentId.

Endpoint: Verify KYB Document Status

export DOCUMENT_ID="<YOUR_DOCUMENT_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"

curl -X POST \
  "https://app.bitgo-test.com/api/document-service/v1/documents/$DOCUMENT_ID/verify" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{}'

Step Result

{
  "documentId": "c7c00bb6-0ad3-470d-83f3-a96ce043d812",
  "documentType": "w9",
  "documentTypeLabel": "W9 Form",
  "status": "uploaded",
  "files": [
    {
      "fileId": "c6c8651e-dbd3-4f35-ad4d-b3ed1c742a6b",
      "fileView": "full",
      "required": true,
      "status": "uploaded"
    }
  ]
}

5.5 Associate Documents with Identity

Associate each verified document with the correct identity. Use the business identity ID for business documents. Use the individual identity ID for individual documents. Add documentSubType when the document type has one. For example, a government ID uses a sub-type such as pp for a passport.

Endpoint: Assign KYB Document to Identity

export IDENTITY_ID="<YOUR_IDENTITY_ID>"
export DOCUMENT_ID="<YOUR_DOCUMENT_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"

curl -X POST \
  "https://app.bitgo-test.com/api/identity-service/v1/identities/$IDENTITY_ID/documents" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "documents": [
      {
        "documentId": "'"$DOCUMENT_ID"'",
        "documentType": "w9",
        "documentSubType": null
      }
    ]
  }'

Step Result

Save the id in acceptedDocuments. If you replace the document later, you must pass this ID.

{
  "identityId": "c1ecba6b-0914-4bc3-ae67-4188e061aa3e",
  "acceptedDocuments": [
    {
      "id": "3a83bde3-6db8-49f4-b3aa-7d38ecd1006c",
      "documentId": "c7c00bb6-0ad3-470d-83f3-a96ce043d812",
      "documentType": "w9",
      "status": "submitted",
      "createdAt": "2025-09-18T16:25:52.045Z",
      "updatedAt": "2025-09-18T16:25:52.045Z"
    }
  ],
  "rejectedDocuments": []
}

5.6 Update Document Association (Optional)

If you make a mistake, you can replace an uploaded document - you don't need to remove and re-add it.

Repeat the following steps:

Then update the association using the following:

Endpoint: Update KYB Document

export IDENTITY_ID="<YOUR_IDENTITY_ID>"
export IDENTITY_DOCUMENT_ID="<IDENTITY_DOCUMENT_ID>" # id from acceptedDocuments array in step 5.5
export NEW_DOCUMENT_ID="<NEW_DOCUMENT_SERVICE_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"

curl -X PUT \
  "https://app.bitgo-test.com/api/identity-service/v1/identities/$IDENTITY_ID/documents/$IDENTITY_DOCUMENT_ID" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "documentId": "'"$NEW_DOCUMENT_ID"'",
    "documentType": "w9"
  }'

Step Result

{
  "id": "3a83bde3-6db8-49f4-b3aa-7d38ecd1006c",
  "documentId": "d8e00cc7-1be4-581e-94g4-b07df154e923",
  "documentType": "w9",
  "status": "submitted",
  "createdAt": "2025-09-18T16:25:52.045Z",
  "updatedAt": "2025-09-18T16:35:12.011Z"
}

6. Check Statuses

Fetch each identity (business and individuals) to see if any requirements are still missing.

Endpoint: Get KYB Identity

export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export IDENTITY_ID="<BUSINESS_IDENTITY_ID>"

curl -X GET \
  "https://app.bitgo-test.com/api/identity-service/v1/identities/$IDENTITY_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Step Result

Ensure all fields in the following arrays are ready for BitGo review:

Array Requirements
requestedProducts[] "status": "readyForSubmission"
associatedPeople[]
  • One controlPerson.
  • Additional people are a beneficialOwner.
  • "status": "readyForSubmission".
  • individual[].missingRequirements must be empty.
requirements[] "status": "submitted"
documents[] "status": "submitted"

If you have any outstanding requirements, you can:

7. Finalize Submission

Once all statuses are ready and all supporting documentation is uploaded, finalize the KYB submission, marking it ready for review by BitGo.

Important

Finalization is permanent. Ensure all information is complete before proceeding. Once submitted, you can no longer update the identity.

Endpoint: Update KYB Identity

export IDENTITY_ID="<BUSINESS_IDENTITY_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"

curl -X PATCH \
  "https://app.bitgo-test.com/api/identity-service/v1/identities/$IDENTITY_ID" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "finalizeSubmission": true
  }'

Step Result

BitGo returns the business identity with:

  • "finalizeSubmission": "true".
  • Each requirement is submitted.
  • Each requested product moves to inReview.

The business identity is now under review by BitGo. If additional information is required, BitGo contacts you — not your end user.

Note

If you receive any values with missing or if the missingRequirements array has objects, then BitGo didn't accept the finalized submission. Supply the missing information and try again.

{
  "type": "business",
  "id": "c1ecba6b-0914-4bc3-ae67-4188e061aa3e",
  "requestedProducts": [
    {
      "name": "Trade",
      "bitgoOrg": "BitGo Trust",
      "status": "inReview"
    },
    {
      "name": "Go Account",
      "bitgoOrg": "BitGo Trust",
      "status": "inReview"
    }
  ],
  "requirements": [
    { "kind": "document", "name": "certificateOfIncorporation", "status": "submitted" },
    { "kind": "document", "name": "proofOfAuthorizedSignatories", "status": "submitted" },
    { "kind": "businessInformation", "name": "businessName", "status": "submitted" },
    { "kind": "businessInformation", "name": "amlAttestation", "status": "submitted" },
    { "kind": "associatedPerson", "name": "controlPeople", "status": "submitted" }
  ],
  "associatedPeople": [
    {
      "associatedPersonId": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
      "role": "controlPerson",
      "identityId": "df114ee7-7dc9-431e-aeae-fe4294f789cc",
      "status": "inReview",
      "missingRequirements": []
    }
  ],
  "finalizeSubmission": true
}

8. Sign Contracts

Before BitGo activates the enterprise, you must sign the following contracts in two separate calls:

  • master-agreement (which includes includes trade-mpa, custody-sa, and staking-sa)
  • distributed-custody-mic

Endpoint: Sign a Contract for an Enterprise Within an Organization

export ORGANIZATION_ID="<YOUR_ORGANIZATION_ID>"
export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"

curl -X POST \
  "https://app.bitgo-test.com/api/v2/organization/$ORGANIZATION_ID/enterprise/$ENTERPRISE_ID/contract" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "contractType": "master-agreement",
    "signedDate": "2026-09-09T18:47:23"
  }'

Step Result

{
  "success": true,
  "contractsSigned": [
    {
      "contractType": "master-agreement",
      "signedBy": "string",
      "signedDate": "string",
      "ip": "string"
    }
  ],
  "message": "string"
}

Next Steps

Create Go Accounts for your end users.

See Also