Onboarder

API Documentation

OAuth 2.0 API Reference

Manual OAuth implementation for any backend language (Python, PHP, Ruby, Go, Java, etc.)

When to use Manual OAuth

Use this approach if you're building with a backend framework and want full control over the OAuth flow.

Backend frameworks (Django, Laravel, Rails, Express, Spring Boot)
Mobile apps (iOS, Android, React Native, Flutter)
Desktop applications

OAuth Flow Overview

  1. 1User clicks "Sign in with Onboarder" in your app
  2. 2Your app redirects to /oauth/authorize with client_id and flow_id
  3. 3User completes verification on Onboarder's hosted UI
  4. 4Onboarder redirects back with authorization code
  5. 5Your backend exchanges code for access_token
  6. 6Fetch verified user data from /oauth/userinfo

Base URL

# Production
https://api.onboarder.com/api/v1
# Sandbox (for testing)
https://api.onboarder.com/api/v1

Step 1: Authorization Request

Redirect the user to Onboarder's authorization endpoint to begin verification.

GET/oauth/authorize

Query Parameters

ParameterTypeRequiredDescription
client_idstring✅ YesYour platform's client ID from dashboard
flow_idUUID✅ YesVerification flow ID (defines requirements)
redirect_uriURL✅ YesCallback URL (must match dashboard config)
response_typestring✅ YesMust be "code" (authorization code flow)
statestring⚠️ RecommendedRandom string for CSRF protection
scopestring❌ NoSpace-separated scopes (e.g., "profile email phone")
code_challengestring❌ NoPKCE challenge (recommended for public clients)
code_challenge_methodstring❌ No"S256" or "plain" (use with code_challenge)

Example Request

https://api.onboarder.com/api/v1/oauth/authorize?client_id=plt_sandbox_abc123&flow_id=550e8400-e29b-41d4-a716-446655440000&redirect_uri=https://yourapp.com/callback&response_type=code&state=random_csrf_token_xyz&scope=profile email phone

Important: flow_id is required

The flow_id parameter specifies which verification requirements the user must complete. Create verification flows in your dashboard.

Step 2: Handle Callback

After the user completes verification, Onboarder redirects back to your redirect_uri with these query parameters:

ParameterDescription
codeAuthorization code (valid for 10 minutes)
stateSame state value you sent (validate this!)

Example callback URL:

https://yourapp.com/callback?code=auth_code_abc123xyz&state=random_csrf_token_xyz

Security: Always validate the state parameter

Compare the returned state with what you sent to prevent CSRF attacks. If they don't match, reject the request.

Step 3: Exchange Code for Access Token

Exchange the authorization code for an access token. This MUST be done on your backend to keep client_secret secure.

POST/oauth/token

Request Body (JSON)

ParameterTypeRequiredDescription
grant_typestring✅ YesMust be "authorization_code"
codestring✅ YesAuthorization code from callback
client_idstring✅ YesYour platform client ID
client_secretstring✅ YesYour platform client secret (NEVER expose!)
redirect_uriURL✅ YesSame redirect_uri from authorization step
code_verifierstring❌ NoPKCE verifier (if you sent code_challenge)

Response

{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "refresh_token_here",
"scope": "profile email phone"
}

Code Example

import requests
# Exchange code for token
response = requests.post(
'https://api.onboarder.com/api/v1/oauth/token',
json={
'grant_type': 'authorization_code',
'code': auth_code,
'client_id': 'plt_sandbox_abc123',
'client_secret': 'secret_xyz', # Keep this secret!
'redirect_uri': 'https://yourapp.com/callback'
}
)
tokens = response.json()
access_token = tokens['access_token']

Step 4: Get Verified User Data

Use the access token to fetch verified user information.

GET/oauth/userinfo

Headers

Authorization: Bearer YOUR_ACCESS_TOKEN

Response

{
"sub": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"email_verified": true,
"phone": "+1234567890",
"phone_verified": true,
"name": "John Doe",
"given_name": "John",
"family_name": "Doe",
"picture": "https://...",
"verifications": {
"passport": {
"verified": true,
"verified_at": "2025-01-15T10:00:00Z",
"document_number": "X12345678",
"country": "US",
"expiry_date": "2030-01-15"
},
"liveness": {
"verified": true,
"verified_at": "2025-01-15T10:01:00Z"
}
}
}

Code Example

import requests
# Get user info
response = requests.get(
'https://api.onboarder.com/api/v1/oauth/userinfo',
headers={'Authorization': f'Bearer {access_token}'}
)
user_info = response.json()
print(f"User: {user_info['name']}")
print(f"Email verified: {user_info['email_verified']}")
print(f"Phone verified: {user_info['phone_verified']}")

Security Best Practices

1. Always use the state parameter

Generate a random, unguessable string for each authorization request and validate it in the callback to prevent CSRF attacks.

2. Never expose client_secret

Keep client_secret on your backend only. Never include it in frontend code, mobile apps, or version control.

3. Use PKCE for mobile/public clients

For mobile apps or SPAs, implement PKCE (Proof Key for Code Exchange) by sending code_challenge and code_verifier to prevent authorization code interception.

4. Always use HTTPS in production

OAuth requires HTTPS to prevent token interception. Onboarder will reject non-HTTPS redirect URIs in production.

5. Store tokens securely

Use httpOnly cookies for web apps. For mobile apps, use platform-specific secure storage (Keychain on iOS, Keystore on Android).

Error Codes

ErrorDescription
invalid_requestMissing or invalid required parameters
unauthorized_clientInvalid client_id or client_secret
access_deniedUser denied authorization request
invalid_grantInvalid or expired authorization code
invalid_scopeRequested scope is invalid or not allowed
server_errorInternal server error