Identity Verification (KYC/KYB)

Overview

Before a user can create a virtual account, they must complete identity verification. This is a regulatory requirement to prevent fraud and ensure compliance with financial regulations.

  • KYC (Know Your Customer) - For individual users
  • KYB (Know Your Business) - For business users

Verification Methods

Automatic Verification (Recommended)

When you create a user with all required fields, verification is triggered automatically. This is the recommended approach for new integrations.

How it works:

  1. Create a user via POST /v1/users with all required fields
  2. The response includes verification_triggered: true
  3. Verification runs in the background
  4. You receive a webhook notification when verification completes

Benefits:

  • No additional API calls needed
  • Faster user onboarding
  • Simpler integration

See the User Management Guide for details on creating users with automatic verification.


Embedded Link Mode

The user is redirected to a hosted verification page where they complete the KYC/KYB process themselves. This is the easiest manual integration method.

Best for:

  • Consumer-facing applications
  • Quick integration
  • Minimal compliance burden on your platform

Verification Status

StatusDescriptionActions Available
unverifiedUser has not started verificationCan create verification session
not_startedVerification session created but not startedUser needs to complete verification
in_progressVerification in progressWait for completion
in_reviewVerification submitted, awaiting reviewWait for approval
verifiedVerification approvedCan create virtual accounts
rejectedVerification rejectedReview rejection reason, may retry
needs_actionAdditional information requiredUser must provide missing data

Webhooks

You can receive real-time updates about verification status changes via webhooks. See the Webhooks guide for setup instructions.

Verification Accepted

Sent when user verification is approved:

{
  "event": "user.verification.accepted",
  "data": {
    "event_id": "ec538bcc-53e3-4d1b-bb8b-0e8cfd6e6aac",
    "user_id": "e9610a11-d514-4587-85dc-e18e2b461e55",
    "status": "VERIFIED",
    "verified_fields": [
      "first_name",
      "last_name",
      "date_of_birth",
      "document_type",
      "document_number",
      "document_country",
      "address_street",
      "address_city",
      "address_state",
      "address_zip_code"
    ]
  }
}

Key fields:

  • status: User verification status (VERIFIED)
  • verified_fields: List of fields that were successfully verified

Verification Failed

Sent when user verification is rejected:

{
  "event": "user.verification.failed",
  "data": {
    "event_id": "ee8e3df9-6ad8-40d6-81de-ddea5399d011",
    "user_id": "8d05b02e-9d15-46d6-bb33-9c81d461a969",
    "status": "REJECTED",
    "reasons": [
      {
        "reason": "Your information could not be verified",
        "developer_reason": "Inconsistent details between submissions.",
        "created_at": "2026-01-14T03:44:00.884Z"
      }
    ]
  }
}

Key fields:

  • status: User verification status (REJECTED)
  • reasons: Array with details about why verification failed (user-facing and developer-facing explanations)

Required Information for Verification

Note: For automatic verification, provide these fields when creating the user via POST /v1/users.

Individual Users (KYC)

FieldUSA ResidentsInternational
first_name✅ Required✅ Required
last_name✅ Required✅ Required
birth_date✅ Required✅ Required
email✅ Required✅ Required
ssn✅ Required-
document_type✅ Required✅ Required
document_number✅ Required✅ Required
document_country✅ Required✅ Required
address_street✅ Required✅ Required
address_city✅ Required✅ Required
address_state✅ Required✅ Required
address_zip_code✅ Required✅ Required
address_country✅ Required✅ Required

Business Users (KYB)

FieldUSA BusinessesInternational
company_name✅ Required✅ Required
email✅ Required✅ Required
ein✅ Required-
business_type✅ Required✅ Required
representative_first_name✅ Required✅ Required
representative_last_name✅ Required✅ Required
document_type✅ Required✅ Required
document_number✅ Required✅ Required
document_country✅ Required✅ Required
address_street✅ Required✅ Required
address_city✅ Required✅ Required
address_state✅ Required✅ Required
address_zip_code✅ Required✅ Required
address_country✅ Required✅ Required

Note: USA vs International is determined by the nationality and formation_country or the address_country field.

Error Responses

User Not Found

{
  "code": "not_found",
  "message": "User with ID 550e8400-e29b-41d4-a716-446655440000 not found"
}

Missing Required Fields

{
  "code": "validation_error",
  "message": "User is missing required fields for verification: date_of_birth, address_line_1"
}

Verification Already Exists

{
  "code": "resource_conflict",
  "message": "An active verification session already exists for this user"
}

Best Practices

  1. Use automatic verification - Provide all required fields when creating users for seamless verification
  2. Monitor status via webhooks - Use webhooks (user.verification.accepted, user.verification.failed) for real-time updates
  3. Handle rejections gracefully - Provide clear next steps if verification is rejected
  4. Test in sandbox - Use sandbox mode to test the full verification flow
  5. Clear communication - Explain to users why verification is required
  6. Check verification_triggered - Verify the response field to confirm automatic verification started

Testing in Sandbox

In sandbox/test environments, verification completes automatically. This allows you to test the complete user flow without waiting for real verification.

Next Steps

After successful verification (you'll receive a user.verification.accepted webhook):

  1. Create a virtual account for the user
  2. User can start receiving deposits

Migration Guide

If you're currently using the manual verification flow:

  1. Update your user creation - Include all required fields when calling POST /v1/users
  2. Check the response - Look for verification_triggered: true to confirm automatic verification started
  3. Remove manual verification calls - You no longer need to call POST /v1/users/{userId}/verifications
  4. Keep webhook handlers - The webhook events remain the same (user.verification.accepted, user.verification.failed)