Tahoe Enrollment API

API Endpoints available for enrolling learners in courses on Tahoe from a third-party system. 

Use these to use an external system to enroll users in courses by sending the relevant information over to Tahoe to start the learner’s enrollment process there. 

Note:

In this doc, you will see references to Token <insert token here>. If you are a Tahoe site admin, please contact support@appsembler.com to request a unique auth token for your site. 

Registration vs Enrollment

Registration is the process of signing up for an account on an Open edX site. It requires at least an email, name, username, password, and acceptance of TOU/Privacy Policy. It does not enroll the user in any courses.

Enrollment is the process of enrolling a registered user in one or more courses.

Bulk enrollment (and unenrollment)

Endpoint: /tahoe/api/v1/enrollments/
Request Method: POST

Description

The Tahoe API v1 bulk enrollment API performs enrollment of one or more learners in one or more courses. The same API can be used to unenroll learners from one or more course depending on the value of the "action" parameter.

The bulk enrollment is derived from and modeled after the bulk enrollment available to our Enterprise customers on Ginkgo or higher. For reference, see our edx-platform Ginkgo api docs

Payload

The bulk enrollment payload is an HTTP request body.

Table 1 - Required Parameters

Name Type Description
action string To enroll, value must be either “enroll” or "unenroll".
courses List of “string” Each list item is the course identifier. This identifies the course for which to enroll (or unenroll; depending on "action") all learners in the “identifiers” list. To populate this, you can either use course identifiers you already know, or get them from the Course API.
identifiers List of “string” Each list item is a learner identifier. This can be an email address or username. If the learner has not yet registered, it must be an email address. To populate this, you can either use learner identifiers you already know, or get them from the User API.

Table 2 - Optional Parameters

Name Type Description
auto_enroll boolean Enroll learners in the specified courses as soon as they register. This applies to learners in your list who are not yet registered for the site. Default is false. 

Note: This parameter is only applicable when "action" is "enroll". It is, however, ignored when action is "unenroll".
email_learners boolean Learners will be sent email notifications upon enrollment. Default is false.

Response

The following tables identify the keys and values of the response. The response body is JSON data by default. See the example response following these tables.

Table 3 - Top Level Response Keys

Name Description
action The action as sent in the request body
courses List of “string” These are the course identifiers as sent in the request body
results List of results for each learner enrollment. See the following table for the structure of each element
email_learners See the optional  parameter “email_learners” in Table 2. This is that value
auto_enroll See the optional  parameter “auto_enroll” in Table 2. This is that value

Note: This response key shows up only when action is "enroll".

Table 4 - Enrollment “results” key values

These are the values for each element in the “results” value for the previous table
Name Description
identifier User unique identifier. This is either the user’s email or the user’s username. Should be the same as the value entered in the “identifiers” list in the required POST parameters table
before Contains a set of flags indicating the “before enrollment” state
after Contains a set of flags indicating the “after enrollment” state

Table 5 - Enrollment “before” and “after” values

NOTE: These are response values built into the existing Open edX platform and not a new feature of the Tahoe enrollment API.

Name Description
enrollment Boolean. Has the user been enrolled. ‘False’ for new users (not yet registered). ‘True’ for already existing users.
auto_enroll Boolean. If ‘True’, then the user will be automatically enrolled in the course after registering. If ‘False’ then the user will not be automatically enrolled after registering OR the user has already been enrolled (meaning an existing user has enrolled). 

Notes:
  • If ‘enrollment’ is true, then this value should be ‘false’ and vice versa.
  • This response key shows up only when action is "enroll".
Note: 
user Boolean. Does the user exist after the bulk enrollment. ‘False’ for new users, as the user needs to personally register. ‘True’ if enrolling an existing users
allowed Boolean. User is allowed to enroll in the course. ‘True’ for new users (who need to register to enroll). ‘False’ for existing users who are enrolled by this bulk enrollment.

Table 6 - Response codes

Name Description
201 Created. Bulk enrollment was successful for an "enroll" action.
200 Ok. Bulk enrollment was successful for an "unenroll" action.
400 Bad Request. Invalid parameter(s) or value(s) in request body
401 Unauthorized. User token passes but user doesn’t have permissions
403 Forbidden. An invalid token will cause this

Examples

Example enroll payload

{
    "action": "enroll",
    "courses": [
        "org.26/course_26/Run_26",
        "org.27/course_27/Run_27"
    ],
    "identifiers": [
        "robot+test+54@example.com",
        "alpha@example.com",
    ],
    "email_learners": true,
    "auto_enroll": true
}

Example enroll response

{
    "action": "enroll",
    "courses": [
        "org.26/course_26/Run_26",
        "org.27/course_27/Run_27"],
        "email_learners": true,
        "results": [
            {
                "identifier": "robot+test+54@example.com",
                "after": {
                    "enrollment": true,
                    "auto_enroll": false,
                    "user": true,
                    "allowed": false
                },
                "before": {
                    "enrollment": false,
                    "auto_enroll": false,
                    "user": true, "allowed": false
                }
            },
            {
                "identifier": "alpha@example.com",
                "after": {
                    "enrollment": false,
                    "auto_enroll": true,
                    "user": false,
                    "allowed": true
                },
                "before": {
                    "enrollment": false,
                    "auto_enroll": false,
                    "user": false,
                    "allowed": false
                }
            }
        ],
        "auto_enroll": true
}

