SecureAccess Widget SDK

Embeddable proctoring and identity verification widget for secure assessments.

Quick Start

1. Get API Credentials

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"}'
Save the returned apiKey - it won't be shown again!

2. Create a Session (Server-Side)

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

3. Embed the Widget (Client-Side)

<!-- 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>

Face Enrollment

Before starting, the user's face must be enrolled. Two options:

Option A: Pre-enroll via API

Provide facePhotoUrl when creating the session.

Option B: In-Widget Enrollment

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'
  })
});

Video Modes

ModeDescriptionUse Case
recordingWebRTC local recording uploaded to serverSelf-paced exams
liveReal-time Zoom video with proctorLive proctored exams
hybridBoth recording + ZoomHigh-stakes assessments

Authentication Score

The widget calculates an auth score (0-100%) based on:

ComponentWeightMeasures
Identity50%Face matches enrolled photo
Presence20%Face continuously visible
Behavioral30%No tab switches, fullscreen maintained

Violations

SeverityExamplesAuto-Stop Threshold
lowBrief face absenceNo auto-stop
mediumTab switch, multiple facesAfter 10
highExtended face absenceAfter 5
criticalIdentity mismatchAfter 1

API Reference

Sessions

POST/api/widget/sessions - Create session (requires API key)
GET/api/widget/session - Get session info
POST/api/widget/session/start - Start assessment
POST/api/widget/session/complete - Complete assessment
POST/api/widget/session/stop - Stop assessment

Face Verification

POST/api/widget/session/face-enroll - Enroll face photo
POST/api/widget/session/verify-identity - Verify face during session

Documents

GET/api/widget/session/documents - List documents
POST/api/widget/session/documents - Upload document
GET/api/widget/session/documents/:id - Download document

Messages

GET/api/widget/session/messages - Get messages
POST/api/widget/session/messages - Send message

Violations & Scores

POST/api/widget/session/violation - Report violation
POST/api/widget/session/auth-score - Update auth score

Webhooks

Configure 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

Architecture

┌─────────────────┐     ┌──────────────────────┐
│   Your LMS      │     │  SecureAccess API    │
│   (Backend)     │────▶│  (Cloudflare Worker) │
└────────┬────────┘     └──────────┬───────────┘
         │                         │
         │ sessionToken            │
         ▼                         ▼
┌─────────────────┐     ┌──────────────────────┐
│   Browser       │     │  Storage             │
│   (Widget SDK)  │────▶│  D1 + R2             │
└─────────────────┘     └──────────────────────┘
Try the Demo: https://secureaccess-demo.pages.dev