Skip to main content
This guide walks you through onboarding an end-user using the Custom KYC flow, where you handle identity verification using your own KYC provider (e.g., Sumsub, Persona, Onfido).

Prerequisites

  • You have received your business API key
  • You have your own KYC verification provider set up
  • Your user has completed KYC verification through your provider

Custom KYC Flow Overview

1

Create end-user record

Create the record with basic information
2

Generate ToS link

Get a link for user to accept Bridge’s Terms of Service
3

User accepts ToS

Receive signed_agreement_id after acceptance
4

Submit KYC data

Send the KYC data you collected from your provider
5

Poll for approval

Wait for Bridge endorsement approval
6

Create accounts

User is ready for virtual accounts or liquidation addresses

Step 1: Create End-User Record

Create an end-user record with their basic information:
POST /v0/end-users
{
  "externalUserId": "user_123",  // Your internal user ID
  "email": "[email protected]"
}

// Response
{
  "data": {
    "id": "770e8400-e29b-41d4-a716-446655440000",
    "externalUserId": "user_123",
    "email": "[email protected]",
    "applicantId": "custom_kyc_business_customer_id_user_123",
    "bridgeCustomerId": null,  // Will be populated after KYC submission
    "createdAt": "2025-10-31T12:00:00Z"
  }
}
The externalUserId is YOUR user ID from your database. Use the same ID consistently throughout all API calls for this user.
Generate a Terms of Service acceptance link for your user:
POST /v0/end-users/user_123/tos-link
{
  "redirectUri": "https://yourapp.com/onboarding/complete"  // Optional (only for redirect integration)
}

// Response
{
  "data": {
    "tosLinkId": "tos_link_12345",
    "tosLink": "https://dashboard.bridge.xyz/tos/accept/...",
    "tosStatus": "pending"
  }
}

Integration Options

You can integrate ToS acceptance in two ways:
Embed the ToS page directly in your application.
  1. Display the ToS link in an iframe:
<iframe
  id="bridge-tos-iframe"
  src="[tosLink from response]"
  style="width: 100%; height: 600px; border: none;"
></iframe>
  1. Listen for the signed_agreement_id via postMessage:
window.addEventListener('message', (event) => {
  // Security: Verify origin
  if (event.origin !== 'https://dashboard.bridge.xyz') return;

  if (event.data?.signedAgreementId) {
    const signedAgreementId = event.data.signedAgreementId;
    console.log('Received:', signedAgreementId);
    // Example: "69bad66e-e8da-4845-a0be-a8ef3e14f87d"

    // Store for next step
    sessionStorage.setItem('signedAgreementId', signedAgreementId);
  }
});
Benefits: Seamless UX, user stays in your app, no redirect needed.

Step 3: Collect KYC Data

While the user is accepting ToS, collect and verify their KYC data using your own verification provider (Sumsub, Persona, Onfido, etc.). You’ll need:
  • Full name (first and last)
  • Email address
  • Date of birth (YYYY-MM-DD format)
  • Residential address
  • Government ID document images (drivers license, passport, or national ID)
  • SSN (if applicable)

Step 4: Submit Custom KYC Data

After receiving the signed_agreement_id (via either integration method), submit the KYC data:
POST /v0/end-users/user_123/submit-kyc
{
  "type": "individual",
  "first_name": "John",
  "last_name": "Doe",
  "email": "[email protected]",
  "residential_address": {
    "street_line_1": "123 Main St",
    "city": "San Francisco",
    "subdivision": "CA",  // 2-letter state code for US
    "postal_code": "94102",
    "country": "USA"
  },
  "birth_date": "1990-01-15",
  "signed_agreement_id": "69bad66e-e8da-4845-a0be-a8ef3e14f87d",  // From ToS acceptance
  "identifying_information": [
    {
      "type": "ssn",
      "issuing_country": "usa",
      "number": "123-45-6789"
    },
    {
      "type": "drivers_license",
      "issuing_country": "usa",
      "number": "D1234567",
      "image_front": "data:image/png;base64,...",
      "image_back": "data:image/png;base64,..."
    }
  ]
}

// Response
{
  "data": {
    "id": "770e8400-e29b-41d4-a716-446655440000",
    "externalUserId": "user_123",
    "email": "[email protected]",
    "applicantId": "custom_kyc_business_customer_id_user_123",
    "bridgeCustomerId": "cus_1234567890abcdef",  // Now populated!
    "createdAt": "2025-10-31T12:00:00Z"
  }
}
Critical Requirements:
  • signed_agreement_id is REQUIRED
  • identifying_information MUST include at least ONE government ID with images
  • SSN alone is NOT sufficient
  • For US addresses, use 2-letter state code for subdivision (e.g., “CA”)
  • Images must be base64-encoded: data:image/png;base64,...

Step 5: Poll Customer Status

Poll the customer status endpoint until the endorsement is approved:
GET /v0/end-users/user_123/customer-status

// Response when approved
{
  "data": {
    "externalUserId": "user_123",
    "bridgeCustomerId": "cus_1234567890abcdef",
    "kycStatus": "approved",
    "status": "active",
    "baseEndorsementStatus": "approved",  // Must be "approved"!
    "baseEndorsementRequirements": {
      "complete": ["government_id_verification", "terms_of_service"],
      "missing": {},
      "pending": [],
      "issues": []
    }
  }
}
Poll every 5 seconds until baseEndorsementStatus is "approved".
Typical approval time in sandbox: 20-30 seconds Production approval time may vary based on verification complexity

Verification Complete!

Once baseEndorsementStatus is "approved", your user is fully onboarded and ready to use on/off-ramp services.

Next Steps