Roster Sync API

Authentication for APIs

All Oneroster APIs are authenticated based on the client id and secret shared by Gooru with partners. Partner need to base64 encode the client id and secret in order to pass as Basic authorization header to APIs.

Example: (To generate Base64 Encoded Credentials)

ClientId: 3d6bc3ea-2aff-4106-8762-9246d5d84813
Secret: kteuobYdO1oRfqJ1+PZ5phMSeI=

Combine client id and secret with ‘:’ -
3d6bc3ea-2aff-4106-8762-9246d5d84813:kteuobYdO1oRfqJ1+PZ5phMSeI=

And then encode it by Base64 encoder which will generate string like below. Use it to pass in request header.
M2Q2YmMzZWEtMmFmZi00MTA2LTg3NjItOTI0NmQ1ZDg0ODEzOmt0ZXVvYllkTzFvUmZxSjErUFo1cGhNU2VJPQ==

Data Requirements

All csv files contained in the zip should comply to the IMS Global OneRoster specification

CSV Overview:
Tenants should provide the student information to Gooru as .csv formatted files.
Tenants must continue to use .csv files to exchange roster information with Gooru, below is an outline of the format for the roster data which corresponds to the OneRoster standard.
Tenants can choose to upload class rosters by preparing four (4) files in csv format outlined in this document.

  1. orgs.csv
  2. users.csv
  3. classes.csv
  4. enrollments.csv

CSV Format:
The file format MUST be comma separated values format (CSV) for the OneRoster profile. Each field will be separated by commas and line breaks between each row. Double quotes MUST be used with a field that contains a comma.
● All files are required
● The header row is required.
● Some fields are required.
● The primary id is marked in red below, this must be unique per file.
ALL Header fields MUST be supplied in EXACTLY the same order as in the tables below. Optional fields with no data MUST simply be empty in the CSV. Header fields MUST be named the same as per the field header in the tables below. All filenames and header fields are case sensitive.

Organization Rostering
First step in the rostering to create the organization based on the details provided in the “orgs.csv”. This file should be processed first if present

  • New organization will be created if there is no organization present with the same “sourced_id” for the tenant.
  • If an organization with the same “sourced_id” found for the tenant rostering the data, then the last modified date from the csv will be compared with the last modified date present in the database. If date from csv file is later than what present in date, class data will be updated otherwise no action will be taken

If this file is not present in the zip uploaded by the tenant, other csv files should contain references to existing organizations (orgSourcedId).

If there is no organization with orgSourcedId, no data will be rostered and error should be returned to the tenant.

There is one to one mapping between the organization and tenant. If any partner wants to roster the data for multiple school districts, all school districts should be first configured in Gooru as a sub tenant of the partner’s tenant.

School districts will contain multiple schools having their own organization sourced ids. Data will be mapped in Gooru based on the tenant for which the data is getting rostered.

Partner’s roster sync system will be responsible to roster the data against each school district separately.

Support Fields:

file headerrequiredfrormatdescription
sourcedIdYesUUIDunique id for the organization. SourcedId is used in other files and must be unique across all organizations. (For example –schools in your district).
statusNoString“active”.
dateLastModifiedNoDateThe date that this record was last modified. (format is YYYY-MM-DD)
nameYesStringName of the Organization
typeYesString“school”
identifierNoStringNCES ID National Center for Education Statistics) for the school / district
metadata.classificationNoString“charter” | “private” | “public”
metadata.genderNoString“female” | “male” | “mixed”
metadata.boardingNoBooleanTrue if school is boarding school
parentSourcedIdNoUUIDSourcedId of the Parent organization

Class Rostering
Based on the data present in the “classes.csv” file, classes are rostered into Gooru.

  • New class will be created if there is no existing class present for the organization with same “sourced_id”
  • If a class with the same “sourced_id” is found for the organization, the last modified date from the csv will be compared with the last modified date present in the database. If date from csv file is later than what present in date, class data will be updated otherwise no action will be taken

Support Fields:

file headerrequiredfrormatdescription
sourcedIdYesUUIDUnique ID for the class. SourcedId is used in other files and must be unique across all classes.
statusNoString“active”
dateLastModifiedNoDateThe date that this record was last modified. (FORMAT IS YYYY-MM-DD)
titleYesStringName of this class
gradeNoStringGrade (i.e. 9)
courseSourcedIdNoUUIDSourcedId of the course of which this class is an instance
classCodeNoStringHuman readable code used to help identify this class
classTypeYesString“homeroom”, “scheduled”
locationNoStringHuman readable description of where the class is physically located
schoolSourcedIdYesUUIDSourcedId of the organization which teaches this class
termSourcedIdNoUUIDSourcedId of the academicSessions(s) in which the class is taught. If more than one term is needed, use double quotes and delimit with commas, (per RFC 4180)
Examples:
“1,2”
1
“1,4,8”
subjectsYesStringSubject name(s). If more than one subject is needed, use double quotes, and delimit with commas (per RFC 4180):

