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 Modes

Kira supports two verification modes:

1. Embedded Link Mode (Recommended)

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

Best for:

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

2. API Mode

You submit the required personal data and verification documents through the API. The user doesn't interact with a third-party verification page.

Best for:

  • Enterprise integrations
  • Custom verification flows
  • Existing KYC processes

Create Verification Session

Endpoint

POST /v1/users/{userId}/verifications

Headers

HeaderRequiredDescription
AuthorizationYesBearer token from authentication
x-api-keyYesYour API key
Content-TypeYesMust be application/json
idempotency-keyYesUUID to prevent duplicate verification creation

Request Body (Embedded Link Mode)

{
  "type": "embedded-link",
  "redirect_uri": "https://yourapp.com/verification-complete"
}

Request Body (API Mode)

{
  "type": "api",
  "documents": {
    "identity_document": {
      "type": "passport",
      "number": "123456789",
      "country": "US",
      "expiration_date": "2030-12-31",
      "front_image": "base64_encoded_image",
      "back_image": "base64_encoded_image"
    },
    "address_proof": {
      "type": "utility_bill",
      "document_url": "https://yourcdn.com/documents/proof.pdf"
    }
  }
}

Example Request (Embedded Link)

curl -X POST https://api.balampay.com/v1/users/550e8400-e29b-41d4-a716-446655440000/verifications \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "idempotency-key: verification-$(date +%s)" \
  -d '{
    "type": "embedded-link",
    "redirect_uri": "https://yourapp.com/verification-complete"
  }'

Response (Embedded Link Mode)

{
  "id": "ver_123456789",
  "provider": "verification_provider",
  "provider_link": "https://verify.example.com/session?token=abc123...",
  "provider_metadata": {
    "template_id": "tmpl_123",
    "session_id": "sess_456"
  },
  "status": "not_started"
}

Response (API Mode)

{
  "id": "ver_123456789",
  "provider": "persona",
  "provider_link": "",
  "provider_metadata": {},
  "status": "in_progress"
}

Embedded Link Flow

Step 1: Create Verification Session

Create a verification session and receive the provider_link:

const response = await fetch('https://api.balampay.com/v1/users/{userId}/verifications', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json',
    'idempotency-key': `verification-${Date.now()}`
  },
  body: JSON.stringify({
    type: 'embedded-link',
    redirect_uri: 'https://yourapp.com/verification-complete'
  })
});

const { provider_link } = await response.json();

Step 2: Redirect User to Verification Page

Redirect the user to the provider_link:

// In your application
window.location.href = provider_link;

// Or open in a new window
window.open(provider_link, '_blank');

Step 3: User Completes Verification

The user will:

  1. Review the information you provided
  2. Take a selfie for identity verification
  3. Upload required documents (ID, proof of address, etc.)
  4. Submit the verification

Step 4: User is Redirected Back

After completion, the user is redirected to your redirect_uri:

https://yourapp.com/verification-complete?status=success&verification_id=ver_123456789

Query parameters:

  • status - Verification result: success, pending, or failed
  • verification_id - The verification session ID

Step 5: Check Verification Status

After the user returns, check the verification status:

curl -X GET https://api.balampay.com/v1/users/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-api-key: YOUR_API_KEY"

Response:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "verification_status": "verified",
  ...
}

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": "ebd2325e-f16d-4917-8a83-7dcb3a2ebf73",
    "id": "ebd2325e-f16d-4917-8a83-7dcb3a2ebf73",
    "user_id": "147ba2c0-0637-4949-b0e2-f89d228b69c8",
    "verification_status": "verified",
    "kyc_type": "simplified",
    "tier": 1
  }
}

Note: kyc_type can be either "simplified" or "full" depending on the verification level.

Verification Failed

Sent when user verification is rejected:

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

Note: The reasons array provides details about why verification failed, including both user-facing and developer-facing explanations.

Required Information for Verification

Individual Users (KYC)

Basic Information:

  • Full name (first + last)
  • Email address
  • Phone number
  • Date of birth
  • Country of residence
  • Full address

Documents:

  • Government-issued ID (passport, driver's license, or national ID)
  • Proof of address (utility bill, bank statement, etc.) - less than 3 months old
  • Selfie (taken during verification process)

Business Users (KYB)

Basic Information:

  • Legal business name
  • Business type (LLC, Corporation, Partnership, etc.)
  • Tax ID (EIN)
  • Business address
  • Business phone number
  • Business email

Documents:

  • Certificate of incorporation or business registration
  • Tax ID documentation (EIN letter)
  • Proof of business address
  • Beneficial owner information (individuals who own 25% or more)

Beneficial Owner Information: For each beneficial owner:

  • Full name
  • Date of birth
  • Ownership percentage
  • Government-issued ID
  • Address

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. Pre-fill user information - Ensure all required fields are populated before creating verification
  2. Clear communication - Explain to users why verification is required and what documents they'll need
  3. Mobile-friendly - The verification link works on mobile devices
  4. Monitor status via webhooks - Don't poll the API; use webhooks for real-time updates
  5. Handle rejections gracefully - Provide clear next steps if verification is rejected
  6. Test in sandbox - Use sandbox mode to test the full verification flow

Testing in Sandbox

In sandbox/test environments, users are automatically verified after creating a verification session. This allows you to test the complete user flow without manual verification.

Next Steps

After successful verification:

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