DocsDeliveringSCORM

SCORM

Ship a course into someone else's LMS as a standard package — and pull an existing LMS library back out.

Exporting a course

Any course can be downloaded as a .zip from its page in the dashboard, then uploaded to your LMS the same way you would any other package. Two versions are available:

  • scorm2004 SCORM 2004 (4th Edition). The default, and the right choice unless your LMS says otherwise.
  • scorm12 SCORM 1.2. Older, but still the only version some enterprise LMSs handle reliably. Try this one if 2004 imports but never records completion.

What's in the package

It is self-contained: the zip carries your course content and a standalone build of the same player the embed uses, so it runs entirely from your LMS's own origin with no callback to Underlayer. Images, video and custom fonts are still loaded from wherever they are hosted, as they are in the embed.

The whole course is one SCO rather than one per screen. Courses here keep state across screens — running quiz scores, the results screen, buttons that jump to another screen — which needs a single continuous session. Screens are reported as cmi.location bookmarks, so your LMS still resumes a learner where they left off.

Every block type the embed renders renders here too — including the contents panel, the built-in completion screen, and steps, timelines, accordions and slideshows. It is the same player code, built standalone; there is no second renderer to fall behind. The course’s quizFeedback and navigation settings travel with the package, so a course that marks answers immediately in the embed does so in your LMS too.

A packaged course can offer its certificate too, carrying the same verifiable serial an embed-issued one does — but only when the export was made with track=1 and the LMS tells the package who the learner is. Both, or neither: the certificate is re-derived from a real completion record, and without tracking no such record is ever written, so offering the link otherwise would hand every learner a 404 at the moment they finished.

What your LMS receives

Completion and pass/fail (against the course's passing score), the final score, time spent, a resume bookmark, and one interaction per graded question with the learner's answer and whether it was correct.

Only graded blocks are reported — single/multiple choice, true/false and fill-in-the-blank. Matching and hotspot blocks are interactive but deliberately ungraded, here and in the embed, so a package's score always equals the score the learner saw on screen.

Importing a package

Import SCORM on the Courses page creates a course from an uploaded .zip (up to 100MB). Imported courses always arrive as drafts. What you get back depends on where the package came from:

A package Underlayer exported

Restored exactly — every block type, quiz, style and branching target, identical to the course it came from. Useful for moving a course between workspaces, or recovering one you no longer have.

A package from another authoring tool

You get the outline from its manifest, the readable text of each screen, and any quiz data we can read — turned into real quiz blocks, not just text. Three sources are tried:

  • QTI (both 1.2 and 2.x) — the IMS standard for assessment items, and what LMS exports like Moodle, Blackboard and Common Cartridge carry. Questions, options and correct answers all import.
  • Embedded course data — Rise, Storyline, Captivate and iSpring all ship their quiz model as JSON inside the package. We read it by shape rather than by vendor, so unfamiliar tools often work too. Correct answers usually come across.
  • HTML forms — hand-built radio/checkbox quizzes. The answer key normally isn't in the markup, so these import with options unmarked for you to complete. We never guess an answer: a wrong key grades real learners incorrectly and nobody notices.

Layout, styling and custom interactions still don't convert, and quizzes drawn to canvas with no structured data behind them can't be recovered at all. The import tells you exactly how many questions it found, where they came from, and how many need an answer key — so a partial result is obvious immediately rather than at the moment someone is graded.

Doing it over the API

The API endpoint requires the Scale plan or higher — a Sandbox/Build key gets a 403 plan_required. Exporting and importing from the dashboard works on every plan.

Both directions are available programmatically, for pushing a catalogue into an LMS pipeline or migrating an existing library in bulk. Export returns the .zip itself rather than a link — packages are built on demand from live course data, so there is nothing durable to point at.

exportbash
curl -L -H "Authorization: Bearer sk_live_..." \
  "https://underlayer.outworx.io/api/v1/courses/COURSE_ID/scorm?version=scorm2004" \
  -o course.zip

Export also accepts lang to package a translated locale, and track=1 to have the package additionally report runs back to your Underlayer analytics (see below).

importbash
curl -X POST -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/zip" \
  --data-binary @course.zip \
  "https://underlayer.outworx.io/api/v1/courses/import/scorm?title=Optional%20override"

Import responds 201 with the created course, plus a meta object whose kind is roundtrip or salvaged — so an automated migration can flag the partial ones for review without inspecting content.

import responsejson
{
  "data": { "id": "...", "title": "Workplace Safety", "status": "draft", "sourceKind": "imported", ... },
  "meta": {
    "kind": "salvaged",
    "warnings": ["This wasn't an Underlayer package, so only the structure and readable text could be imported — ..."]
  }
}

Analytics from inside an LMS

A SCORM package normally reports only to the LMS running it, which means those learners are invisible in your Underlayer dashboard. Exporting with track=1 also sends view, answer and completion beacons back to us, keyed to the LMS's own learner id — so if you use consistent ids, a learner's SCORM activity lines up with their embed activity and their webhooks fire as usual.

It is strictly additive. The LMS's own SCORM record stays authoritative, and a network that blocks the beacon costs you dashboard analytics only — never a learner's completion.