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
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer token from authentication |
x-api-key | Yes | Your API key |
Content-Type | Yes | Must be application/json |
idempotency-key | Yes | UUID 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:
- Review the information you provided
- Take a selfie for identity verification
- Upload required documents (ID, proof of address, etc.)
- 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, orfailedverification_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
| Status | Description | Actions Available |
|---|---|---|
unverified | User has not started verification | Can create verification session |
not_started | Verification session created but not started | User needs to complete verification |
in_progress | Verification in progress | Wait for completion |
in_review | Verification submitted, awaiting review | Wait for approval |
verified | Verification approved | Can create virtual accounts |
rejected | Verification rejected | Review rejection reason, may retry |
needs_action | Additional information required | User 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
- Pre-fill user information - Ensure all required fields are populated before creating verification
- Clear communication - Explain to users why verification is required and what documents they'll need
- Mobile-friendly - The verification link works on mobile devices
- Monitor status via webhooks - Don't poll the API; use webhooks for real-time updates
- Handle rejections gracefully - Provide clear next steps if verification is rejected
- 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:
- Create a virtual account for the user
- User can start receiving deposits
Updated 12 days ago
