Embeddable proctoring and identity verification widget for secure assessments.
Create an integration to get your API key:
curl -X POST https://secureaccess-api.rr-startech-innovation.workers.dev/api/integrations \
-H "Content-Type: application/json" \
-d '{"name": "My LMS"}'
apiKey - it won't be shown again!Your backend creates a session for each assessment:
// YOUR SERVER - Never expose API key to browser
const response = await fetch('https://secureaccess-api.rr-startech-innovation.workers.dev/api/widget/sessions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
externalUserId: 'student-123',
userName: 'John Doe',
userEmail: 'john@example.com',
assessmentTitle: 'Final Exam',
assessmentType: 'recording', // 'recording' | 'live' | 'hybrid'
facePhotoUrl: 'https://your-lms.com/photos/john.jpg', // Optional
config: {
maxDurationMinutes: 60
}
})
});
const { sessionToken } = await response.json();
// Send sessionToken to the browser
<!-- Include the SDK -->
<script src="https://secureaccess-demo.pages.dev/secureaccess-widget.js"></script>
<!-- Container for the widget -->
<div id="proctoring-widget"></div>
<script>
const widget = new SecureAccessWidget({
apiUrl: 'https://secureaccess-api.rr-startech-innovation.workers.dev',
sessionToken: 'sa_sess_xxx', // From your server
containerId: 'proctoring-widget',
onReady: () => console.log('Widget ready'),
onAuthScoreUpdate: (scores) => console.log('Score:', scores.overall),
onCheatingDetected: (v) => console.log('Violation:', v.type),
onAssessmentComplete: (r) => console.log('Done:', r.authScore),
onError: (e) => console.error('Error:', e)
});
await widget.init();
await widget.startAssessment();
// Later: await widget.completeAssessment();
</script>
Before starting, the user's face must be enrolled. Two options:
Provide facePhotoUrl when creating the session.
The widget shows an enrollment flow where user can capture via webcam or upload a photo.
// Manual enrollment
await fetch(`${API_URL}/api/widget/session/face-enroll`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${sessionToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
imageBase64: '<base64-encoded-image>',
source: 'webcam'
})
});
| Mode | Description | Use Case |
|---|---|---|
recording | WebRTC local recording uploaded to server | Self-paced exams |
live | Real-time Zoom video with proctor | Live proctored exams |
hybrid | Both recording + Zoom | High-stakes assessments |
The widget calculates an auth score (0-100%) based on:
| Component | Weight | Measures |
|---|---|---|
| Identity | 50% | Face matches enrolled photo |
| Presence | 20% | Face continuously visible |
| Behavioral | 30% | No tab switches, fullscreen maintained |
| Severity | Examples | Auto-Stop Threshold |
|---|---|---|
low | Brief face absence | No auto-stop |
medium | Tab switch, multiple faces | After 10 |
high | Extended face absence | After 5 |
critical | Identity mismatch | After 1 |
/api/widget/sessions - Create session (requires API key)/api/widget/session - Get session info/api/widget/session/start - Start assessment/api/widget/session/complete - Complete assessment/api/widget/session/stop - Stop assessment/api/widget/session/face-enroll - Enroll face photo/api/widget/session/verify-identity - Verify face during session/api/widget/session/documents - List documents/api/widget/session/documents - Upload document/api/widget/session/documents/:id - Download document/api/widget/session/messages - Get messages/api/widget/session/messages - Send message/api/widget/session/violation - Report violation/api/widget/session/auth-score - Update auth scoreConfigure a webhook URL when creating your integration to receive events:
{
"type": "session.completed",
"sessionId": "abc123",
"externalUserId": "student-123",
"externalAssessmentId": "exam-456",
"timestamp": "2025-12-20T05:00:00Z",
"authScore": 95.5
}
Event types: session.started, session.completed, session.stopped, violation.detected, score.submitted
┌─────────────────┐ ┌──────────────────────┐
│ Your LMS │ │ SecureAccess API │
│ (Backend) │────▶│ (Cloudflare Worker) │
└────────┬────────┘ └──────────┬───────────┘
│ │
│ sessionToken │
▼ ▼
┌─────────────────┐ ┌──────────────────────┐
│ Browser │ │ Storage │
│ (Widget SDK) │────▶│ D1 + R2 │
└─────────────────┘ └──────────────────────┘