Quickstart
Install the SDK, mount the Vue wrapper, choose a preset, and end sessions cleanly.
On this page
Use the Proctor SDK to add proctoring signals to a browser-based assessment. Proctor ships as a framework-agnostic core (@a4anthony/proctorkit-sdk) with a view layer on top: the batteries-included UI is Vue (@a4anthony/proctorkit-vue), the raw SDK supports bring-your-own UI integrations today, and the React wrapper is in progress. preset plus policyOverrides is the single source of assessment configuration on the Vue path.
Before choosing a policy, review System requirements. Browser, device, memory, orientation, network, and media requirements differ between basic, standard, and strict assessments.
Choose your integration
Every path drives the same engine — the preflight SystemCheck and the runtime ProctoringClient, both in @a4anthony/proctorkit-sdk — and the same server. Only the view layer differs, so preset, policy, events, webhooks, and the dashboard are identical whichever you pick.
| Path | Package | Status | Use when |
|---|---|---|---|
| Vue | @a4anthony/proctorkit-vue | ✅ Available | You use Vue 3. Drop-in <ProctoredAssessment> + preflight wizard. |
| React | @a4anthony/proctorkit-react | 🚧 In progress | You use React. Same components/hooks over the shared engine. |
| Vanilla JS / other frameworks | @a4anthony/proctorkit-sdk | ✅ Available | Angular, Svelte, Solid, or plain JS. Bring your own UI; drive the engine directly. |
The Vue wrapper and raw SDK are available today. @a4anthony/proctorkit-react is the only client path below that is 🚧 in progress. Raw integrations carry more lifecycle, policy-compilation, and recovery responsibility; review the Raw SDK integration guide before choosing that path.
Install
For the Vue path, install the wrapper and SDK:
npm install @a4anthony/proctorkit-vue @a4anthony/proctorkit-sdk
# or: pnpm add / yarn addApp keys
Create an app key from the dashboard keys page. App keys (pk_…) are public browser credentials, locked to allow-listed origins — safe to ship in client code. Your backend uses a separate secret key (sk_…) for the server API. See Authentication for the full key model, origin allow-listing, and rotation.
Client integration
Vue — ✅ available
<script setup lang="ts">
import { ProctoredAssessment } from "@a4anthony/proctorkit-vue";
import "@a4anthony/proctorkit-vue/style.css";
const candidate = {
id: "cand_123",
name: "Jane Candidate",
email: "jane@example.com",
};
</script>
<template>
<ProctoredAssessment
app-id="pk_live_xxx"
correlationid
candidate
preset
apibaseurl
template #
proctoringclient
sessionid
@complete
template
templatecorrelationId is owned by the customer assessment platform and stays stable across retries. The wrapper resolves the internal Proctor sessionId and uses it for preflight, runtime events, heartbeat, media uploads, and dashboard review.
Do not configure raw SDK observers separately when using the wrapper. The wrapper derives camera, screen-share, heartbeat, and detector behavior from the resolved policy.
To let candidates change an enabled camera, microphone, or speaker during the assessment, call openSettings() on the active client returned by useProctoringClient(). The dialog, device verification, face detector, and switching state remain owned by <ProctoredAssessment>; see Opening device settings during an assessment.
React — 🚧 in progress
npm install @a4anthony/proctorkit-react @a4anthony/proctorkit-sdkThe React package mirrors the Vue surface — same props, same resolved policy, same render-prop children — over the same engine:
import { ProctoredAssessment } from "@a4anthony/proctorkit-react";
import "@a4anthony/proctorkit-react/style.css";
const candidate = { id: "cand_123", name: "Jane Candidate", email: "jane@example.com" };
export function Exam() {
return (
<ProctoredAssessment
appId="pk_live_xxx"
correlationId="client-attempt-123"
candidatecandidate
preset
apiBaseUrl
client attempt endSession
proctoringClientclient
sessionIdattemptsessionId
onCompleteendSession
🚧 In progress. @a4anthony/proctorkit-react is not published yet — the API above is the planned shape (prop + render-prop parity with the Vue wrapper). Until it ships, React apps can drive the headless engine directly, exactly like the vanilla path below.
Vanilla JS & other frameworks — ✅ available
For Angular, Svelte, Solid, or plain JS, drive the framework-agnostic engine yourself. Both stages already ship in @a4anthony/proctorkit-sdk — the wrapper is just a view over them:
npm install @a4anthony/proctorkit-sdkimport { SystemCheck, ProctoringClient } from "@a4anthony/proctorkit-sdk";
// Stage 1 — preflight. Render your own UI from the engine's check rows.
const preflight = new SystemCheck(/* options compiled from your preset */);
const unsubscribe = preflight.subscribe((rows) => renderChecklist(rows
report preflight
reportpassed report
client
appId
sessionId resolvedAttemptsessionId
ingestUrl
workerUrl metaurl
policySnapshot resolvedPolicy
observers
clientThe Vue wrapper resolves your correlationId to the internal session attempt before preflight. Raw integrations must make that call, render every preflight state, compile policy into engine/observer options, and implement activation/recovery themselves. Follow the complete Raw SDK integration guide, not this abbreviated shape.
Presets
A preset is a complete proctoring policy — every preflight check and runtime observer set for you. The preset prop is the single most important configuration choice; there are three, increasing in strictness. Omit it and you get standard.
| Capability | basic | standard | strict |
|---|---|---|---|
| Preflight — browser & system checks | ✓ | ✓ | ✓ |
| Preflight — camera (+ face photo) | – | ✓ | ✓ |
| Preflight — microphone | – | ✓ | ✓ |
| Preflight — speaker | – | ✓ | ✓ |
| Preflight — fullscreen support | – | ✓ | ✓ |
| Preflight — screen-share grant (live) | – | – | ✓ |
| Runtime — heartbeat / idle | ✓ | ✓ | ✓ |
Use basic for low-stakes / monitored-only (browser check + activity signals, no camera or recording), standard for most proctored exams (camera/mic preflight + face photo, fullscreen, clipboard/keyboard monitoring, and webcam snapshots), and strict for high-stakes sessions (continuous webcam and screen-share recording instead of snapshots).
Adjust individual values on top of a preset with :policy-overrides — a deep partial, so you only specify what differs. The final policy is the chosen preset (default standard) with your :policy-overrides deep-merged on top; a preset key inside :policy-overrides also selects the base. Set preflight.enabled to false only when your integration intentionally skips the preflight wizard; runtime monitoring still follows the proctoring branch.
A browser can detect, not block. A web page cannot prevent OS-level actions — switching tab/window, taking an OS screenshot, or using browser shortcuts (Cmd-Tab, PrtScn). Every runtime signal below detects and flags these on the session timeline. The one deterrent available is screenshot.blurOnSuspicion, which frosts the page when a capture is suspected so a delayed screenshot grabs a blurred view — still not a hard block.
Complete policy reference
Every field you can set — the full preflight + proctoring option tables, the written-out standard policy, derived rules, and v2 migration notes — lives in the Policy reference. You rarely need it on day one: pick a preset, override the handful of values that differ, and come back when you need a specific knob.
Custom wrappers
Use the raw ProctoringClient only when building a custom framework wrapper or replacing the Vue preflight UI. Keep the same assessment policy as your source of truth, compile it once, and pass only the compiled runtime options to the SDK. Do not expose both policy fields and raw observers fields to the same customer integration.
The lower-level observer API is documented separately in Observers for wrapper authors.
Ending sessions
In Vue, call the slot's endSession from your submit or completion handler. The SDK sends session.end_requested, drains screen, webcam, and media uploaders, then emits session.ended when the drain completes. If the browser closes before a clean drain, the backend infers abandonment from missing heartbeat/activity.