Overview
This endpoint generates a time-limited, single-use verification session URL that you direct your users to for completing identity verification. The verification process is handled by Baanx’s integrated identity verification provider.
Use this endpoint when:
A user registers and needs to complete identity verification
A user’s verification was rejected and they need to retry
You want to upgrade an unverified user to verified status
How It Works
Generate Session URL
Call this endpoint to receive a unique verification session URL
Redirect User
Direct the user to the session URL (web redirect or open in webview/browser)
User Completes Verification
User uploads documents and completes identity checks on the verification provider’s page
Verification Processing
The provider processes the submission (typically 5-30 minutes)
Status Update
User’s verificationState is updated to either PENDING, VERIFIED, or REJECTED
Authentication
This endpoint requires both client authentication and user authentication:
Your client public key for API authentication
Bearer token obtained from OAuth flow or login endpoint
Set to true to route requests to the US backend environment (if available for your client). Defaults to international environment.
Response
Time-limited verification session URL. Direct the user to this URL to complete identity verification. The URL typically expires after 24 hours and is single-use only.
Examples
cURL
JavaScript
TypeScript
Python
curl --request GET \
--url https://dev.api.baanx.com/v1/user/verification \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'x-client-key: YOUR_CLIENT_KEY'
Response Example
{
"sessionUrl" : "https://example.com?sessionId=12345-12345-12345b"
}
Error Responses
401 Unauthorized
403 Forbidden
500 Internal Server Error
{
"message" : "Not authenticated"
}
401 Unauthorized The access token is missing, invalid, or expired. You need to:
Ensure the Authorization header is present and properly formatted
Verify the access token hasn’t expired (6-hour lifetime)
Obtain a new access token using the refresh token if expired
403 Forbidden The access token is valid but doesn’t have permission to access this resource. This may occur if:
The token doesn’t belong to a valid user
The client key doesn’t match the user’s associated client
The user account has been suspended or disabled
500 Internal Server Error An unexpected error occurred on the server. If this persists:
Check the API status page
Contact support with the request timestamp
Implement retry logic with exponential backoff
Implementation Examples
Web Application Flow
import { useRouter } from 'next/navigation' ;
async function handleStartVerification () {
try {
const response = await fetch ( 'https://dev.api.baanx.com/v1/user/verification' , {
headers: {
'Authorization' : `Bearer ${ accessToken } ` ,
'x-client-key' : process . env . NEXT_PUBLIC_CLIENT_KEY
}
});
if ( ! response . ok ) {
throw new Error ( 'Failed to start verification' );
}
const { sessionUrl } = await response . json ();
window . location . href = sessionUrl ;
} catch ( error ) {
console . error ( 'Verification error:' , error );
showErrorToast ( 'Unable to start verification. Please try again.' );
}
}
Mobile Application Flow (React Native)
import { Linking } from 'react-native' ;
async function startVerificationMobile ( accessToken : string ) {
try {
const response = await fetch ( 'https://dev.api.baanx.com/v1/user/verification' , {
headers: {
'Authorization' : `Bearer ${ accessToken } ` ,
'x-client-key' : YOUR_CLIENT_KEY
}
});
const { sessionUrl } = await response . json ();
const canOpen = await Linking . canOpenURL ( sessionUrl );
if ( canOpen ) {
await Linking . openURL ( sessionUrl );
}
} catch ( error ) {
console . error ( 'Failed to open verification:' , error );
}
}
In-App Browser Flow
For better UX, open the verification URL in an in-app browser:
import { InAppBrowser } from 'react-native-inappbrowser-reborn' ;
async function startVerificationInApp ( accessToken : string ) {
try {
const response = await fetch ( 'https://dev.api.baanx.com/v1/user/verification' , {
headers: {
'Authorization' : `Bearer ${ accessToken } ` ,
'x-client-key' : YOUR_CLIENT_KEY
}
});
const { sessionUrl } = await response . json ();
if ( await InAppBrowser . isAvailable ()) {
await InAppBrowser . open ( sessionUrl , {
dismissButtonStyle: 'cancel' ,
preferredBarTintColor: '#16A34A' ,
preferredControlTintColor: 'white' ,
readerMode: false ,
animated: true ,
modalEnabled: true ,
enableBarCollapsing: false
});
}
} catch ( error ) {
console . error ( 'Failed to open verification:' , error );
}
}
Polling for Verification Completion
After redirecting the user, implement polling to detect when verification is complete:
async function pollVerificationStatus (
accessToken : string ,
onComplete : ( verified : boolean ) => void
) {
const maxAttempts = 60 ; // 5 minutes with 5-second intervals
let attempts = 0 ;
const poll = setInterval ( async () => {
try {
const response = await fetch ( 'https://dev.api.baanx.com/v1/user' , {
headers: {
'Authorization' : `Bearer ${ accessToken } ` ,
'x-client-key' : YOUR_CLIENT_KEY
}
});
const user = await response . json ();
if ( user . verificationState === 'VERIFIED' ) {
clearInterval ( poll );
onComplete ( true );
} else if ( user . verificationState === 'REJECTED' ) {
clearInterval ( poll );
onComplete ( false );
}
attempts ++ ;
if ( attempts >= maxAttempts ) {
clearInterval ( poll );
console . log ( 'Verification still pending after 5 minutes' );
}
} catch ( error ) {
console . error ( 'Polling error:' , error );
}
}, 5000 ); // Poll every 5 seconds
return () => clearInterval ( poll );
}
const stopPolling = pollVerificationStatus ( accessToken , ( verified ) => {
if ( verified ) {
showSuccessMessage ( 'Verification complete! You can now order a card.' );
} else {
showErrorMessage ( 'Verification was rejected. Please contact support.' );
}
});
Important Notes
Session Expiry : The verification session URL typically expires after 24 hours. If a user doesn’t complete verification within this time, you’ll need to generate a new session URL by calling this endpoint again.
Single Use : Each session URL is single-use. Once the user completes (or abandons) the verification session, the URL becomes invalid. Generate a new URL for retry attempts.
User Experience : For the best user experience:
Display a clear message explaining why verification is needed
Show what documents will be required (government ID, proof of address)
Inform users about the typical processing time (5-30 minutes)
Provide a way to check verification status after completion
Verification Process Details
Required Documents
Users will typically need to provide:
One of the following:
Passport
Driver’s license
National ID card
Residence permit
Requirements:
Must be valid (not expired)
Clear, readable photo of the document
All corners visible in the image
Live selfie or video recording
Used for biometric matching with ID photo
Ensures the person presenting the ID is the actual holder
Proof of Address (Region Dependent)
Document showing current residential address (dated within last 3 months):
Utility bill (electricity, water, gas)
Bank statement
Government correspondence
Rental agreement
Verification Timeline
Immediate (0-2 minutes)
Automated checks: Document authenticity, facial recognition, data extraction
Quick Review (5-15 minutes)
Most verifications complete automatically within this timeframe
Manual Review (15-30 minutes)
If automated checks are inconclusive, manual review by compliance team
Extended Review (1-24 hours)
Complex cases requiring additional verification or document requests
Edge Cases & Limitations
Already Verified Users
If a user is already verified and calls this endpoint:
A new verification session is still generated
The existing verification status remains until the new session completes
This allows users to update their verification documents if needed
Verification Rejection
If verification is rejected, the user’s verificationState becomes REJECTED. Common rejection reasons:
Expired documents
Poor image quality (blurry, dark, cut-off)
Documents not accepted in user’s region
Mismatched document information
Selfie doesn’t match ID photo
Name on documents doesn’t match registration
Age doesn’t meet minimum requirements (typically 18+)
Document appears altered or fake
User on sanctions or watchlist
Previous account with same credentials
Suspicious behavior patterns
Proof of address doesn’t match registered address
Document too old (must be within 3 months)
Address in restricted region
Retry After Rejection
When a user is rejected:
Check rejection reason (contact support if not clear)
Wait 24 hours before retry (cooldown period)
Generate new verification session
Ensure documents meet all requirements
Submit with corrected/additional documents
async function retryVerification ( accessToken : string ) {
const userResponse = await fetch ( 'https://dev.api.baanx.com/v1/user' , {
headers: {
'Authorization' : `Bearer ${ accessToken } ` ,
'x-client-key' : YOUR_CLIENT_KEY
}
});
const user = await userResponse . json ();
if ( user . verificationState === 'REJECTED' ) {
// Show guidance on what went wrong
showRejectionGuidance ();
// Generate new session after user confirms they're ready
const verificationResponse = await fetch (
'https://dev.api.baanx.com/v1/user/verification' ,
{
headers: {
'Authorization' : `Bearer ${ accessToken } ` ,
'x-client-key' : YOUR_CLIENT_KEY
}
}
);
const { sessionUrl } = await verificationResponse . json ();
window . location . href = sessionUrl ;
}
}
Regional Differences
International Environment :
Standard KYC requirements
Typical processing: 5-30 minutes
Document requirements vary by country
US Environment (x-us-env: true):
Enhanced KYC requirements
SSN verification
Additional compliance checks
May require proof of address
Typical processing: 15-60 minutes
Session Abandonment
If a user starts verification but doesn’t complete it:
The session URL remains valid until expiry (24 hours)
User’s verificationState stays at current value
No partial progress is saved
User can restart by generating a new session URL
Rate Limiting
Maximum 10 verification sessions per user per day
Maximum 3 concurrent active sessions per user
Cooldown period of 1 hour after 3 consecutive failures
If limits are exceeded, you’ll receive a 429 Too Many Requests response with details:
{
"message" : "Rate limit exceeded" ,
"retryAfter" : 3600 ,
"limit" : "3_per_hour"
}
Webhook Notifications
While this endpoint doesn’t directly support webhooks, you can configure verification status webhooks in your client dashboard to receive real-time notifications when a user’s verification status changes.
Webhook payload example:
{
"event" : "user.verification.completed" ,
"userId" : "100a99cf-f4d3-4fa1-9be9-2e9828b20ebb" ,
"verificationState" : "VERIFIED" ,
"timestamp" : "2024-01-15T10:30:00Z"
}
Testing
Sandbox Environment
In sandbox/test environments, you can use test documents to simulate different verification outcomes:
// Test user - will auto-approve
const testApprovedUser = {
firstName: "Test" ,
lastName: "Approved"
};
// Test user - will auto-reject
const testRejectedUser = {
firstName: "Test" ,
lastName: "Rejected"
};
// Test user - will remain pending
const testPendingUser = {
firstName: "Test" ,
lastName: "Pending"
};
Contact Baanx support for access to sandbox environment and test credentials.
Best Practices
Before redirecting users to verification:
Explain why verification is required
List required documents
Estimate processing time
Provide preparation tips (good lighting, clear images)
Implement robust error handling:
Network failures during session generation
User closing verification window prematurely
Session expiry
Verification rejection
After verification:
Poll user status periodically
Show loading state while verification processes
Display clear success/failure messages
Provide next steps based on outcome
Never store or log verification session URLs
Implement CSRF protection on your redirect endpoints
Validate the user’s session before generating verification URL
Use HTTPS for all communications