Skip to main content

Curriculum API

The Curriculum API manages the learning content hierarchy that lives under courses: Units group lessons, Lessons place resources at positions within units, and Resources are the actual content items (videos, QTI assessments, articles, etc.). The hierarchy is Course → Unit → Lesson → Resource.

All endpoints use the same /rostering/1.0 prefix as the Rostering API — rostering and curriculum paths are disjoint with no conflicts. All endpoints require Authorization: Bearer <token>.

Base prefix: https://api.alpha-1edtech.ai/rostering/1.0


GET /rostering/1.0/units

Returns a paginated list of all units (across all your courses). Supports filter/sort/search.

Scope: roster.readonly

Query params

NameDescriptionRequired
limitMaximum records per page (default 100, max 1000)no
offsetNumber of records to skip (default 0)no
filterOneRoster filter expressionno
sortField to sort byno
orderBySort direction: asc or descno
searchFree-text search termno
fieldsComma-separated list of fields to includeno

Response

200 OK{ "units": [...], "offset": 0, "limit": 100, "total": N }

Each unit includes: sourcedId, title, course, parent, sortOrder, prerequisites.

Example

curl "https://api.alpha-1edtech.ai/rostering/1.0/units" \
-H "Authorization: Bearer <ACCESS_TOKEN>"

GET /rostering/1.0/units/:sourcedId

Returns a single unit by its sourcedId.

Scope: roster.readonly

Path params

NameDescription
sourcedIdUnit UUID

Response

200 OK{ "unit": { ... } }. 404 if not found.

Example

curl "https://api.alpha-1edtech.ai/rostering/1.0/units/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" \
-H "Authorization: Bearer <ACCESS_TOKEN>"

PUT /rostering/1.0/units/:sourcedId

Create or update a Unit under a Course.

Unit is an Alpha extension following OneRoster conventions. The curriculum hierarchy is Course -> Unit -> Lesson -> Resource.

Required fields: sourcedId, status, dateLastModified, title, course.

Create the parent Course first, then PUT Units referencing it.

Scope: roster.createput

Path params

NameDescription
sourcedIdUnit UUID (must match body)

Request body

Wrapped as { "unit": { ... } }.

FieldTypeRequiredDescription
sourcedIdstring (UUID)yesMust match the URL path parameter
dateLastModifiedstring (ISO 8601)yesTimestamp
titlestringyesDisplay name (e.g., "Fractions Unit 1")
course{ sourcedId }yesParent course reference
parent{ sourcedId } or nullnoParent unit reference (null for root-level units)
sortOrderintegernoOrder among siblings (default 0)
prerequisitesstring[]nosourcedIds this unit depends on (pass-through only)
metadataobjectnoStored as extensions on GET

Response

201 Created or 200 OK{ "status": "...", "sourcedId": "..." }

Example

curl -X PUT "https://api.alpha-1edtech.ai/rostering/1.0/units/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"unit": {
"sourcedId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"dateLastModified": "2026-01-15T00:00:00.000Z",
"title": "Fractions Unit 1",
"course": { "sourcedId": "44444444-4444-4444-4444-444444444444" },
"sortOrder": 1
}
}'

DELETE /rostering/1.0/units/:sourcedId

Soft-deletes the unit by setting its status to 'tobedeleted'. Ownership enforced.

Scope: roster.createput

Path params

NameDescription
sourcedIdUnit UUID

Response

204 No Content on success. 403 — ownership violation. 404 — not found.

Example

curl -X DELETE "https://api.alpha-1edtech.ai/rostering/1.0/units/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" \
-H "Authorization: Bearer <ACCESS_TOKEN>"

GET /rostering/1.0/courses/:sourcedId/units

Returns root-level units belonging to a course.

Scope: roster.readonly

Path params

NameDescription
sourcedIdCourse UUID

Query params

Standard pagination query params.

Response

200 OK{ "units": [...], "offset": 0, "limit": 100, "total": N }

