Build vs Buy: What Building Proctoring In-House Costs

Build your own proctoring system only when proctoring is your product and you can fund a team to own it indefinitely. Buy it when proctoring is a feature of something else you sell. The camera preview is the part you can prototype in an afternoon. The real cost is everything behind it: a server-side scoring pipeline the candidate cannot tamper with, face analysis that turns frames into an identity verdict, capture that survives a refresh or a network drop, and a biometric-data compliance posture that never stops needing attention. This page breaks down what you are actually signing up to build, so the decision is made on the hard parts rather than the easy one.

Schedule a Demo

The easy part is a trap

Opening a webcam in the browser takes a few lines, and a demo that shows the candidate’s face in a corner looks like proctoring. It is not. A demo is not a system that has to produce a defensible verdict on an exam a candidate may contest. Judging the build on how quickly you can show a camera feed is how teams underestimate the work by an order of magnitude, because none of the expensive parts are visible in that first demo.

A useful way to frame the decision is the first question in this series: whether you need an LMS plugin, a browser SDK, or a REST API. Build-versus-buy is the same question one level up. If none of the integration surfaces fit, you are considering building the whole thing, and the parts below are what that means.

What you are actually building

A working proctoring system is not one feature. It is a set of subsystems that each stand alone, and skipping any one of them produces evidence that does not hold up. Here is what the browser SDK and the API already do, reframed as the components a from-scratch build has to own.

SubsystemWhat it has to doWhy it is harder than it looks
Resilient captureSurvive refresh, tab close, and network drop without splitting one attempt into several reports.Needs a stable attempt identity, an offline-tolerant event queue, and a flush on page unload.
Keyframe pipelineCapture periodic stills, not continuous video, and move image bytes out of your API path.Continuous video is expensive to store; routing frames through your API makes it your bottleneck.
Face analysisPer-frame presence, absence, multiple faces, and identity match against a reference photo.A machine-learning problem with its own models, thresholds, and a steady false-positive budget.
Audio analysisVoice activity and speaker count without recording a continuous audio stream.Another model to run and tune, with its own privacy footprint.
Anti-tamper scoringCompute the integrity verdict server-side so the candidate cannot edit the outcome.The browser is the part the candidate controls; any score computed there is worthless.
Liveness and heartbeatTrack a heartbeat so a client that goes silent is itself a signal, and a pre-flight system check.Absence of data is evidence; you have to model it deliberately, not ignore gaps.

None of these is a feature flag. Each is a project with its own models, its own failure modes, and its own tests. Capture alone has to handle a candidate who refreshes, loses connectivity, or closes a tab and comes back, all without fragmenting one attempt into several reports. For how much nuance sits in just that one subsystem, see handling the exam session lifecycle.

How small the integration is when you buy it

It helps to see the other side concretely. The entire browser-side integration when you buy it is one call to create a session and one to start it. Your backend mints the session with your API key, which never enters the browser, and reads the finished report afterward.

// The entire browser integration when you buy it.
import { ProctorLink } from '@proctorlink/sdk';

const session = ProctorLink.createSession({
  jwt: sessionJwt,   // session_jwt from POST /v1/sessions
  sessionId,         // session_id from the same response
});

// Safety net if the token outlives the exam: re-mint the SAME attempt_id
// (which resumes the same session) and hand the new token back.
session.on('token-expired', async () => {
  const { session_jwt } = await mintSession({ attempt_id: attemptId });
  session.updateToken(session_jwt);
});

await session.start();   // camera up, keyframes and events flowing

// when the attempt finishes:
session.stop();
session.destroy();

The server-to-server side is two calls: mint, then fetch. The browser only ever holds a short-lived token scoped to one attempt, so there is nothing for a candidate to lift.

// Your backend mints a session. Your API key never enters the browser.
POST /v1/sessions
access-token: <YOUR_ACCESS_TOKEN>
secret-token: <YOUR_SECRET_TOKEN>
content-type: application/json