Examples:
“chemistry, physics”
physics
“music, drama, poetry”

User Rostering
Based on the data present in the “users.csv” file, users data will be rostered into the Gooru system.

  • New user will be created if there is no user present for the organization with same “sourced_id” and username
  • If a user with the same “sourced_id” and username / user_id found for the organization, the last modified date from the csv will be compared with the last modified date present in the database. If date from csv file is later than what present in date, user data will be updated otherwise no action will be taken

“username” is mandatory while rostering users data. This should be the login name or login id of the user in the client system.

While rostering the record into Gooru, uniqueness of the records is based on the “username” and tenant. If there is already a user with “username” (i.e. reference_id in “users” table of Core DB) for the tenant, error (409 Conflict) will be returned.

Supported Fields:

file headerrequiredformatdescription
sourcedIdYesUUIDUnique ID for the user. SourcedId is used in other files and must be unique across all users,
statusNoString“active”
dateLastModifiedNoDateThe date that this record was last modified. (FORMAT IS YYYY-MM-DD)
orgSourcedIdsYesUUIDSourcedIds of the Organizations to which this user belongs.

(Note in most cases, it is expected that users will belong to a single school).
roleYesString“teacher”, “student”
usernameYesStringUsername
userIdNoStringexternal machine readable id (e.g. LDAP id, LTI id) for this user, to be used if the sourcedId should not be used.
givenNameYesStringUser’s first name
familyNameYesStringUser’s surname
identifierNoStringIdentifier for the user with a human readable meaning
emailNoStringEmail address for the user
smsNoStringSMS address for the user
phoneNoStringPhone number for the user
agentsNoStringSourcedIds of the users to which this user has a relationship.
Note: In most cases this will be for indicating parental relationships.

Enrollment Rostering
Based on the data present in the “enrollments.csv” file, enrollments will be rostered into the Gooru system.
It's mandatory to pass organization sourced id, class sourced id and user sourced id in order to enroll the users. Missing any of the details will not create enrollment and specific errors should be returned.

Support Fields:

file headerrequiredtypedescription
sourcedIdYesUUIDId of this enrollment
classSourcedIdYesUUIDId of the class
schoolSourcedIdYesUUIDId of the school
userSourcedIdYesUUIDId of the user (teacher or student)
roleYesString“student” | “teacher”
statusYesString“active”
dateLastModifiedNoDateThe date that this record was last modified. (FORMAT IS YYYY-MM-DD)
primaryYesBooleanMUST only be set to true for ONE teacher for a class.

Upload Roster

This API is used to upload the roster files in zip format. All csv files contained in the zip should comply to the IMS Global Oneroster specification. Invalid or extra uploaded files are skipped from rostering. Current scope of this API is to process orgs, users, classes and enrollments only. Other files such as academicSessions, demographics and courses will be not be processed and rostered into system.

All data will be rostered against the client id (tenant) in Gooru. Client applications need to provide same client id and secret while performing SSO which id used while rostering the users.

This API will not return any details on error / exceptions for the failed records. Status API should be explicitly called with required parameters to get the status / error while rostering files.

NameValue
HTTP MethodPOST
End Pointhttp://{host}/api/nucleus-oneroster/{version}/upload
Samplehttp://oneroster.gooru.org/api/nucleus-oneroster/v1/upload

Headers

Header NameValue
AuthorizationBasic
Content-Typemultipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
  • Replace the correct value of encoded credentials in ‘Authorization’ header
  • Boundary in the ‘Content-Type’ header is sample. Need to be replaced with actual boundary while calling the API.

Request Payload

Attach the file with request.

Success Reponse

HTTP Status Code: 201 Created
Location header of the response will contain the Upload Id which can be used to get the status of the upload.

Error Response

In case of any error while uploading the Roster, API will not provide any details of error / exceptions for records in the files. For Error response codes, refer to Reference section in this document.

Get Upload Status

This API is used to get the status of the upload for give upload id. For now this API will return total records and success record counts. It may be enhanced in future to return records level details.

