Tutorial - Import a Course

Upload your Content

This is part of the tutorial series: Upload Content, Register Learners, and Track Progress:

  1. Intro
  2. Upload your Content
  3. Register Learners
  4. Track Progress
  5. Recap

Start an Upload Job

First things first, if we want to upload a course, we need a course to upload. Luckily, we keep one around for just this kind of thing. You can get a free sample SCORM course about Golf here.

We should note at this point that there are several ways to get course content imported into SCORM Cloud, depending on your needs. For this guide we’ll only focus on the most common path (and the one used by our web portal), which is providing the course content via a HTTP POST request to our servers.

In order to upload our course into SCORM Cloud, we’ll use our API’s Course Service; specifically, the CreateUploadAndImportCourseJob method. While this call accepts a number of parameters, we only need two of them to import our course:

courseId - This is the identifier you’ll use to refer to the course you’re uploading. This can be whatever you’d like, for instance my_course_id.
file - The form POSTed file content. In our case: the .zip file from just a bit earlier.

This method starts off an import job, and returns the id for that import job. Your response from this call might look something like this:

  "result": "KUG2Q5880Umy_course_id"

Validate your Upload

The next step is to check the status of this job so that we know when the course is uploaded, imported, and ready for launch. We can do this by using the GetImportJobStatus method. Since the content we uploaded is tiny, chances are this job will be finished by the time we can even check on it. Let’s go ahead and test that out. Your response will look something like this:

  "jobId": "ImportJobKUG2Q5880Umy_course_id",
  "status": "COMPLETE",
  "message": "Finished",
  "importResult": {
    "webPathToCourse": "/content/courses/KUG2Q5880U/my_course_id/0",
    "parserWarnings": [],
    "courseLanguages": [],
    "course": {
      "id": "my_course_id",
      "title": "Golf Explained - Run-time Advanced Calls",
      "xapiActivityId": "urn:uuid:41689290-8c34-5bbd-91e5-0a7b63132ecd",
      "created": "2021-01-27T19:32:58Z",
      "updated": "2021-01-27T19:33:13Z",
      "version": 0,
      "activityId": "golf_sample_default_org",
      "courseLearningStandard": "SCORM20043RDEDITION",
      "tags": [],
      "dispatched": false,
      "rootActivity": {
        "externalIdentifier": "golf_sample_default_org",
        "itemIdentifier": "golf_sample_default_org",
        "resourceIdentifier": "",
        "activityType": "AGGREGATION",
        "href": "",
        "title": "Golf Explained - Run-time Advanced Calls",
        "children": [
            "externalIdentifier": "item_1",
            "itemIdentifier": "item_1",
            "resourceIdentifier": "resource_1",
            "activityType": "SCO",
            "href": "shared/launchpage.html",
            "scaledPassingScore": "0.8",
            "title": "Golf Explained",
            "children": []

As you can see there is a lot to unpack here, but we don’t care about most of it right now. For now, we’re just interested in seeing that the status is COMPLETE. That means our import has finished and we’re ready to move on.

For real world content of more realistic size, it is reasonable to expect that the import job would take a bit longer. In that case, you’d want to keep periodically checking the job status until it’s reported as COMPLETE before attempting to do anything else referencing that course. The workflow for your system in this case would likely look something like this (note: this is pseudo code):

jobId = CreateUploadAndImportCourseJob(courseId='any_identifier', file=FileObject)
jobStatus = GetImportJobStatus(jobId)

while (jobStatus.status != 'COMPLETED'):
  log(jobStatus.message) # this should be a human readable progress message
  sleep(5000) # wait some reasonable (5 seconds or so)
  jobStatus = GetImportJobStatus(jobId)

Next up: Register Users to Your Content