{
  "external_user_id": "user-9f3c1a",   // your opaque ID, not a name or email
  "exam_id": "math-101-final",
  "attempt_id": "attempt-789",          // stable per attempt, enables resume
  "allowed_origins": ["https://exams.yourcompany.com"]
}

// After the attempt, fetch the finished report from your backend.
GET /v1/sessions/6a7b18df70e4f8ecf2597b6f

That is the whole integration surface. Everything in the subsystem table above sits behind these calls, maintained by someone else. For the full version of this integration in a framework, see how to add proctoring to a web application.

Why the integrity score is the part you cannot shortcut

Of everything on the build list, the scoring model is the one most teams get wrong, because the obvious place to compute it is the wrong one. If the score is calculated in the browser, the candidate controls the exact component that decides whether they passed. The verdict has to be computed server-side, from signals collected in a part of the page the candidate cannot reach, or the whole system is theatre.

A defensible score is also explainable. It is not a single opaque number: it is a value with an itemised, weighted breakdown that a human reviewer can read and defend if the outcome is challenged. Face analysis drives the verdict; browser events like a tab switch stay pooled and capped so ordinary behaviour cannot manufacture a flag. Getting that balance wrong in either direction, flagging innocent candidates or missing real impersonation, is how an in-house score loses the trust of the exam board that relies on it.

// The verdict you would otherwise have to build and defend yourself.
// Computed server-side, so the candidate cannot influence it.
{
  "status": "validated",
  "integrity": {
    "score": 72,
    "level": "medium",
    "flagged": true,
    "identity_match": "pass",
    "reasons": [
      { "code": "no_face", "detail": "...", "weight": -18 },
      { "code": "browser_activity", "detail": "...", "weight": -10 }
    ]
  }
}

Designing a model like this, and defending the weighting, is a project in itself. The full treatment is in how to design an exam integrity score, and the reasoning behind automated versus human verdicts is in AI proctoring vs live proctoring.

Build versus buy, concern by concern

Set side by side, the trade is clearer. Building gives you full control and a permanent maintenance bill. Buying trades some control for a surface you can integrate against in an afternoon and never have to patch when a browser changes.

ConcernBuild in-houseBuy (ProctorLink)
Browser integrationCamera, fullscreen, clipboard, focus, and device-change handling across every browser.A thin loader (~3 KB) mounts a cross-origin iframe enclave. One start() call.
The verdictDesign, weight, and defend a scoring model, then keep it server-side and tamper-proof.A server-side integrity score with itemised, weighted reasons you read from the report.
Identity matchingTrain or license a face model, store reference photos, run per-frame comparison.Reference photo at mint or via the SDK; identity_match returned in the report.
Camera permission UXRe-prompt the candidate on every customer domain that embeds you.Permission binds to the enclave origin, so it persists across every site using it.
Browser-change maintenancePermanent. Each browser release can break detection silently.Absorbed by the vendor. The SDK and enclave are versioned together.
Biometric-data complianceConsent, retention, deletion, data minimisation, and sub-processor records, all yours.Still your obligation, but the architecture is built to support it.

The camera-permission row is a good example of value that is invisible until you hit it. ProctorLink mounts a cross-origin iframe enclave, and the camera permission binds to that enclave origin, so a candidate who has granted it once is not re-prompted on the next site that embeds it. Build it yourself and every customer domain prompts afresh. The reasoning is in why proctoring runs in a cross-origin iframe.

The limits you inherit either way

Some costs do not go away by building, because they are properties of the web platform, not gaps in any one product. A browser tab cannot see other applications, a second device, a virtual machine, or a remote-desktop session. That is why serious proctoring tiers into a browser SDK, a browser extension, and a desktop agent, and building in-house means building that tiering yourself if you need it.

