OneRoster CSV packages
Send a OneRoster 1.2 CSV package so the portal takes in seasons, students and enrollments.
Many student information systems export OneRoster CSV packages (one .zip file). The portal takes them in two ways:
- School staff upload the package under Kết nối hệ thống (always previewed before it is applied).
- The school's system sends it over the API:
POST /integration/v1/imports/oneroster, scopeimports:write.
Sending over the API
The body is the zip file itself, Content-Type: application/zip, up to 20 MB.
curl -X POST -H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/zip" \
-H "Idempotency-Key: 2026-11-13-oneroster" \
--data-binary @oneroster.zip \
"https://<trường>.<tên-miền-nền-tảng>/integration/v1/imports/oneroster?dryRun=true"The answer is 202 with a job; follow it at /jobs/{id} as in Sending data. With ?dryRun=true, counts shows what would change and nothing is saved; drop dryRun to apply. warnings.package holds the package version, each file's mode, how many non-student users were skipped, and notes.
An unreadable package returns 422 with type urn:ttdn:problem:invalid-package and the reason in detail.
What the package needs
| File | Required | Used for |
|---|---|---|
manifest.csv | yes | oneroster.version (1.2; 1.1 is also read) and file.<name> = bulk, delta or absent for each file |
users.csv | yes | Users; only those with the student role are taken |
roles.csv | for 1.2 | Users' roles (1.1 uses the role column of users.csv) |
academicSessions.csv | no | Terms (term, semester) become seasons |
classes.csv | no | Classes, to know each enrollment's term |
enrollments.csv | no | Students' class enrollments |
Other files (orgs.csv, courses.csv, demographics.csv...) are ignored. Each file has a header row and up to 50,000 rows.
How the portal reads it
- Seasons: each term (
termorsemester) used by the package's classes becomes a season, placed by its dates as when sending seasons. Without classes, every term is used. - Students: everyone with the
studentrole. The student code is taken fromidentifier, thenuserIdsas{studentCode:SV2026001}, thenusername. The full name is built in Vietnamese order:familyName middleName givenName.sourcedIdbecomesexternalId. - Sign-in: a row with
passwordsigns in with a login name (username, or the student code) and that password; without one, with Google usingemail. - Enrollments: a student enrolled in a class is admitted to the season of that class's term. Without
enrollments.csv, students are admitted to the open season. - Blocking:
status = tobedeletedorenabledUser = falseblocks the account. - No deletion: students missing from a
bulkfile are left as they are. Deleted terms and enrollments are noted, never applied. - Users with other roles (teachers, guardians...) are skipped and counted in
ignoredUsers.
When a term is in progress while the school has another season open, the portal creates the new season as upcoming and reports switchSeason in warnings. School staff confirm the switch under Kết nối hệ thống.