scorm-taking

4 endpoints.

GET/api/scorm-courses/available Bearer token

List the courses the caller can take

Lists the live SCORM courses the caller may take, each with their own attempt state: organization-owned courses of every organization whose directory names them, department-owned courses of departments they hold a role in, and trainers-only courses their scorm:read covers. Needs no permission grant for the first two: the course's audience is the authorization.

Responses

StatusDescriptionBody
200The caller's available courses.AvailableScormCourseList
401The access token is missing or invalid.ErrorResponse
500The database could not be read.ErrorResponse
POST/api/scorm-courses/{course_id}/attempts Bearer token

Launch a course (start or resume an attempt)

Prepares a session of the caller's attempt: resumes the attempt in progress (its saved CMI data seeds the runtime, and its accumulated time rolls forward as the new session's base), or starts attempt n+1 when none is open — immediately with restart: true, which closes the open attempt first. The response carries everything the in-page runtime needs, including the signed content URL the module's iframe loads. An attempt runs against the package version it was launched with — a resumed attempt keeps its version even after the course's package was replaced; only a fresh attempt starts on the current one. Needs no permission grant: the course's audience is the authorization — organization membership, narrowed to the owning department's role holders for department-owned courses, or scorm:read over the owner for trainers-only courses.

Parameters

NameInTypeRequiredDescription
course_idpathstring (uuid)yesUUID id of the SCORM course.

Request body

application/jsonoptionalLaunchScormCourseRequest
FieldTypeRequiredDescription
restartbooleanno

True closes any attempt in progress and starts a fresh one; the default resumes it.

Responses

StatusDescriptionBody
200The attempt already in progress, resumed.ScormLaunch
201A freshly started attempt.ScormLaunch
401The access token is missing or invalid.ErrorResponse
404No course available to the caller has that id.ErrorResponse
409A concurrent launch is already starting an attempt; retry.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
503File storage is not configured on this deployment.ErrorResponse
PUT/api/scorm-attempts/{attempt_id} Bearer token

Commit an attempt's CMI data

Saves what the module has reported: the full CMI element map replaces the attempt's saved copy, and the summary the row carries — completion, success, scores, location, accumulated time — is re-derived from it server-side. The first commit that reports the attempt complete also files the result into the learner's records. The runtime calls this on every LMSCommit/Commit and on LMSFinish/Terminate. Only the attempt's own learner may commit; not their attempt is indistinguishable from a missing one.

Parameters

NameInTypeRequiredDescription
attempt_idpathstring (uuid)yesUUID id of the attempt.

Request body

application/jsonrequiredCommitScormAttemptRequest
FieldTypeRequiredDescription
cmiobjectyes

SCORM CMI elements by name, e.g. cmi.core.lesson_status.

api_flavorstring | nullyes

one of "scorm-1.2" | "scorm-2004" | null

terminatedbooleanyes

True once the module has called LMSFinish / Terminate this session.

Responses

StatusDescriptionBody
200The attempt with its freshly derived summary.ScormAttempt
400The request body failed validation.ErrorResponse
401The access token is missing or invalid.ErrorResponse
404No attempt of the caller's has that id.ErrorResponse
409The attempt is closed; launch the course again for a fresh one.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
GET/api/scorm-content/{ticket}/{asset_path} Public

Serve a file from a course package

Serves one file out of a SCORM course's package zip: the launch page the player's iframe loads, and every asset it references by relative URL. The signed ticket segment is the authorization — POST /scorm-courses/{course_id}/attempts mints it into content_url after checking the caller may take the course — so no bearer token is required (module asset requests cannot carry one). Tickets are scoped to one course and the package version the attempt was launched against, and expire with the session.

Parameters

NameInTypeRequiredDescription
ticketpathstringyesSigned content ticket, scoped to one course and package version — the launch response's content_url carries it.
asset_pathpathstringyesPackage-relative path of the file, spanning multiple path segments (the launch page's relative asset URLs resolve here on their own).

Responses

StatusDescriptionBody
200The file's bytes, served with the package entry's own content type.—
400The asset path is missing or malformed.ErrorResponse
403The content ticket is invalid or has expired; relaunch the course.ErrorResponse
404The course is gone, or no file at that path exists in its package.ErrorResponse
500The course content could not be served.ErrorResponse
502The course package could not be read from storage.ErrorResponse