The rest of the platform limits are the same for everyone. Multi-monitor detection is Chrome-only and permission-gated. Virtual cameras are detectable as a signal through device heuristics, never as proof. iOS Safari has no screen-capture API and suspends the camera when the tab is backgrounded. Face analysis is probabilistic, so the honest result is “frames where no face was detected”, not “the candidate left the room”. Building your own system does not lift any of these constraints. It just makes them your job to discover, document, and explain. For where the line actually falls, see what browser-based proctoring can and cannot detect.

The compliance bill does not stop

The moment you capture a face, you are processing biometric data, and that obligation outlives any single release. Facial images and the face templates derived from them are biometric data under India’s DPDP Act, GDPR Article 9, and Illinois BIPA, the last of which carries statutory damages assessed per violation. Build the system yourself and you own all of it: explicit pre-capture consent, a chosen and documented retention period, honouring deletion requests, data minimisation, and a documented list of every sub-processor that touches a frame.

Buying does not remove this obligation, but a platform designed for it is built to support the parts you control: an opaque external_user_id so you are not handing over names or emails, periodic keyframes instead of continuous video, and frames that upload straight to object storage rather than through an API. The full breakdown of what each law asks is in proctoring and biometric data: DPDP, GDPR Article 9, and BIPA. If you serve Indian institutions specifically, see online exam proctoring in India. And if your route to market is Moodle, the best Moodle proctoring plugin comparison shows the buy option as a plugin rather than an SDK.

Common mistakes

  • Judging the build on the camera demo. A face in the corner is not a verdict. Fix: scope the build on the scoring, face analysis, and compliance subsystems, not the preview.
  • Computing the score in the browser. The candidate controls that code, so the verdict is editable. Fix: compute the integrity score server-side, from signals they cannot reach.
  • Recording continuous video to review later. That is record-and-review, and it does not scale past a handful of exams. Fix: capture periodic keyframes and triage by score so a human only reviews flagged sessions.
  • Treating maintenance as a post-launch phase. Browser APIs change on their own cadence and break detection silently. Fix: budget for permanent browser-compatibility work, not a one-time build.
  • Deferring biometric compliance until later. The obligation attaches the first time you capture a face. Fix: design consent, retention, deletion, and minimisation in from the start, whichever way you go.

So which should you do?

Build when proctoring is the product you sell, the differentiation is in the detection itself, and you can staff a team to own capture, models, browser compatibility, and compliance for as long as the product lives. Buy when proctoring is a feature that makes your real product more valuable, when time to market matters, and when you would rather integrate against a maintained surface than carry a permanent detection-and-compliance team.

Across published deployments, ProctorLink has supported more than one million proctored exam sessions (methodology note below). Full cohort sizes and outcomes are on the case studies page, and the whole developer series starts from the knowledge hub.

What customers say on G2

Institutions evaluating proctoring tools often look for independent feedback outside vendor case studies. ProctorLink is listed on G2, where Moodle administrators and training teams share verified product reviews.

Read ProctorLink reviews on G2 →

Frequently Asked Questions

Build when proctoring is your product and you can fund a team to own camera capture, server-side face analysis, an anti-tamper architecture, and ongoing browser compatibility indefinitely. Buy when proctoring is a feature of something else you sell, because the hard parts are not the camera preview you can prototype in an afternoon. The real cost is the scoring pipeline that has to run server-side so a candidate cannot edit the verdict, the face analysis that turns frames into an identity match, and the compliance posture around biometric data. Those are the parts that take the longest to get right and never stop needing attention.

Sources & references

Deployment statistics and product behaviour described in this guide link to the sources below.

Next steps

Before you commit to a build, see exactly what the buy path gives you. Sign up at app.proctorlink.com to get your API keys, run a session, and read a full server-side report.

More Proctoring Guides

See the Buy Path Before You Build

One create-session call, one start, a server-side verdict you can defend. Run a real session and read the report before you commit a team to building it yourself.