NameValue
HTTP MethodGET
End Pointhttp://{host}/api/nucleus-oneroster/{version}/upload/{uploadId}/status
Samplehttp://oneroster.gooru.org/api/nucleus-oneroster/v1/upload/62f3fbd3-4341-4e30-8efe-3b655074133d/status

Headers

Header NameValue
AuthorizationBasic
  • Replace the correct value of encoded credentials in ‘Authorization’ header.

Request Payload

No request payload required for this API

Success Response

HTTP Status Code: 200 OK

Error Response

Refer to reference section of this document below.

Possible Status

StatusPurpose
pendingDenotes the zip upload is success and pending to be process. The uploads are queued at server and picked up one by one.
acceptedDenotes that the upload zip file has been accepted for rostering. This is the status after parsing and validation of all csv files, and still the sync with Gooru main database is pending.
failedDenotes that the upload has been failed. In case of failure while rostering records, this status will be returned.
completedDenotes that the upload has been complete. When all records are rostered successfully, this status will be returned.

Responses

{
	"status": "pending",
	"total_records": {
		"orgs": 1,
		"users": 10,
		"classes": 2,
		"enrollments": 12
	},
	"success_records": {
		"orgs": 1,
		"users": 8,
		"classes": 2,
		"enrollments": 10
	}
}
{
    "status": "failed",
    "errors": {
        "orgs_errors": [
            {
                "error": "Field 'sourcedId' is mandatory but no value was provided.",
                "line_number": 3
            }
        ],
        "classes_errors": [
            {
                "error": "Field 'title' is mandatory but no value was provided.",
                "line_number": 1
            }
        ],
        "enrollments_errors": [
            {
                "error": "Field 'role' is mandatory but no value was provided.",
                "line_number": 29
            }
        ],
        "users_errors": [
            {
                "error": "Field 'username' is mandatory but no value was provided.",
                "line_number": 2
            }
        ]
    }
}
{
	"status": "accepted",
	"total_records": {
		"orgs": 1,
		"users": 10,
		"classes": 2,
		"enrollments": 12
	},
	"success_records": {
		"orgs": 0,
		"users": 0,
		"classes": 0,
		"enrollments": 0
	}
}
{
	"status": "completed",
	"total_records": {
		"orgs": 1,
		"users": 10,
		"classes": 2,
		"enrollments": 12
	},
	"success_records": {
		"orgs": 1,
		"users": 8,
		"classes": 2,
		"enrollments": 10
	}
}

Reference

HTTP Response Codes

HTTP Status CodeHTTP MethodResponse BodyDescription
200GETEntity which is requestedOperation successful without error
201 CreatedPOSTNo Entity in body except for the location of entity in headerEntity creation successful
204 No ContentPUT, DELETENo ContentEntity update or delete is successful
400 Bad RequestALLError messagesMalformed, invalid or incorrect request or request parameters which are applicable to this Entity
401 UnauthorizedALLNo ContentAction requires authentication or session token may have expired. Note that we don’t return www-authenticate headers as we do not want browser to participate in the auth flow.
403 ForbiddenALLError messageAuthentication failure, or invalid API key, or insufficient privileges
f693bd0a-a67e-4e2d-92c7-0b75d0b0dd3eALLNo ContentEntity not found
405 Not AllowedALLNo ContentEntity does not support the requested operation
408 Request TimeoutALLNo ContentRequest has timed out. The system was not able to complete the operation within specified time
413 Request Entity Too LargePOST, PUTNo ContentThe representation of payload is too large for server to handle, or is not allowed
500 Internal Server ErrorALLError messageSome exception happened while processing the request. The message may be technical and may not be suitable for UI consumption.

Do’s and Don’ts

  • Make sure to keep a track of all sourcedIds. These sourcedIds are required when you want to enrol the new user to the old class or old user to new class.
  • CSV files should include all columns in the same sequence, including optional ones irrespective of whether there is data or not.
  • One user can be associated to one organization only.
  • Always class is associated with a teacher account.
  • If you need to associate a Student to an existing class please use the same sourcedid of that respective class.
  • ​Supported organization type : "school"​
  • ​Supported Users Role : student, teacher​
  • Enrollments : make sure teacher related data is available first then student.
  • Update existing Users records: there is no change in the process. But if you need to delete any account, update the status column with appropriate value and sourcedId.
  • Update existing Enrollments:
  • If you want to add a new user to the existing class, make sure you provide the correct sourcedId in the enrollments.csv file