Example enroll cURL command

curl -X POST \
  https://<your-site-name>.tahoe.appsembler.com/tahoe/api/v1/enrollments/ \
  -H 'Authorization: Token <insert token here>' \
  -H 'Cache-Control: no-cache' \

  -H 'Content-Type: application/json' \
  -d '{
    	"action": "enroll",
    	"email_learners": true,
    	"identifiers": [
    		"ann@example.com",
    		"robert@example.com"
    	],
    	"auto_enroll": true,
    	"courses": [
    		"course-v1:testing-apis+AP200+2019",
    		"course-v1:testing-apis+AS100+2018"
    	]
    	}'

Example unenroll cURL command

Similar to the example above, but using the "unenroll" action. Notice that we dropped the "auto_enroll" parameter because it's irrelevant in the case of "unenroll" action.

curl -X POST \
  https://<your-site-name>.tahoe.appsembler.com/tahoe/api/v1/enrollments/ \
  -H 'Authorization: Token <insert token here>' \
  -H 'Cache-Control: no-cache' \

  -H 'Content-Type: application/json' \
  -d '{
    	"action": "unenroll",
    	"email_learners": true,
    	"identifiers": [
    		"ann@example.com",
    		"robert@example.com"
    	],
    	"courses": [
    		"course-v1:testing-apis+AP200+2019",
    		"course-v1:testing-apis+AS100+2018"
    	]
    	}'

Comments/Notes

Running a POST twice on the same data with new (unregistered) user emails should not create additional records. It is intended to be idempotent (at least with regard to CourseEnrollmentAllowed records).

GET List

Endpoint: /tahoe/api/v1/enrollments/
Request Method: GET

Table 7 - Query parameters

Name Type Description
course_id string URL friendly course id.example: “course-v1:delta-rook+APH5P+2019”
username string Username for the user on whom to filter[1]
user_id integer User id for the user on whom to filter[1]

[1] For the initial release, only one user is retrieved. If the username and user_id don’t match, then nothing is retrieved. This is a bug that needs to be fixed so we can retrieve multiple users

Response

The top level response contains pagination data, which can be used to page through the list responses.

Table 8 - Top Level Response Keys

Name Description
count Number of total records retrieved
next Link to the next page of results. Null if no next page
previous Link to the previous page of results. Null if no previous page
results List of enrollment data. See the next table

Table 9 - Results element values

Name Description
created Timestamp when the course was created
mode The mode of the course. For example, “honor”
is_active Boolean. Is the course active or not
course_details List of course details records
user String. This is the user’s username

Table 10 - Course details record

Name Description
course_id String id for the course
course_name Descriptive name of the course
enrollment_start Date the course is open for enrollment. Null if there is no enrollment window (enrollment open anytime)
enrollment_end Date the course closes for enrollment. Null if there is no enrollment window (enrollment open anytime)
course_start Date the course starts
course_end Date the course ends. Can be null
invite_only Boolean. True if enrollment is restricted to invites
course_modes List of course modes. See the following table

Table 11 - Course modes record

Name Description
slug Slug for the course mode (lowercase, no spaces. This is the url friendly string for the course mode. Example “honor”
name Name for the course mode. Example “Honor”
min_price Minimum price for the course. 0 (zero) if there is no cost to the course
sugested_price Can be an empty string.
currency Country’s ISO currency code. For example, “usd” for United States dollars
expiration_datetime Can be null
description Can be null
sku Can be null
bulk_sku Can be null

Table 12 - Response codes

Name Description
200 OK (success)
400 Bad Request. Invalid parameter(s) or value(s) in request body
401 Unauthorized. User token passes but user doesn’t have permissions
403 Forbidden. An invalid token will cause this

Example cURL command

curl -X GET \
  https://<your-site-name>.tahoe.appsembler.com/tahoe/api/v1/enrollments/ \
  -H 'Accept: */*' \
  -H 'Authorization: Token <insert token here> \
  -H 'Cache-Control: no-cache'

Example response

{
    "count": 59,
    "next": "https://your-site-name.tahoe.appsembler.com/tahoe/api/v1/enrollments/?limit=20&offset=20",
    "previous": null,
    "results": [
        {
            "created": "2019-01-03T16:01:26.609570Z",
            "mode": "honor",
            "is_active": true,
            "course_details": {
                "course_id": "course-v1:testing-apis+AP200+2019",
                "course_name": "APIs: How I learned to stop worrying and love APIs",
                "enrollment_start": null,
                "enrollment_end": null,
                "course_start": "2030-01-01T00:00:00Z",
                "course_end": null,
                "invite_only": false,
                "course_modes": [
                    {
                        "slug": "honor",
                        "name": "Honor",
                        "min_price": 0,
                        "suggested_prices": "",
                        "currency": "usd",
                        "expiration_datetime": null,
                        "description": null,
                        "sku": null,
                        "bulk_sku": null
                    }
                ]
            },
            "user": "ann_example_com"
        },
     &hellip; 
]

GET Detail

Endpoint: /tahoe/api/v1/enrollments/<enrollment id>/
Request Method: GET

DO NOT USE. This is currently broken. It returns a course overview and not a course enrollment.