PaperScorer Correction Embed — Live Demo

Full integration guide →

What this page is

A live, interactive preview of the PaperScorer correction embed — the same widget you'd drop into your own app to let users fix invalid student IDs and rebubble mis-read answers on scanned sheets. The demo uses canned data served from this site; no real sheet is scored.

Sandbox. The Submit button POSTs to a demo endpoint that simply echoes your payload back. No PaperScorer engine state changes. Refresh the page to reset the demo.

Live embed

The two widgets below are both auto-mounted via the data-ps-correction-embed drop-in pattern — no JavaScript glue is running on this page beyond correction.js itself. They illustrate the two correction flows the embed handles: fixing a misread student ID, and fixing misread bubble answers. In production, which view a partner shows depends on what the engine couldn't resolve about the scanned sheet; the embed picks the right one automatically based on the sheet data.

Demo 1 — Student ID correction

The engine couldn't bubble out a student identifier from this sheet. The embed hides the question grid (bubble data isn't reliable without a resolved student) and prompts for the corrected ID. Type a value and click Submit student ID.

Demo 2 — Answer bubble correction

The student ID is already resolved (pre-filled per-student sheet), but the engine flagged question 2 for multiple marked bubbles. The embed hides the student-ID input and renders the bubble grid for editing — toggle a different answer on Q2 and click Submit answer corrections.

Demo 3 — All editable question types

One question per editable type (1–8) for debugging side-by-side. Every type renders the same flat bubble-grid UI today; the semantic difference is single-select (types 1, 4, 8) vs. multi-select (types 2, 3, 5, 6, 7). Toggle a few bubbles in each section to see how the embed handles the different interaction rules, then submit to inspect the payload shape (the demo backend echoes it back).

Integrate it on your own page

The script URL — two flavors

The embed bundle is served from two URLs, and which one you pick is a caching decision:

Computing the md5 in your template (any backend language works the same — fetch our bundle once at build/deploy time, hash the bytes, render the URL):

// PHP
$bundle = file_get_contents('https://learnosity.paperscorer.com/embed/correction.js');
$hash   = substr(md5($bundle), 0, 8);
$src    = "https://learnosity.paperscorer.com/embed/dist/correction.{$hash}.js";

// Node
const crypto = require('crypto');
const bundle = await fetch('https://learnosity.paperscorer.com/embed/correction.js')
  .then(r => r.arrayBuffer());
const hash = crypto.createHash('md5').update(Buffer.from(bundle))
  .digest('hex').slice(0, 8);
const src = `https://learnosity.paperscorer.com/embed/dist/correction.${hash}.js`;

Cache the resulting URL on your side (memoize at process start, or recompute on deploy) — you don't need to re-hash on every page render.

Option A — Auto-mount (HTML drop-in)

The simplest path: mark a container with data-ps-correction-embed and point it at two URLs on your backend. The embed scans the DOM on DOMContentLoaded, fetches the sheet, and POSTs corrections back when the user submits. Your backend brokers the call to /api/get-correction-sheet and /api/submit-correction-sheet with header auth — your Consumer-Key never reaches the browser. The {{ hash }} placeholder below is the value from the snippet above.

<div data-ps-correction-embed
     data-fetch-url="/your-backend/correction-data?task_id=619&form_id=F-100"
     data-submit-url="/your-backend/submit-correction"
     data-task-id="619"
     data-form-id="F-100"></div>

<script src="https://learnosity.paperscorer.com/embed/dist/correction.{{ hash }}.js"></script>

Option B — Programmatic mount

For full control over the fetch (e.g. you already have the sheet data in your app's store, or you need custom request headers / retry logic), call window.PSCorrectionEmbed.mount(el, options) yourself.

<div id="my-correction"></div>

<script src="https://learnosity.paperscorer.com/embed/dist/correction.{{ hash }}.js"></script>
<script>
(async () => {
  const data = await fetch('/your-backend/correction-data?task_id=619&form_id=F-100')
    .then(r => r.json());

  window.PSCorrectionEmbed.mount(
    document.getElementById('my-correction'),
    {
      data,
      async onSubmit(corrected) {
        const res = await fetch('/your-backend/submit-correction', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            task_id: '619',
            form_id: 'F-100',
            ...corrected,
          }),
        });
        return res.json();
      },
    }
  );
})();
</script>

Next steps