Skip to main content
GET
/
v1
/
user
/
verification
{
  "message": "Not authenticated"
}

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

1

Generate Session URL

Call this endpoint to receive a unique verification session URL
2

Redirect User

Direct the user to the session URL (web redirect or open in webview/browser)
3

User Completes Verification

User uploads documents and completes identity checks on the verification provider’s page
4

Verification Processing

The provider processes the submission (typically 5-30 minutes)
5

Status Update

User’s verificationState is updated to either PENDING, VERIFIED, or REJECTED
6

Verification Complete

Check the user’s verification status via GET /v1/user

Authentication

This endpoint requires both client authentication and user authentication:
x-client-key
string
required
Your client public key for API authentication
Authorization
string
required
Bearer token obtained from OAuth flow or login endpoint
x-us-env
boolean
default:"false"
Set to true to route requests to the US backend environment (if available for your client). Defaults to international environment.

Response

sessionUrl
string
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 --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

{
  "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
Document showing current residential address (dated within last 3 months):
  • Utility bill (electricity, water, gas)
  • Bank statement
  • Government correspondence
  • Rental agreement

Verification Timeline

1

Immediate (0-2 minutes)

Automated checks: Document authenticity, facial recognition, data extraction
2

Quick Review (5-15 minutes)

Most verifications complete automatically within this timeframe
3

Manual Review (15-30 minutes)

If automated checks are inconclusive, manual review by compliance team
4

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:
  1. Check rejection reason (contact support if not clear)
  2. Wait 24 hours before retry (cooldown period)
  3. Generate new verification session
  4. Ensure documents meet all requirements
  5. 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