How Onboarder Works
A complete walkthrough of the Onboarder verification flow from start to finish.
The Big Picture
Onboarder is an OAuth 2.0 identity verification platform. Instead of building verification forms and handling document uploads yourself, users sign in through Onboarder where we handle all verification, then return to your app fully verified.
You Configure
Set up your platform and define verification requirements
User Clicks
"Sign in with Onboarder" button in your app
We Verify
User completes verifications on Onboarder's hosted pages
You Get Data
Receive verified user data via OAuth
The Complete User Journey
User Initiates Sign-In
User clicks "Sign in with Onboarder" on your application. Your app redirects them to Onboarder's OAuth authorization endpoint with your client_id and flow_id.
// Your app redirects user to Onboarderconst authUrl = new URL('https://api.onboarder.com/api/v1/oauth/authorize');authUrl.searchParams.append('client_id', 'plt_sandbox_abc123');authUrl.searchParams.append('flow_id', 'flow_banking_kyc'); // Defines what they must verifyauthUrl.searchParams.append('redirect_uri', 'https://yourapp.com/callback');authUrl.searchParams.append('response_type', 'code');authUrl.searchParams.append('state', 'random_csrf_token');
window.location.href = authUrl.toString();User Lands on Onboarder
User is now on Onboarder's hosted pages. They see our branded UI with options to sign up or log in.
What the user sees:
- • "YourApp wants to verify your identity"
- • "Sign up" or "Log in" buttons
- • Clear explanation of what will be verified
Sign Up / Log In
New users: Create account with email/password
Returning users: Log in with existing credentials
💡 Pro Tip: Returning users who already verified don't need to verify again! They simply log in and authorize your app - instant access.
Onboarder Checks Requirements
Based on your flow_id, Onboarder checks what this user still needs to verify.
✓ Already Verified
User completed these before → Skip
⚠ Still Needed
User must complete these now
User Completes Verifications
User is guided through each required verification step-by-step on Onboarder's hosted pages.
Email Verification
Receive OTP code, enter it → Verified
Phone Verification
Receive SMS OTP, enter it → Verified
Document Verification
Upload passport/ID → Data extraction and validation
Biometric Enrollment
Face enrollment with liveness detection, voice enrollment → Unique identity ID (OBD-XXXXXX)
Custom Forms (if any)
Answer additional questions you configured
Consent Screen
After all verifications complete, user sees consent screen showing what data your app will receive.
Example consent screen:
"YourApp is requesting access to:"
- ✓ Your email address (verified)
- ✓ Your phone number (verified)
- ✓ Your full name and date of birth
- ✓ Your passport verification status
User clicks "Allow" or "Deny"
Redirect Back to Your App
User is redirected back to your redirect_uri with an authorization code.
// User lands back on your callback URL:https://yourapp.com/callback?code=AUTH_CODE_HERE&state=random_csrf_token
// Your app extracts the code:const urlParams = new URLSearchParams(window.location.search);const code = urlParams.get('code');const state = urlParams.get('state');
// Verify state matches (CSRF protection)if (state !== savedState) { throw new Error('Invalid state parameter');}Exchange Code for Access Token (Backend)
Your backend exchanges the authorization code for an access token. This MUST happen on your server because it requires your client_secret.
// Backend API endpointapp.post('/api/auth/callback', async (req, res) => { const { code } = req.body;
// Exchange code for tokens const tokenResponse = await fetch('https://api.onboarder.com/api/v1/oauth/token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ grant_type: 'authorization_code', code, client_id: process.env.UNBOARDER_CLIENT_ID, client_secret: process.env.UNBOARDER_CLIENT_SECRET, // NEVER expose in frontend! redirect_uri: 'https://yourapp.com/callback' }) });
const { access_token, refresh_token } = await tokenResponse.json();
// Store tokens securely (httpOnly cookies, session, database) res.cookie('access_token', access_token, { httpOnly: true, secure: true, sameSite: 'strict' });
return res.json({ success: true });});Get Verified User Data
Use the access token to fetch the user's verified information from Onboarder's /userinfo endpoint.
// Fetch user dataconst userResponse = await fetch('https://api.onboarder.com/api/v1/oauth/userinfo', { headers: { 'Authorization': `Bearer ${access_token}` }});
const userData = await userResponse.json();
// Example response:{ "sub": "user_abc123", // Unique user ID "email": "john@example.com", "email_verified": true, "phone": "+1234567890", "phone_verified": true, "given_name": "John", "family_name": "Doe", "birthdate": "1990-01-15", "picture": "https://...",
"verifications": { "email": { "verified": true, "verifiedAt": "2025-01-15T10:00:00Z" }, "phone": { "verified": true, "verifiedAt": "2025-01-15T10:05:00Z" }, "passport": { "verified": true, "verifiedAt": "2025-01-15T10:10:00Z", "documentNumber": "X12345678", "documentCountry": "US", "documentType": "passport", "expiryDate": "2030-01-15" }, "liveness": { "verified": true, "verifiedAt": "2025-01-15T10:10:00Z", "confidence": 0.98 } }}Create User Session
Now you have verified user data! Create a session in your app, save the user to your database, and grant them access.
// Save user to your databaseconst user = await db.users.create({ unboarderId: userData.sub, email: userData.email, emailVerified: userData.email_verified, phone: userData.phone, phoneVerified: userData.phone_verified, firstName: userData.given_name, lastName: userData.family_name, dateOfBirth: userData.birthdate, passportVerified: userData.verifications.passport.verified, passportNumber: userData.verifications.passport.documentNumber, // ... store whatever you need});
// Create sessionreq.session.userId = user.id;
// User is now logged in and verified! 🎉🎯 Key Takeaways
- You don't build any verification UI - Onboarder hosts everything
- Users verify once - they can sign into multiple apps without re-verifying
- You control requirements via verification flows - change anytime without code changes
- Standard OAuth 2.0 - works with any framework or language
- Get verified data via simple API call - no verification state management needed