Overview
Once users are registered and authenticated, they can view and manage their profile information through a set of profile management endpoints. These endpoints provide access to personal details, account settings, and KYC verification status.
All profile management endpoints require authentication. Include the Authorization: Bearer <token> header with a valid access token from login.
Quick Reference
Get User Profile Retrieve complete user information including personal details and verification status
Update Settings Modify account preferences and security settings
Verification Status Check and initiate identity verification process
Onboarding Details Retrieve detailed onboarding information by ID
Get User Profile
Retrieve complete profile information for the authenticated user.
Endpoint
API Reference: GET /v1/user
Request
cURL
JavaScript/TypeScript
Python
curl -X GET https://dev.api.baanx.com/v1/user \
-H "x-client-key: YOUR_CLIENT_KEY" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response
{
"id" : "100a99cf-f4d3-4fa1-9be9-2e9828b20ebb" ,
"firstName" : "John" ,
"lastName" : "Doe" ,
"dateOfBirth" : "1990-01-01" ,
"email" : "[email protected] " ,
"verificationState" : "VERIFIED" ,
"phoneNumber" : "7400846282" ,
"phoneCountryCode" : "+44" ,
"addressLine1" : "23 Werrington Bridge Rd" ,
"addressLine2" : "Milking Nook" ,
"city" : "Peterborough" ,
"zip" : "PE6 7PP" ,
"countryOfResidence" : "GB" ,
"countryOfNationality" : "GB" ,
"usState" : null ,
"ssn" : null
}
Response Fields
Field Type Description idstring Unique user identifier emailstring User’s email address firstNamestring User’s legal first name lastNamestring User’s legal last name dateOfBirthstring Date of birth (YYYY-MM-DD format) phoneNumberstring Phone number without country code phoneCountryCodestring International dialing code (e.g., “+44”, “+1”) verificationStatestring KYC status: UNVERIFIED, PENDING, VERIFIED, or REJECTED addressLine1string Primary address line addressLine2string | null Secondary address line (optional) citystring City or town zipstring Postal/ZIP code countryOfResidencestring ISO 3166-1 alpha-2 country code countryOfNationalitystring ISO 3166-1 alpha-2 nationality code usStatestring | null US state code (only for US residents) ssnstring | null Masked SSN (only for US residents)
Sensitive fields like SSN are masked in the response for security. Full SSN is never returned via API.
Use Cases
Display User Dashboard:
const profile = await getUserProfile ( accessToken );
document . getElementById ( 'userName' ). textContent =
` ${ profile . firstName } ${ profile . lastName } ` ;
document . getElementById ( 'userEmail' ). textContent = profile . email ;
document . getElementById ( 'verificationBadge' ). textContent =
profile . verificationState ;
Check Verification Before Action:
const profile = await getUserProfile ( accessToken );
if ( profile . verificationState !== 'VERIFIED' ) {
alert ( 'Please complete identity verification to access this feature' );
redirectToVerification ();
}
Prefill Edit Forms:
const profile = await getUserProfile ( accessToken );
document . getElementById ( 'firstName' ). value = profile . firstName ;
document . getElementById ( 'lastName' ). value = profile . lastName ;
document . getElementById ( 'email' ). value = profile . email ;
Common Errors
{
"message" : "Unauthorized"
}
Resolution : Access token is missing, invalid, or expired. Re-authenticate the user.
{
"message" : "User not found"
}
Resolution : User account may have been deleted or token belongs to different environment.
Verification Status
Check the user’s identity verification status and initiate the verification process if needed.
Endpoint
GET /v1/user/verification
API Reference: GET /v1/user/verification
Request
cURL
JavaScript/TypeScript
Python
curl -X GET https://dev.api.baanx.com/v1/user/verification \
-H "x-client-key: YOUR_CLIENT_KEY" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response
{
"sessionUrl" : "https://example.com?sessionId=12345-12345-12345b"
}
How It Works
This endpoint generates a time-limited, single-use verification session URL where users complete identity verification:
Request Verification Session
Redirect User
Direct the user to the returned sessionUrl to complete verification
User Completes Verification
User submits identity documents and biometric verification (handled by verification provider)
Check Status
User’s verificationState is updated to PENDING or VERIFIED after completion
Verification session URLs are time-limited and single-use. Generate a new URL if the session expires or is abandoned.
Verification States
State Description Next Action UNVERIFIED User has not started verification Call this endpoint to get session URL PENDING Verification submitted, under review Wait for manual review (typically 1-3 business days) VERIFIED Identity confirmed User has full account access REJECTED Verification failed Contact support or resubmit with correct information
Implementation Example
JavaScript/TypeScript
Python
class VerificationManager {
private apiBase : string ;
private clientKey : string ;
constructor ( apiBase : string , clientKey : string ) {
this . apiBase = apiBase ;
this . clientKey = clientKey ;
}
async checkAndPromptVerification ( accessToken : string ) : Promise < void > {
const profile = await this . getUserProfile ( accessToken );
switch ( profile . verificationState ) {
case 'UNVERIFIED' :
if ( confirm ( 'Identity verification required. Start now?' )) {
await this . startVerification ( accessToken );
}
break ;
case 'PENDING' :
alert ( 'Your verification is under review. This usually takes 1-3 business days.' );
break ;
case 'VERIFIED' :
console . log ( 'User is verified' );
break ;
case 'REJECTED' :
alert ( 'Your verification was rejected. Please contact support or try again.' );
break ;
}
}
async startVerification ( accessToken : string ) : Promise < void > {
try {
const response = await fetch ( ` ${ this . apiBase } /v1/user/verification` , {
method: 'GET' ,
headers: {
'x-client-key' : this . clientKey ,
'Authorization' : `Bearer ${ accessToken } `
}
});
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 );
throw error ;
}
}
private async getUserProfile ( accessToken : string ) : Promise < any > {
const response = await fetch ( ` ${ this . apiBase } /v1/user` , {
method: 'GET' ,
headers: {
'x-client-key' : this . clientKey ,
'Authorization' : `Bearer ${ accessToken } `
}
});
if ( ! response . ok ) {
throw new Error ( 'Failed to fetch profile' );
}
return response . json ();
}
}
const verificationManager = new VerificationManager (
'https://dev.api.baanx.com' ,
'YOUR_CLIENT_KEY'
);
verificationManager . checkAndPromptVerification ( 'YOUR_ACCESS_TOKEN' );
Get Onboarding Details
Retrieve detailed onboarding information by onboarding ID. This is useful during the registration process to check progress or resume incomplete registrations.
Endpoint
GET /v1/auth/register?onboardingId= < I D >
API Reference: GET /v1/auth/register
Request
cURL
JavaScript/TypeScript
Python
curl -X GET "https://dev.api.baanx.com/v1/auth/register?onboardingId=US_100a99cf-f4d3-4fa1-9be9-2e9828b20ebb" \
-H "x-client-key: YOUR_CLIENT_KEY" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response
{
"id" : "100a99cf-f4d3-4fa1-9be9-2e9828b20ebb" ,
"firstName" : "John" ,
"lastName" : "Doe" ,
"dateOfBirth" : "1990-01-01" ,
"email" : "[email protected] " ,
"verificationState" : "UNVERIFIED" ,
"addressLine1" : "23 Werrington Bridge Rd" ,
"addressLine2" : "Milking Nook" ,
"city" : "Peterborough" ,
"zip" : "PE6 7PP" ,
"countryOfResidence" : "GB" ,
"countryOfNationality" : "GB" ,
"phoneNumber" : "7400846282" ,
"phoneCountryCode" : "+44"
}
Use Cases
Resume Incomplete Registration:
const onboardingData = await getOnboardingDetails ( onboardingId , accessToken );
if ( ! onboardingData . firstName ) {
console . log ( 'Resume from personal details step' );
} else if ( ! onboardingData . addressLine1 ) {
console . log ( 'Resume from address step' );
} else {
console . log ( 'Registration appears complete' );
}
Validate Registration State:
const details = await getOnboardingDetails ( onboardingId , accessToken );
if ( details . verificationState === 'UNVERIFIED' ) {
console . log ( 'Registration complete but verification pending' );
redirectToVerification ();
}
Update Account Settings
Modify user account settings and preferences.
This endpoint is referenced in the OpenAPI spec but implementation details may vary based on your environment configuration. Check with your account manager for available settings.
Endpoint
API Reference: PUT /v1/auth/settings
Common Settings
While specific settings vary by environment, common updateable settings include:
Communication Preferences : Marketing emails, SMS notifications
Security Settings : OTP enable/disable, password changes
Privacy Settings : Data sharing preferences
Notification Settings : Alert preferences
Settings updates may require re-authentication or email verification depending on the setting type and security requirements.
Profile Display Component Example
Here’s a complete example of a user profile display component:
React Component
Python Flask
import { useState , useEffect } from 'react' ;
interface UserProfile {
id : string ;
email : string ;
firstName : string ;
lastName : string ;
verificationState : 'UNVERIFIED' | 'PENDING' | 'VERIFIED' | 'REJECTED' ;
phoneNumber : string ;
phoneCountryCode : string ;
addressLine1 : string ;
city : string ;
zip : string ;
countryOfResidence : string ;
}
function UserProfileCard ({ accessToken } : { accessToken : string }) {
const [ profile , setProfile ] = useState < UserProfile | null >( null );
const [ loading , setLoading ] = useState ( true );
const [ error , setError ] = useState < string | null >( null );
useEffect (() => {
fetchProfile ();
}, []);
const fetchProfile = async () => {
try {
const response = await fetch ( 'https://dev.api.baanx.com/v1/user' , {
headers: {
'x-client-key' : 'YOUR_CLIENT_KEY' ,
'Authorization' : `Bearer ${ accessToken } `
}
});
if ( ! response . ok ) {
throw new Error ( 'Failed to fetch profile' );
}
const data = await response . json ();
setProfile ( data );
} catch ( err ) {
setError ( err instanceof Error ? err . message : 'Unknown error' );
} finally {
setLoading ( false );
}
};
const getVerificationBadge = ( state : string ) => {
const badges = {
VERIFIED: { color: 'green' , text: 'Verified ✓' },
PENDING: { color: 'yellow' , text: 'Pending Review' },
UNVERIFIED: { color: 'red' , text: 'Not Verified' },
REJECTED: { color: 'red' , text: 'Rejected' }
};
const badge = badges [ state as keyof typeof badges ];
return (
< span style = { { color: badge . color , fontWeight: 'bold' } } >
{ badge . text }
</ span >
);
};
if ( loading ) return < div > Loading profile... </ div > ;
if ( error ) return < div > Error: { error } </ div > ;
if ( ! profile ) return < div > No profile data </ div > ;
return (
< div style = { { border: '1px solid #ccc' , padding: '20px' , borderRadius: '8px' } } >
< h2 > Profile Information </ h2 >
< div style = { { marginBottom: '10px' } } >
< strong > Name: </ strong > { profile . firstName } { profile . lastName }
</ div >
< div style = { { marginBottom: '10px' } } >
< strong > Email: </ strong > { profile . email }
</ div >
< div style = { { marginBottom: '10px' } } >
< strong > Phone: </ strong > { profile . phoneCountryCode } { profile . phoneNumber }
</ div >
< div style = { { marginBottom: '10px' } } >
< strong > Address: </ strong > { profile . addressLine1 } , { profile . city } { profile . zip }
</ div >
< div style = { { marginBottom: '10px' } } >
< strong > Country: </ strong > { profile . countryOfResidence }
</ div >
< div style = { { marginBottom: '10px' } } >
< strong > Verification Status: </ strong > { ' ' }
{ getVerificationBadge ( profile . verificationState ) }
</ div >
{ profile . verificationState !== 'VERIFIED' && (
< button
onClick = { () => window . location . href = '/verification' }
style = { {
marginTop: '10px' ,
padding: '10px 20px' ,
backgroundColor: '#007bff' ,
color: 'white' ,
border: 'none' ,
borderRadius: '5px' ,
cursor: 'pointer'
} }
>
Complete Verification
</ button >
) }
</ div >
);
}
export default UserProfileCard ;
Best Practices
Cache Profile Data Cache user profile data locally with appropriate TTL to reduce API calls. Refresh when user updates information.
Handle Verification States Provide clear UI/UX for each verification state. Guide users through the verification process.
Secure Token Storage Never expose access tokens in URLs or logs. Use secure storage mechanisms appropriate for your platform.
Error Handling Gracefully handle 401 errors by re-authenticating. Show user-friendly messages for other errors.
Data Validation Validate profile data on the client side before display to prevent rendering issues with null/undefined values.
Privacy Considerations Mask sensitive information (SSN, full phone numbers) when displaying to users. Only show full details when necessary.
Security Considerations
Personal Data Protection
Never log full user data including SSN, full address, or financial information
Mask sensitive fields in UI (show last 4 digits of SSN, etc.)
Implement proper access controls for admin users viewing profiles
Comply with GDPR, CCPA, and other privacy regulations
Token Management
Validate token before each profile request
Re-authenticate if token is expired or invalid
Clear local profile cache on logout
Implement automatic token refresh when approaching expiration
Verification Status
Don’t bypass verification checks on client side
Always validate verification status server-side before allowing sensitive operations
Log verification status changes for audit trails
Alert users when verification status changes
Troubleshooting
Common Issues
Profile Data Not Updating
Symptoms : Changes made during registration not reflected in profileCauses :
Cached data on client side
Token from old session
Wrong environment (sandbox vs production)
Resolution :
Clear local cache and fetch fresh data
Ensure using latest access token
Verify x-client-key matches registration environment
Verification Session Expired
Symptoms : User completes verification but status remains UNVERIFIEDCauses :
Session URL expired before completion
Network issues during verification
Verification failed (documents rejected)
Resolution :
Generate new verification session URL
Check verification provider dashboard for rejection reasons
Wait 1-3 business days for manual review if status is PENDING
Symptoms : Some profile fields are null or undefinedCauses :
Incomplete registration
Optional fields not provided
Different requirements for different countries
Resolution :
Check registration completion status
Validate all required fields were submitted during registration
Handle null values gracefully in UI
Debug Checklist
When troubleshooting profile issues:
Complete Profile Manager Example
Full-featured profile management class with caching and error handling:
JavaScript/TypeScript
Python
class ProfileManager {
private apiBase : string ;
private clientKey : string ;
private cache : Map < string , { data : any ; timestamp : number }> = new Map ();
private cacheTTL = 5 * 60 * 1000 ;
constructor ( apiBase : string , clientKey : string ) {
this . apiBase = apiBase ;
this . clientKey = clientKey ;
}
async getProfile (
accessToken : string ,
useCache = true
) : Promise < UserProfile > {
if ( useCache ) {
const cached = this . cache . get ( 'profile' );
if ( cached && Date . now () - cached . timestamp < this . cacheTTL ) {
return cached . data ;
}
}
try {
const response = await fetch ( ` ${ this . apiBase } /v1/user` , {
headers: {
'x-client-key' : this . clientKey ,
'Authorization' : `Bearer ${ accessToken } `
}
});
if ( ! response . ok ) {
if ( response . status === 401 ) {
throw new Error ( 'UNAUTHORIZED' );
}
throw new Error ( `HTTP ${ response . status } ` );
}
const data = await response . json ();
this . cache . set ( 'profile' , { data , timestamp: Date . now () });
return data ;
} catch ( error ) {
console . error ( 'Failed to fetch profile:' , error );
throw error ;
}
}
async startVerification ( accessToken : string ) : Promise < string > {
try {
const response = await fetch ( ` ${ this . apiBase } /v1/user/verification` , {
headers: {
'x-client-key' : this . clientKey ,
'Authorization' : `Bearer ${ accessToken } `
}
});
if ( ! response . ok ) {
throw new Error ( 'Failed to start verification' );
}
const { sessionUrl } = await response . json ();
return sessionUrl ;
} catch ( error ) {
console . error ( 'Verification error:' , error );
throw error ;
}
}
clearCache () : void {
this . cache . clear ();
}
isVerified ( profile : UserProfile ) : boolean {
return profile . verificationState === 'VERIFIED' ;
}
needsVerification ( profile : UserProfile ) : boolean {
return [ 'UNVERIFIED' , 'REJECTED' ]. includes ( profile . verificationState );
}
formatAddress ( profile : UserProfile ) : string {
const parts = [
profile . addressLine1 ,
profile . addressLine2 ,
profile . city ,
profile . zip ,
profile . countryOfResidence
]. filter ( Boolean );
return parts . join ( ', ' );
}
formatPhone ( profile : UserProfile ) : string {
return ` ${ profile . phoneCountryCode } ${ profile . phoneNumber } ` ;
}
maskSsn ( ssn ?: string ) : string {
if ( ! ssn ) return 'Not provided' ;
return `***-**- ${ ssn . slice ( - 4 ) } ` ;
}
}
interface UserProfile {
id : string ;
email : string ;
firstName : string ;
lastName : string ;
dateOfBirth : string ;
phoneNumber : string ;
phoneCountryCode : string ;
verificationState : 'UNVERIFIED' | 'PENDING' | 'VERIFIED' | 'REJECTED' ;
addressLine1 : string ;
addressLine2 ?: string ;
city : string ;
zip : string ;
countryOfResidence : string ;
countryOfNationality : string ;
usState ?: string ;
ssn ?: string ;
}
const profileManager = new ProfileManager (
'https://dev.api.baanx.com' ,
'YOUR_CLIENT_KEY'
);
async function displayUserDashboard ( accessToken : string ) {
try {
const profile = await profileManager . getProfile ( accessToken );
console . log ( 'User Dashboard' );
console . log ( '==============' );
console . log ( `Name: ${ profile . firstName } ${ profile . lastName } ` );
console . log ( `Email: ${ profile . email } ` );
console . log ( `Phone: ${ profileManager . formatPhone ( profile ) } ` );
console . log ( `Address: ${ profileManager . formatAddress ( profile ) } ` );
console . log ( `Verification: ${ profile . verificationState } ` );
if ( profileManager . needsVerification ( profile )) {
console . log ( ' \n ⚠️ Verification required' );
const sessionUrl = await profileManager . startVerification ( accessToken );
console . log ( `Complete verification at: ${ sessionUrl } ` );
}
} catch ( error ) {
if ( error . message === 'UNAUTHORIZED' ) {
console . error ( 'Session expired. Please login again.' );
} else {
console . error ( 'Error:' , error );
}
}
}
Next Steps