Integration Guide
Comprehensive guide to integrating okID verification into your application. Choose from JavaScript SDK or Direct API integration.
Integration Methods
JavaScript SDK Integration
Modal-based integration with pre-built UI components. Perfect for web applications.
- 5-minute setup
- Pre-built UI components
- Event-driven architecture
Direct API Integration
Complete control over the verification flow. Build custom experiences for any platform.
- Full customization
- Platform agnostic
- Webhook support
JavaScript SDK Integration
The JavaScript SDK provides a modal-based integration that handles the complete verification flow. It's built using the proven patterns from our integration examples.
1. SDK Setup
Include the SDK files in your HTML:
<!-- Include CSS -->
<link rel="stylesheet" href="modal.css">
<!-- Include SDK files -->
<script src="sdk-config.js"></script>
<script src="verification-sdk.js"></script>
File Location
The SDK files are available in the deprecated/docs/integration/
directory. Copy them to your project's static assets.
2. Configuration
Configure the SDK in sdk-config.js:
window.verificationSDKOptions = {
baseUrl: 'https://verify.test.okid.io', // Your v2client URL
onSuccess: function(data) {
console.log('Verification completed:', data);
// Handle successful verification
// - Update user status in your database
// - Redirect to success page
// - Enable restricted features
},
onError: function(error) {
console.error('Verification error:', error);
// Handle verification error
// - Show error message to user
// - Log error for debugging
// - Provide retry options
},
onClose: function() {
console.log('Modal closed');
// Handle modal close
// - Clean up any temporary state
// - Return to previous screen
}
};
3. Integration Options
Opens verification directly without pre-generating verification ID. Shows QR code page.
// Direct verification
function startVerification() {
VerificationIntegration.startDirectVerification();
}
// Or using SDK class directly
const sdk = new VerificationSDK(options);
sdk.openDirect();
Pre-generates verification ID server-side for better security and control.
// Managed verification
async function startVerification() {
// Generate verification ID server-side
const response = await fetch('/api/generate-verification', {
method: 'POST'
});
const { verification_id } = await response.json();
// Open with verification ID
window.verificationSDK.openWithVerificationId(verification_id);
}
4. Event Handling
Advanced event handling:
// Listen for iframe messages
window.addEventListener('message', (event) => {
if (event.origin !== 'https://verify.test.okid.io') return;
const { type, data } = event.data;
switch (type) {
case 'verification_complete':
handleVerificationSuccess(data);
break;
case 'verification_error':
handleVerificationError(data);
break;
case 'verification_closed':
handleVerificationClosed();
break;
case 'verification_step_change':
handleStepChange(data.step);
break;
}
});
function handleVerificationSuccess(data) {
// Update user status in your system
updateUserVerificationStatus(data.user_id, 'verified');
// Show success message
showSuccessMessage('Verification completed successfully!');
// Redirect or enable features
window.location.href = '/dashboard';
}
5. Error Management
Common Error Scenarios
- • Network connection issues
- • Invalid or expired verification ID
- • Camera/microphone access denied
- • Document validation failures
- • User cancellation
Error handling implementation:
function handleVerificationError(error) {
const errorMessages = {
'network_error': 'Connection failed. Please check your internet connection.',
'invalid_verification_id': 'Session expired. Please start verification again.',
'camera_denied': 'Camera access is required for verification.',
'document_invalid': 'Document could not be validated. Please try again.',
'user_cancelled': 'Verification was cancelled by user.'
};
const message = errorMessages[error.code] || 'Verification failed. Please try again.';
// Show user-friendly error message
showErrorMessage(message);
// Log error for debugging
console.error('Verification error:', error);
// Optionally provide retry option
if (error.code !== 'user_cancelled') {
showRetryButton();
}
}
Direct API Integration
For complete control over the verification flow, integrate directly with the v2client API endpoints.
1. Server-Side Implementation
Security Requirement
API keys must be stored server-side only. Never expose them to client-side code.
// Configure v2client
const config = {
apiKey: process.env.API_KEY,
baseUrl: process.env.V2CLIENT_BASE_URL
};
// Save configuration
await fetch(`${config.baseUrl}/api/save-config`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(config)
});
// Generate verification endpoint
app.post('/api/generate-verification', async (req, res) => {
try {
const response = await fetch(
`${config.baseUrl}/api/generate-verification`,
{ method: 'POST', headers: { 'Content-Type': 'application/json' } }
);
const data = await response.json();
res.json({
verification_id: data.verificationId,
expires_at: data.expiresAt
});
} catch (error) {
res.status(500).json({ error: 'Failed to generate verification' });
}
});
import requests
import os
# Configure v2client
config = {
"apiKey": os.getenv('API_KEY'),
"baseUrl": os.getenv('V2CLIENT_BASE_URL')
}
# Save configuration
requests.post(f"{config['baseUrl']}/api/save-config", json=config)
@app.route('/api/generate-verification', methods=['POST'])
def generate_verification():
try:
response = requests.post(
f"{config['baseUrl']}/api/generate-verification"
)
data = response.json()
return {
"verification_id": data["verificationId"],
"expires_at": data.get("expiresAt")
}
except Exception as e:
return {"error": "Failed to generate verification"}, 500
2. Client-Side Implementation
Complete client-side flow:
class VerificationClient {
constructor(baseUrl) {
this.baseUrl = baseUrl;
}
async startVerification() {
try {
// Step 1: Generate verification ID
const response = await fetch('/api/generate-verification', {
method: 'POST'
});
const { verification_id } = await response.json();
// Step 2: Open verification UI
this.openVerificationUI(verification_id);
} catch (error) {
console.error('Failed to start verification:', error);
this.handleError(error);
}
}
openVerificationUI(verificationId) {
// Option 1: New window
const verificationWindow = window.open(
`${this.baseUrl}/verify?verification_id=${verificationId}`,
'verification',
'width=800,height=600,scrollbars=yes'
);
// Option 2: Iframe
const iframe = document.createElement('iframe');
iframe.src = `${this.baseUrl}/verify?verification_id=${verificationId}`;
iframe.style.width = '100%';
iframe.style.height = '600px';
iframe.allow = 'camera; microphone; geolocation; fullscreen';
document.getElementById('verification-container').appendChild(iframe);
}
handleSuccess(data) {
console.log('Verification completed:', data);
// Update UI, redirect, etc.
}
handleError(error) {
console.error('Verification error:', error);
// Show error message, retry options, etc.
}
}
3. Webhook Handling
Set up webhooks to receive real-time notifications about verification status changes.
Webhook endpoint implementation:
// Webhook endpoint
app.post('/api/webhooks/verification', (req, res) => {
const { verification_id, status, user_data } = req.body;
// Verify webhook signature (recommended)
const signature = req.headers['x-webhook-signature'];
if (!verifyWebhookSignature(req.body, signature)) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Handle different verification statuses
switch (status) {
case 'completed':
handleVerificationCompleted(verification_id, user_data);
break;
case 'failed':
handleVerificationFailed(verification_id, user_data);
break;
case 'expired':
handleVerificationExpired(verification_id);
break;
}
res.json({ received: true });
});
function handleVerificationCompleted(verificationId, userData) {
// Update user status in database
updateUserVerificationStatus(userData.user_id, 'verified');
// Send confirmation email
sendVerificationConfirmationEmail(userData.email);
// Log completion
console.log(`Verification completed for user: ${userData.user_id}`);
}
Security Best Practices
Follow these security best practices to ensure your integration is secure and compliant.
API Key Security
- Store API keys as environment variables
- Never expose API keys to client-side code
- Use different keys for development and production
- Regularly rotate API keys
HTTPS Requirements
- Use HTTPS in production for camera access
- Implement proper SSL/TLS certificates
- Enforce secure communication
- Validate certificate chains
Origin Validation
- Validate message origins in iframe communication
- Implement CORS policies correctly
- Use Content Security Policy (CSP)
- Whitelist allowed domains
Rate Limiting
- Implement rate limiting on verification endpoints
- Monitor API usage patterns
- Set up alerts for unusual activity
- Use authentication for server endpoints
Security Implementation Example
Secure message handling:
// Secure iframe message handling
const ALLOWED_ORIGINS = ['https://verify.test.okid.io', 'https://verify.yourdomain.com'];
window.addEventListener('message', (event) => {
// Validate origin
if (!ALLOWED_ORIGINS.includes(event.origin)) {
console.warn('Rejected message from untrusted origin:', event.origin);
return;
}
// Validate message structure
if (!event.data || typeof event.data !== 'object' || !event.data.type) {
console.warn('Invalid message structure');
return;
}
// Process trusted message
handleTrustedMessage(event.data);
});
// Rate limiting implementation
const rateLimiter = new Map();
function checkRateLimit(userId) {
const now = Date.now();
const userRequests = rateLimiter.get(userId) || [];
// Remove old requests (older than 1 hour)
const recentRequests = userRequests.filter(time => now - time < 3600000);
// Check if user has exceeded limit (5 requests per hour)
if (recentRequests.length >= 5) {
throw new Error('Rate limit exceeded');
}
// Update user requests
recentRequests.push(now);
rateLimiter.set(userId, recentRequests);
}
Ready to Implement?
Choose your integration method and follow the implementation guide. Our examples and documentation will help you get started quickly.