Platform Integration Layers
Overview
This guide enables partners to build identity verification solutions that are use case agnostic and support both initial identity establishment and fast re-verification flows. The integration uses CLEAR's User Profile Matching technology to bind verified identity to customer employee records, enabling seamless authentication across multiple use cases.
Key Outcome: Once a user completes identity establishment, all subsequent verifications across any use case become fast, friction-reduced selfie-only flows.
Integration Layers: What Partners Must Build
A complete CLEAR integration requires partners to build two critical layers:
Layer 1: Admin Configuration Experience
The backend configuration and setup that enables customers to connect their CLEAR environment to your platform. This includes:
- CLEAR Environment Provisioning: How customers obtain CLEAR credentials
- Credential Management: Where customers input and manage their Project IDs and API keys
- Workflow Configuration: Defining which use cases trigger CLEAR verification
- Data Mapping Configuration: Specifying which customer fields map to CLEAR data
Layer 2: Customer End User Experience
The actual verification flow that your customer's end users (their employees/users) experience. Once your customer configures CLEAR credentials (Layer 1), their end users can verify their identity. This layer is about facilitating the standard CLEAR integration experience for your customers:
Core Integration Components:
- Create Verification Session (API Docs): Initiate CLEAR verification with the right project and data
- Get Verification Results (API Docs): Retrieve session results and map data back to user records
- User Profile Matching Logic: Check if CLEAR userID exists, route to appropriate flow (Project A with UPM or Project B with known user key)
- Result Retrieval Mechanism: Define redirect path to pull verification results (redirect, polling, or button-triggered)
What Partners Must Build:
- Data System Check: Mechanism to check if CLEAR userID exists on user record
- Flow Routing:
- If no userID → Create session with Project A (User Profile Matching), send
employee_idincustom_fields - If userID exists → Create session with Project B (Known User Key), send
user_idin request
- If no userID → Create session with Project A (User Profile Matching), send
- Redirect Path Definition: Specify
redirect_urlin both create session API calls - Result Processing: When user redirects back, call Get Verification endpoint to retrieve results
- Data Correlation: Map returned data back to correct user record using
employee_idfromcustom_fields - UserID Storage: Store CLEAR
user_idwhen User Profile Matching returnsmatch_result: "match"
User Experience Patterns:
- Traditional Web Application: Pre-verification screen → CLEAR verification → Post-verification landing screen
- Terminal Screen: CLEAR ends on final screen, results retrieved via polling or agent-triggered button
- Call Center Assisted: Agent helps user verify, retrieves results manually
Key Point: The end goal is to create the session, retrieve results, and map the verified identity back to the correct user record by correlating data.
Both layers must work together seamlessly to deliver a complete identity verification solution.
Layer 1: Admin Configuration Experience
Overview
Before any end user can verify their identity with CLEAR, your platform must enable customers (admins/IT teams) to configure CLEAR within your system. This configuration determines:
- Which CLEAR environment and projects power the verification
- Who owns and controls the verification data
- Which workflows and use cases trigger CLEAR
- Where and how data is stored
Configuration Options for Partners
Partners must implement at minimum Option A (Bring Your Own Keys). Option B (Self-Service Procurement) is optional but recommended for a seamless customer experience.
Option A: Bring Your Own Keys (BYOK) - REQUIRED
What It Is: A configuration interface that allows customers to input their own CLEAR environment credentials (Project IDs and API keys) obtained directly from CLEAR.
Why It's Critical: Ensures customers own and control their verification data. Data flows through customer-specific CLEAR tenants, not shared infrastructure. This is a fundamental requirement for enterprise security and compliance.
What Partners Must Build:
-
Admin Configuration UI - A secure settings page where authorized admins can input:
- Establish Identity Project ID: For first-time verification with User Profile Matching
- Known User Key Project ID: For fast re-verification flows
- API Key: Authentication credential (supports both projects)
- Environment Selection: Production vs. Sandbox
-
Credential Storage - Secure backend storage for customer-specific CLEAR credentials:
- Encrypted at rest
- Scoped per customer/tenant
- Accessible only to authorized platform services
-
Credential Validation - Test connectivity before saving:
async function validateClearCredentials(projectId, apiKey) { try { // Validate by attempting to create a test session const response = await fetch('https://verified.clearme.com/v1/verification_sessions', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ project_id: projectId, redirect_url: 'https://yourapp.com/test', custom_fields: { test: 'validation' } }) }); // Valid credentials return 200/201 return response.ok; } catch (error) { return false; } }Note: There is no dedicated
/validateendpoint. Validate credentials by creating a test session and checking for a successful response (200/201 status).
Implementation Checklist:
- Secure settings page accessible only to authorized admins
- Input fields for both Project IDs and API Key
- Credential validation before saving
- Encrypted storage of credentials
- Credential rotation support
- Audit logging of configuration changes
Option B: Self-Service Procurement (OPTIONAL)
What It Is: Enable customers to provision CLEAR environments, create projects, and generate credentials directly through your platform using CLEAR's provisioning APIs. Credentials are automatically populated into the BYOK configuration UI.
Why Consider It:
- Reduces customer friction (no need to contact CLEAR separately)
- Faster time-to-value (instant provisioning vs. manual setup)
- Seamless customer experience (never leave your platform)
- Automatic credential management
How to Implement:
Self-service procurement requires access to CLEAR's provisioning APIs, which are not yet publicly available.
To enable Option B, please contact CLEAR:
- Email: [email protected]
- Request: Access to provisioning APIs, code samples, and API reference documentation
- What You'll Receive:
- Provisioning API credentials
- Complete API reference for environment and project creation
- Code samples for orchestrating the provisioning workflow
- Integration guide for automatic credential population
- Testing environment access
Workflow Configuration
Once CLEAR credentials are configured, admins must define where and when CLEAR verification is triggered.
Key Configuration Points:
-
Use Case Selection: Which workflows require CLEAR verification?
- Employee onboarding
- Password reset
- Account recovery
- High-risk transactions
- Conditional access (new device/location)
- VPN/network access
- Application access
-
Trigger Conditions: When should verification be required?
- Always (every login)
- Conditional (risk-based triggers)
- On-demand (user-initiated)
- Periodic (time-based re-verification)
-
Flow Routing Logic: Which CLEAR project to use?
- If
clear_user_idexists → Known User Key Project - If
clear_user_idnull → Establish Identity Project
- If
Data Mapping Configuration
Admins must specify which fields from their user database map to CLEAR's expected fields for User Profile Matching.
Required Mappings:
| CLEAR Field | Customer Field (Example) | Required For |
|---|---|---|
employee_id | employee_id or user_id | Establish Identity |
first_name | first_name or given_name | Establish Identity |
last_name | last_name or family_name | Establish Identity |
date_of_birth | dob or birth_date | Establish Identity |
email | email or work_email | Optional |
Layer 2: Customer End User Experience
Overview
This layer enables your customer's end users (their employees) to complete identity verification through CLEAR. Once customers configure their CLEAR credentials in Layer 1, their end users can verify. This layer implements the core CLEAR integration workflow.
What This Layer Does:
Partners facilitate the standard CLEAR verification flow documented at:
- Create Verification Session: Initiate verification
- Get Verification: Retrieve results
The Critical Addition: User Profile Matching (UPM)
When creating a session, partners must check if the user has a stored CLEAR userID:
- No CLEAR userID exists → Use Project A (configured for User Profile Matching):
- Send
employee_id,first_name,last_name,date_of_birthincustom_fields - CLEAR performs biometric verification AND matches verified data against the data you sent
- Result includes
match_result: "match"ormatch_result: "no_match" - If match succeeds, store the returned CLEAR
user_idto the user record
- Send
- CLEAR userID exists → Use Project B (re-verification):
- Send the stored CLEAR
user_idin the request - User completes selfie-only flow (3-5 seconds)
- Verify returned
user_idmatches storeduser_id
- Send the stored CLEAR
CLEAR Owns the Matching: When using User Profile Matching, CLEAR determines if the verified identity data matches the employee data you sent. The verification result tells you two things:
- Did the user pass CLEAR verification? (document valid, selfie matches ID)
- Did the verified data match the employee data you sent? (
match_result)
Three Core Components Partners Must Build:
- End User Experience Design: Where CLEAR is triggered, what the user sees before/during/after verification, error handling, and success paths
- User Matching & Verification Logic: Check for CLEAR userID, route to correct project, process match results, store userID
- Data Storage & Correlation: Store CLEAR userID, map results back to correct user record using
employee_id, retrieve verification data
Component 1: End User Experience Design
Partners must design and implement the following UX touchpoints:
1. Verification Trigger Points
Question: Where and how is CLEAR verification initiated?
Common Trigger Patterns:
A. Button/Link Click
User explicitly clicks a button to start verification.
When to Use: Password reset, account recovery, on-demand verification
B. Automatic Redirect
System automatically redirects user to CLEAR when conditions are met.
async function handleLogin(username, password) {
const user = await authenticateCredentials(username, password);
// Check if conditional access verification required
if (isNewDevice(user.id) || isHighRiskLogin(user.id)) {
// Automatic redirect to CLEAR
const sessionUrl = await initiateVerification(user.id, 'conditional_access');
return redirect(sessionUrl);
}
// Normal login flow
return redirect('/dashboard');
}When to Use: Conditional access, risk-based authentication
C. Workflow Step
CLEAR verification as part of a multi-step process.
Step 1: Create Account → Step 2: Verify Identity → Step 3: Set Preferences
(CLEAR verification)
When to Use: Employee onboarding, account setup flows
D. SMS/Email Link
User receives a message with a link to start verification.
SMS: "To complete your account recovery, verify your identity:
https://yourapp.com/verify/abc123"
When to Use: Async verification requests, out-of-band authentication
2. Pre-Verification Experience
Question: What does the user see immediately before entering CLEAR?
Design Considerations:
A. Context Setting
Explain why verification is needed and what will happen (e.g., "We need to verify your identity to reset your password. You'll scan a photo ID and take a quick selfie. Verification completes in under 60 seconds.").
B. Returning User (Known User Key)
Provide a different message for users who have already completed their first verification (e.g., "Welcome back! We just need a quick selfie to verify it's you. This will only take 3-5 seconds.").
Implementation:
async function showPreVerificationScreen(userId) {
const user = await getUserProfile(userId);
if (user.clear_user_id) {
// Returning user - show Known User Key message
return renderScreen('quick_verification_prompt');
} else {
// New user - show full Establish Identity message
return renderScreen('full_verification_prompt');
}
}3. CLEAR Session Flow
Question: How does the user navigate to and from CLEAR?
Required Pattern: Full Redirect
CLEAR verification must redirect the user outside of the partner application. Popups and iframe embeds are not supported.
User leaves partner app entirely, completes CLEAR verification, and is redirected back to partner app.
Partner App → CLEAR Verification → Partner App
(redirect) (verify.clearme.com) (redirect_url callback)
Implementation:
async function initiateVerification(userId) {
// 1. Create session and get token
const session = await createClearSession(userId);
// 2. Construct CLEAR verification URL with token
const verificationUrl = `https://verified.clearme.com/verify?token=${session.token}`;
// 3. Full page redirect to CLEAR
window.location.href = verificationUrl;
}
// User completes verification on CLEAR's site, then CLEAR redirects back
// to the redirect_url you specified during session creation
// Callback endpoint handles the return
app.get('/verify/confirmation', async (req, res) => {
const sessionId = req.query.session_id;
const results = await getSessionResults(sessionId);
await processResults(results);
res.redirect('/verification/success');
});Why Full Redirect Is Required:
- Ensures consistent user experience across all devices
- Avoids popup blocker issues
- Works reliably on mobile devices
- Maintains CLEAR's security and verification integrity
- No complex iframe or postMessage handling needed
4. Post-Verification Experience
Question: What happens after CLEAR returns the user?
Critical Steps:
A. Loading/Processing State
Show user that verification is being processed (e.g., loading spinner with message "Verifying your identity... This may take a few seconds.").
B. Retrieve Session Results
Fetch verification data from CLEAR.
app.get('/clear/callback', async (req, res) => {
const sessionId = req.query.session_id;
try {
// Show loading screen
res.send(renderLoadingScreen());
// Fetch results (redirect or polling)
const results = await getSessionResults(sessionId);
// Process based on flow type
if (results.mode === 'user_profile_matching') {
await handleEstablishIdentityResults(results);
} else {
await handleKnownUserKeyResults(results);
}
// Redirect to success
res.redirect('/verification/success');
} catch (error) {
res.redirect(`/verification/error?reason=${error.message}`);
}
});C. Success Path
User verification succeeded - grant access and provide confirmation (e.g., "Identity Verified Successfully. Your identity has been confirmed. You can now proceed with your password reset.").
Implementation:
async function handleEstablishIdentityResults(results) {
if (results.status === 'completed' && results.match_result === 'match') {
// Store CLEAR userID
await updateUserProfile(results.custom_fields.employee_id, {
clear_user_id: results.user_id,
identity_verified_at: new Date()
});
// Grant access
await grantWorkflowAccess(results.custom_fields.employee_id);
// Log success event
await logEvent('verification_success', {
employee_id: results.custom_fields.employee_id,
session_id: results.session_id,
flow_type: 'establish_identity'
});
}
}D. Failure Paths
Handle various failure scenarios gracefully:
Scenario 1: Verification Failed - Unable to verify identity (e.g., unclear ID, poor lighting, information mismatch). Provide retry option and support contact.
Scenario 2: User Profile Match Failed (Establish Identity) - Verified identity doesn't match employee record on file. Direct user to contact IT/HR to update employee information. Include session reference code.
Scenario 3: UserID Mismatch (Known User Key) - Verified identity doesn't match stored userID. This is a security event - log it, notify administrators, and provide clear messaging about potential unauthorized access attempt.
Scenario 4: Session Expired - Verification session timed out. Provide option to start new verification.
Error Handling Implementation:
async function processVerificationResults(results) {
// Handle different statuses
switch (results.status) {
case 'completed':
if (results.match_result === 'match') {
return handleSuccess(results);
} else if (results.match_result === 'no_match') {
return handleProfileMismatch(results);
}
break;
case 'failed':
return handleVerificationFailed(results);
case 'expired':
return handleSessionExpired(results);
case 'cancelled':
return handleUserCancelled(results);
default:
return handleUnknownError(results);
}
}
async function handleVerificationFailed(results) {
// Log failure
await logEvent('verification_failed', {
employee_id: results.custom_fields?.employee_id,
session_id: results.session_id,
reason: results.failure_reason
});
// Show user-friendly error
return renderErrorScreen('verification_failed', {
canRetry: true,
supportContact: '[email protected]'
});
}Component 2: User Matching & Verification Logic
Overview
This component handles how users are matched to their records during verification and how the system validates identity on subsequent verifications.
First-Time Verification: User Profile Matching (UPM)
Purpose: Match the verified identity data from CLEAR against the customer's employee/user records to ensure the right person is accessing the right account.
How It Works:
-
Customer sends employee data in the session creation request:
{ project_id: "proj_abc123", redirect_url: "https://yourapp.com/verify/confirmation", custom_fields: { employeeID: "EMP12345" // For correlation only }, user_profile_information: { // Biographic data for matching name: { first_name: "Jane", last_name: "Smith" }, dob: "1990-05-15" } }Important:
custom_fieldsis for correlation data only (e.g., employeeID, department, etc.)user_profile_informationcontains the biographic data CLEAR will match against
-
User completes CLEAR verification (ID scan + selfie)
-
CLEAR performs biometric matching:
- Extracts data from government-issued ID
- Matches selfie to ID photo using facial biometrics
- Compares verified data to employee data sent in
user_profile_information - If data matches, returns
user_idin the response - If data doesn't match, no
user_idis returned
-
Partner validates the match:
if (results.user_id) { // Success: Verified identity matches employee record // Store CLEAR userID to employee profile await updateUserProfile(employeeId, { clear_user_id: results.user_id }); } else { // No match: Verified identity doesn't match employee data // Flag for manual review await flagForReview(employeeId, results); }
Key Point: User Profile Matching ensures the person verifying is the same person as the employee record, preventing account takeover or identity confusion.
Subsequent Verifications: UserID-to-UserID Matching
Purpose: On subsequent verifications, match the CLEAR userID returned from the session against the stored userID on the employee profile.
How It Works:
-
Partner sends stored userID in the session creation request:
{ project_id: "known_user_key_project_id", user_id: "psuid_abc123def456" // From employee profile } -
User completes selfie-only verification (3-5 seconds)
-
CLEAR matches selfie to stored biometric using the provided userID
-
Partner validates userID match:
const storedUserId = userProfile.clear_user_id; const returnedUserId = results.user_id; if (returnedUserId === storedUserId) { // Success: UserIDs match await grantAccess(employeeId); } else { // SECURITY ALERT: UserID mismatch await logSecurityAlert({ employee_id: employeeId, stored_user_id: storedUserId, returned_user_id: returnedUserId }); throw new Error('Unauthorized access attempt'); }
Key Point: UserID-to-userID matching prevents unauthorized users from accessing accounts even if they bypass initial verification flows.
Component 3: Data Storage Strategy
Overview
After verification, partners must decide what data from the CLEAR session to store on user profiles. The requirements vary based on your system's capabilities and compliance needs.
Required Data (Minimum)
Always store these fields:
await updateUserProfile(employeeId, {
// REQUIRED: Enables Known User Key flow
clear_user_id: results.user_id, // e.g., "psuid_abc123def456"
// REQUIRED: Audit and troubleshooting
verification_session_id: results.session_id, // e.g., "session_xyz789"
// REQUIRED: Timestamps for compliance
identity_verified_at: new Date()
});Why Required:
- clear_user_id: Without this, you cannot use Known User Key flow. Every verification would require full ID + selfie.
- verification_session_id: Essential for audit trails, troubleshooting, and linking back to CLEAR session data.
- identity_verified_at: Compliance requirement for tracking when identity was last verified.
Recommended Data (If Your System Supports PII Storage)
If your system can store PII, we recommend also storing verified data from the CLEAR session:
await updateUserProfile(employeeId, {
// Required minimum
clear_user_id: results.user_id,
verification_session_id: results.session_id,
identity_verified_at: new Date(),
// RECOMMENDED: Verified PII from government-issued ID
verified_first_name: results.verified_data.first_name,
verified_last_name: results.verified_data.last_name,
verified_dob: results.verified_data.date_of_birth,
verified_address: results.verified_data.address,
// RECOMMENDED: Document metadata
document_type: results.verified_data.document_type, // "drivers_license", "passport"
document_number: results.verified_data.document_number,
document_expiration: results.verified_data.document_expiration,
// RECOMMENDED: Contact information
verified_phone_number: results.verified_data.phone_number,
verified_email: results.verified_data.email,
// RECOMMENDED: Audit metadata
match_result: results.match_result, // "match" or "no_match"
verification_method: 'clear_user_profile_matching'
});Why Recommended:
- System of Record: Your platform becomes the authoritative source for verified employee data
- Compliance: Meets regulatory requirements for identity verification documentation
- Audit Trail: Complete record of what data was verified and when
- Reconciliation: Compare stored data against employee records to detect discrepancies
- User Profile Enhancement: Populate or update employee profiles with verified, authoritative data
Optional Data (Not Required If PII Storage Is Not Allowed)
If your system cannot store PII (due to data minimization policies, GDPR, or security constraints):
await updateUserProfile(employeeId, {
// Only store required minimum
clear_user_id: results.user_id,
verification_session_id: results.session_id,
identity_verified_at: new Date(),
// NO verified PII stored
});When to Use This Approach:
- Data minimization requirements
- Systems with limited PII storage capabilities
- Environments where PII storage increases compliance burden
- Known User Key flow still works (only requires
clear_user_id)
Trade-offs:
- Cannot use verified data for profile updates or reconciliation
- Must rely on session_id to look up historical verification data if needed
- Limited audit trail visibility without accessing CLEAR API
Known User Key Flow: Event Logging Only
On subsequent verifications (Known User Key), DO NOT update stored data. Only log the verification event:
// DO NOT update clear_user_id (already stored)
// Only log the verification event
await logVerificationEvent({
employee_id: employeeId,
session_id: results.session_id,
clear_user_id: results.user_id,
verification_type: 'known_user_key',
verified_at: new Date(),
use_case: 'password_reset', // Or 'conditional_access', etc.
result: 'success'
});Why: The userID never changes, so no profile updates are needed. Only track that verification occurred.
Data Retention Guidelines
| Data Type | Retention Period | Purpose |
|---|---|---|
| clear_user_id | Permanent | Required for all future verifications |
| verification_session_id | 90 days minimum | Audit and troubleshooting |
| Verified PII | Per compliance policy | System of record, reconciliation |
| Verification logs | 1-7 years typical | Compliance and security audit |
| Session metadata | 90 days minimum | Debugging and support |
Component 4: Result Retrieval & Data Correlation
Overview
After the user completes CLEAR verification, partners MUST retrieve the session results and map the data back to the correct user record. This is a required step to complete the verification workflow.
Critical Requirement: Define a redirect_url in BOTH create session API calls (User Profile Matching and Known User Key). This enables the system to retrieve results when the user is redirected back to your application.
Three Methods to Retrieve Results
Partners must implement at least one method to retrieve verification results:
Method 1: Redirect (RECOMMENDED - Most Common)
How It Works:
- When creating the session, include
redirect_url:{ "project_id": "proj_abc123", "redirect_url": "https://yourapp.com/clear/callback?employee_id={employee_id}" } - User completes CLEAR verification
- User is redirected back to your callback URL with
session_idparameter - Your system calls Get Verification to retrieve results
- Map results back to user record using
employee_idfromcustom_fields
When to Use:
- Standard web application flows (most common pattern)
- User-present verification (login, password reset, onboarding)
- Browser-based experiences
- Real-time user feedback required
Implementation:
// Helper function to create verification session
async function createVerificationSession(
apiKey,
projectId,
redirectUrl,
employeeId,
pii, // { first_name, last_name, dob } for User Profile Matching
userId // CLEAR user_id for re-verification
) {
const body = {
project_id: projectId,
redirect_url: redirectUrl,
custom_fields: { employeeID: employeeId },
};
// If userId provided, this is re-verification
if (userId) {
body.user_id = userId;
} else if (pii) {
// Otherwise, use User Profile Matching for initial verification
body.user_profile_information = {
name: {
first_name: pii.first_name,
last_name: pii.last_name,
},
dob: pii.dob,
};
}
const response = await fetch('https://verified.clearme.com/v1/verification_sessions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || 'Failed to create CLEAR verification session');
}
return data; // { id, token, status }
}
// 1. Create session with redirect_url
app.post('/create-session', async (req, res) => {
const { employeeId } = req.body;
// Look up employee
const employee = await getEmployeeById(employeeId);
// Determine if this is initial verification or re-verification
const isReverification = !!employee.clear_user_id;
const redirectUrl = `https://yourapp.com/verify/confirmation`;
let clearSession;
if (isReverification) {
// Re-verification with Known User Key
clearSession = await createVerificationSession(
apiKey,
reverificationProjectId,
redirectUrl,
employee.employee_id,
undefined,
employee.clear_user_id // Pass stored userID
);
} else {
// Initial verification with User Profile Matching
const pii = {
first_name: employee.first_name,
last_name: employee.last_name,
dob: employee.date_of_birth
};
clearSession = await createVerificationSession(
apiKey,
initialProjectId,
redirectUrl,
employee.employee_id,
pii,
undefined
);
}
// Save session to database
await saveSession({
employee_id: employee.id,
clear_session_id: clearSession.id,
status: 'pending'
});
// Return token to frontend
res.json({ token: clearSession.token });
});
// 2. Frontend redirects user to CLEAR
// window.location.href = `https://verified.clearme.com/verify?token=${token}`;
// 3. Handle redirect callback
app.get('/verify/confirmation', async (req, res) => {
// User was redirected back from CLEAR
// Now retrieve results using Get Verification endpoint
const { sessionId } = req.query; // Your internal session ID
// Look up session
const session = await getSessionById(sessionId);
// Get results from CLEAR
const response = await fetch(
`https://verified.clearme.com/v1/verification_sessions/${session.clear_session_id}`,
{
method: 'GET',
headers: {
'Authorization': `Bearer ${apiKey}`,
},
}
);
const clearData = await response.json();
// Extract employee_id from custom_fields to map back to correct record
const employeeId = clearData.custom_fields.employeeID;
// Process and store results
await processResults(employeeId, clearData);
// Show success screen
res.redirect('/verification/success');
});User Experience Pattern:
[Pre-Verification Screen] → [CLEAR Verification] → [Post-Verification Landing Screen]
Your Application CLEAR Your Application (with results)
Method 2: Polling
How It Works:
- Create session and redirect user to CLEAR
- Periodically poll Get Verification endpoint
- When
statuschanges tocompleted,failed, orexpired, retrieve results - Map results back to user record
When to Use:
- Terminal screen flows (CLEAR ends on final screen)
- Call center assisted verification (agent triggers result retrieval)
- Async workflows (background verification)
- Mobile apps with deep linking
- SMS/Email initiated flows
Implementation:
// Helper function to get verification session
async function getVerificationSession(apiKey, clearSessionId) {
const response = await fetch(
`https://verified.clearme.com/v1/verification_sessions/${clearSessionId}`,
{
method: 'GET',
headers: {
'Authorization': `Bearer ${apiKey}`,
},
}
);
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || 'Failed to get CLEAR verification session');
}
return data;
}
// Polling implementation
async function pollForResults(apiKey, clearSessionId, employeeId) {
const maxAttempts = 60; // 2 minutes with 2-second intervals
for (let i = 0; i < maxAttempts; i++) {
const clearData = await getVerificationSession(apiKey, clearSessionId);
// Check for completion
const isComplete = clearData.status === 'complete' ||
clearData.status === 'success' ||
clearData.status === 'completed';
if (isComplete) {
console.log('Verification complete!');
console.log('Status:', clearData.status);
console.log('user_id:', clearData.user_id);
// Map results back using employee_id from custom_fields
const employeeIdFromClear = clearData.custom_fields.employeeID;
await processResults(employeeIdFromClear, clearData);
return clearData;
} else if (clearData.status === 'failed' || clearData.status === 'expired') {
throw new Error(`Session ${clearData.status}`);
}
console.log(`Polling attempt ${i + 1}/${maxAttempts}, status: ${clearData.status}`);
// Wait 2 seconds before next poll
await new Promise(resolve => setTimeout(resolve, 2000));
}
throw new Error('Polling timeout - verification took too long');
}
// Usage
app.get('/poll-status/:sessionId', async (req, res) => {
const { sessionId } = req.params;
// Look up session
const session = await getSessionById(sessionId);
try {
const results = await pollForResults(
apiKey,
session.clear_session_id,
session.employee_id
);
res.json({ success: true, results });
} catch (error) {
res.status(500).json({ error: error.message });
}
});Method 3: Agent/Button-Triggered Retrieval
How It Works:
- User completes CLEAR verification (ends on terminal screen)
- Agent or automated system clicks button to retrieve results
- System calls Get Verification endpoint
- Results mapped back to user record
When to Use:
- Call center scenarios (agent assists user with verification)
- Administrative workflows (manual review required)
- Kiosk or in-person verification scenarios
Implementation:
// Agent clicks "Retrieve Results" button
app.post('/admin/retrieve-verification', async (req, res) => {
const { sessionId } = req.body;
try {
// Look up session
const session = await getSessionById(sessionId);
// Retrieve results from CLEAR
const clearData = await getVerificationSession(apiKey, session.clear_session_id);
console.log('=== VERIFICATION RESULTS ===');
console.log('Status:', clearData.status);
console.log('user_id:', clearData.user_id);
console.log('Custom fields:', clearData.custom_fields);
// Extract employee_id to map back to correct record
const employeeId = clearData.custom_fields.employeeID;
// Process and store results
await processResults(employeeId, clearData);
res.json({ success: true, clearData });
} catch (error) {
console.error('Error retrieving verification:', error);
res.status(500).json({ error: error.message });
}
});Data Correlation: Mapping Results to User Records
Critical Step: After retrieving results, map the verified identity data back to the correct user record.
How to Correlate:
-
Use
employee_idfromcustom_fields:const employeeId = results.custom_fields.employee_id; const userRecord = await getUserProfile(employeeId); -
For User Profile Matching (first-time):
- Check
match_result === "match" - If match, store
results.user_idto user record - If no match, flag for manual review
- Check
-
For Known User Key (returning):
- Verify
results.user_id === userRecord.clear_user_id - If mismatch, trigger security alert
- Verify
Example Complete Flow (from real production code):
async function processResults(clearSessionId, apiKey) {
// 1. Get verification data from CLEAR
const clearData = await getVerificationSession(apiKey, clearSessionId);
console.log('=== PROCESSING VERIFICATION RESULTS ===');
console.log('CLEAR Status:', clearData.status);
console.log('CLEAR user_id:', clearData.user_id);
// 2. Extract employee_id from custom_fields to map back
const employeeId = clearData.custom_fields.employeeID;
console.log('Employee ID:', employeeId);
// 3. Fetch user record
const employee = await getEmployeeById(employeeId);
console.log('Current employee clear_user_id:', employee.clear_user_id);
// 4. Route based on flow type
const isComplete = clearData.status === 'complete' ||
clearData.status === 'success' ||
clearData.status === 'completed';
if (isComplete && clearData.user_id) {
if (!employee.clear_user_id) {
// First-time verification with User Profile Matching
console.log('🔄 First-time verification complete! Saving user_id...');
// Store CLEAR userID to employee record
await updateEmployee(employee.id, {
clear_user_id: clearData.user_id,
identity_verified_at: new Date()
});
console.log('✅ Successfully saved user_id to employee record');
// Log verification event
await logVerificationEvent({
employee_id: employee.id,
clear_user_id: clearData.user_id,
verification_type: 'initial',
status: 'success'
});
} else {
// Returning user verification (Known User Key)
console.log('🔄 Re-verification complete. Validating user_id...');
if (clearData.user_id === employee.clear_user_id) {
console.log('✅ user_id matches! Re-verification successful');
// Log verification event (don't update employee record)
await logVerificationEvent({
employee_id: employee.id,
clear_user_id: clearData.user_id,
verification_type: 'reverification',
status: 'success'
});
} else {
// SECURITY ALERT - userID mismatch
console.error('❌ SECURITY ALERT: user_id mismatch!');
console.error('Expected:', employee.clear_user_id);
console.error('Received:', clearData.user_id);
await triggerSecurityAlert({
employee_id: employee.id,
stored_user_id: employee.clear_user_id,
returned_user_id: clearData.user_id,
alert_type: 'user_id_mismatch'
});
throw new Error('UserID mismatch - unauthorized access attempt');
}
}
} else {
console.log('⏸️ Verification not complete. Status:', clearData.status);
}
console.log('=== END PROCESSING ===');
return clearData;
}Key Takeaways
✅ Always define redirect_url in create session requests (required for traditional web flows)
✅ Choose a retrieval method that matches your use case (redirect, polling, or button-triggered)
✅ Retrieve results using Get Verification endpoint: https://docs.clearme.com/reference/get_verification
✅ Map results back to user records using employee_id from custom_fields
✅ Store CLEAR userID when User Profile Matching returns match_result: "match"
✅ Validate userID match on subsequent verifications to prevent unauthorized access
End User Experience Checklist
Use this checklist to ensure complete end user experience implementation:
Pre-Verification:
- Clear context explaining why verification is required
- Different messaging for new vs. returning users
- Instructions on what to expect
- Cancel/back option if verification is optional
Verification Flow:
- Seamless navigation to CLEAR (redirect/popup/iframe)
- Consistent branding throughout journey
- Mobile-responsive design
- Loading states during transitions
Post-Verification:
- Loading indicator while processing results
- Clear success confirmation message
- Appropriate error messages for all failure scenarios
- Retry mechanism for recoverable errors
- Support contact information for unrecoverable errors
Data Handling:
- Store clear_user_id to user profile immediately
- Log all verification events for audit
- Handle session expiration gracefully
- Implement proper error logging and monitoring
Security:
- Verify userID match on Known User Key flows
- Log suspicious activity (userID mismatches)
- Implement rate limiting on verification attempts
- Secure credential storage and transmission
Updated 5 days ago