Example

curl "https://api.alpha-1edtech.ai/rostering/1.0/courses/44444444-4444-4444-4444-444444444444/units" \
-H "Authorization: Bearer <ACCESS_TOKEN>"

GET /rostering/1.0/units/:sourcedId/units

Returns sub-units of the given unit.

Scope: roster.readonly

Path params

NameDescription
sourcedIdParent Unit UUID

Query params

Standard pagination query params.

Response

200 OK{ "units": [...], "offset": 0, "limit": 100, "total": N }

Example

curl "https://api.alpha-1edtech.ai/rostering/1.0/units/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/units" \
-H "Authorization: Bearer <ACCESS_TOKEN>"

GET /rostering/1.0/units/:sourcedId/lessons

Returns lessons belonging to a unit.

Scope: roster.readonly

Path params

NameDescription
sourcedIdUnit UUID

Query params

Standard pagination query params.

Response

200 OK{ "lessons": [...], "offset": 0, "limit": 100, "total": N }

Example

curl "https://api.alpha-1edtech.ai/rostering/1.0/units/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/lessons" \
-H "Authorization: Bearer <ACCESS_TOKEN>"

GET /rostering/1.0/lessons

Returns a paginated list of all lessons. Supports filter/sort/search.

Scope: roster.readonly

Query params

Standard pagination query params.

Response

200 OK{ "lessons": [...], "offset": 0, "limit": 100, "total": N }

Each lesson includes: sourcedId, title, unit, resource, sortOrder, lessonType.

Example

curl "https://api.alpha-1edtech.ai/rostering/1.0/lessons" \
-H "Authorization: Bearer <ACCESS_TOKEN>"

GET /rostering/1.0/lessons/:sourcedId

Returns a single lesson by its sourcedId.

Scope: roster.readonly

Path params

NameDescription
sourcedIdLesson UUID

Response

200 OK{ "lesson": { ... } }. 404 if not found.

Example

curl "https://api.alpha-1edtech.ai/rostering/1.0/lessons/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" \
-H "Authorization: Bearer <ACCESS_TOKEN>"

PUT /rostering/1.0/lessons/:sourcedId

Create or update a Lesson — the placement of a Resource in a Unit.

Required fields: sourcedId, status, dateLastModified, title, unit, resource.

Create the Unit and Resource first, then PUT the Lesson linking them.

Scope: roster.createput

Path params

NameDescription
sourcedIdLesson UUID (must match body)

Request body

Wrapped as { "lesson": { ... } }.

FieldTypeRequiredDescription
sourcedIdstring (UUID)yesMust match the URL path parameter
dateLastModifiedstring (ISO 8601)yesTimestamp
titlestringyesDisplay name
unit{ sourcedId }yesParent unit reference
resource{ sourcedId }yesThe resource this lesson places in the curriculum
sortOrderintegernoOrder within the unit (default 0)
lessonTypestringnoOne of: powerpath-100, quiz, test-out, placement, unit-test, alpha-read-article
metadataobjectnoStored as extensions on GET

Response

201 Created or 200 OK{ "status": "...", "sourcedId": "..." }

Example

curl -X PUT "https://api.alpha-1edtech.ai/rostering/1.0/lessons/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"lesson": {
"sourcedId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
"dateLastModified": "2026-01-15T00:00:00.000Z",
"title": "Introduction to Fractions",
"unit": { "sourcedId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" },
"resource": { "sourcedId": "cccccccc-cccc-cccc-cccc-cccccccccccc" },
"sortOrder": 1,
"lessonType": "quiz"
}
}'

DELETE /rostering/1.0/lessons/:sourcedId

Soft-deletes the lesson. Ownership enforced.

Scope: roster.createput

Path params

NameDescription
sourcedIdLesson UUID

Response

204 No Content on success. 403 — ownership violation. 404 — not found.

Example

curl -X DELETE "https://api.alpha-1edtech.ai/rostering/1.0/lessons/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" \
-H "Authorization: Bearer <ACCESS_TOKEN>"

GET /rostering/1.0/resources

Returns a paginated list of all resources. Supports filter/sort/search.

Scope: roster.readonly

Query params

Standard pagination query params.

Response

200 OK{ "resources": [...], "offset": 0, "limit": 100, "total": N }

Each resource includes: sourcedId, title, type, url, vendorResourceId, learningObjectiveSet.

Example

curl "https://api.alpha-1edtech.ai/rostering/1.0/resources" \
-H "Authorization: Bearer <ACCESS_TOKEN>"

GET /rostering/1.0/resources/:sourcedId

Returns a single resource by its sourcedId with synthesized metadata (url, description, learningObjectiveSet promoted to top-level).

Scope: roster.readonly

Path params

NameDescription
sourcedIdResource UUID

Response

200 OK{ "resource": { ... } }. 404 if not found.

Example

curl "https://api.alpha-1edtech.ai/rostering/1.0/resources/cccccccc-cccc-cccc-cccc-cccccccccccc" \
-H "Authorization: Bearer <ACCESS_TOKEN>"

PUT /rostering/1.0/resources/:sourcedId

Create or update a Resource (content item).

Required fields: sourcedId, status, dateLastModified, title, vendorResourceId, url, learningObjectiveSet.

Each learningObjectiveId is validated against the standards tables. Invalid IDs return 400 with an invalidIds array.

Workflow: (1) GET /standards/1.0/frameworks to find a framework, (2) GET /standards/1.0/frameworks/{id}/package to browse objectives, (3) submit objective sourcedIds here with source='CASE'.

Scope: roster.createput

Path params

NameDescription
sourcedIdResource UUID (must match body)

Request body

Wrapped as { "resource": { ... } }.

FieldTypeRequiredDescription
sourcedIdstring (UUID)yesMust match the URL path parameter
dateLastModifiedstring (ISO 8601)yesTimestamp
titlestringyesDisplay name
typestringyesContent type: qti, text, audio, video, interactive, visual, course-material, assessment-bank
urlstring (URL)yesWhere students access this content
learningObjectiveSetarrayyesAt least one entry: { "source": "CASE", "learningObjectiveIds": ["..."] }
vendorResourceIdstringnoYour internal ID (defaults to sourcedId if omitted)
subTypestringnoRequired when type is qti or course-material
formatstringnoRequired when type is text, audio, video, or visual (e.g., "mp4", "html")
descriptionstringnoHuman-readable description
rolesstring[]no["primary"], ["secondary"], etc.
metadataobjectnoStored as extensions on GET

Response

201 Created or 200 OK{ "status": "...", "sourcedId": "..." }

400 Bad Request — validation error including invalidIds array for bad objective IDs.

Example

curl -X PUT "https://api.alpha-1edtech.ai/rostering/1.0/resources/cccccccc-cccc-cccc-cccc-cccccccccccc" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"resource": {
"sourcedId": "cccccccc-cccc-cccc-cccc-cccccccccccc",
"dateLastModified": "2026-01-15T00:00:00.000Z",
"title": "Fractions Quiz 1",
"type": "qti",
"subType": "qti-test",
"url": "https://vendor.example.com/assessments/fractions-quiz-1",
"learningObjectiveSet": [
{ "source": "CASE", "learningObjectiveIds": ["OBJECTIVE_SOURCED_ID"] }
]
}
}'

DELETE /rostering/1.0/resources/:sourcedId

Soft-deletes the resource. Ownership enforced.

Scope: roster.createput

Path params

NameDescription
sourcedIdResource UUID

Response

204 No Content on success. 403 — ownership violation. 404 — not found.

Example

curl -X DELETE "https://api.alpha-1edtech.ai/rostering/1.0/resources/cccccccc-cccc-cccc-cccc-cccccccccccc" \
-H "Authorization: Bearer <ACCESS_TOKEN>"