Student Course Progress
Track a student's progress through a course curriculum tree — see which sections, topics, levels, and lessons the student has completed, with timestamps.
Note: This guide covers the integration workflow and response structure. For complete endpoint documentation, see the API Reference.
Overview
The Student Course Progress endpoint returns a recursive curriculum tree for a specific course, annotated with per-item completion status for a given student. It combines the CASE curriculum structure (CFItems linked via isChildOf associations) with Caliper completion events to produce a unified progress view.
Prerequisites
- Course exists — The course must be a CFItem with
typeCode = 'course'in the CASE framework. See Curriculum Management for how courses are structured. - Student exists — The student must be a registered OneRoster user on the platform.
- Completion events — The learning application must fire Caliper
AssignableEventevents withaction: Completedfor curriculum items as the student progresses. Without these events, the tree will show all items as incomplete.
Authentication
This endpoint requires the CASE read-only scope:
| Scope | Grants |
|---|---|
https://purl.imsglobal.org/spec/case/v1p0/scope/case.readonly |
Read access to curriculum progress |
Endpoint
GET /curriculum/1.0/courses/{courseId}/students/{studentId}/progress
Path Parameters
| Parameter | Type | Description |
|---|---|---|
courseId |
UUID | CFItem identifier of the course |
studentId |
UUID | OneRoster user sourcedId of the student |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
applicationId |
UUID | No | Scope completion lookup to a specific learning application |
Response Structure
The response is a recursive tree where each node represents a curriculum item:
{
"cfItemId": "course-uuid",
"typeCode": "course",
"completed": false,
"completedAt": null,
"children": [
{
"cfItemId": "section-uuid",
"typeCode": "section",
"completed": false,
"completedAt": null,
"children": [
{
"cfItemId": "topic-uuid",
"typeCode": "topic",
"completed": true,
"completedAt": "2026-04-06T14:30:00.000Z",
"children": []
}
]
}
]
}
| Field | Type | Description |
|---|---|---|
cfItemId |
string (UUID) | The CFItem identifier |
typeCode |
string | The item type code (e.g., course, section, topic, level, lesson) |
completed |
boolean | Whether the student has completed this item |
completedAt |
string | null | ISO 8601 timestamp of completion, or null if not completed |
children |
array | Child items in the curriculum hierarchy |
How Completion Is Determined
A curriculum item is marked as completed: true when a Caliper event exists with:
- Event type:
AssignableEvent - Action:
Completed - Actor: The student (matched by their OneRoster
sourcedId) - Object: The curriculum item (matched by CFItem
identifier)
If applicationId is provided, only completion events from that specific application are considered.
Usage Example
const courseId = '5ef7ba25-fff5-11ed-bfbf-0e2145d6cfdf';
const studentId = 'abc0d677-0070-4996-85b1-271c4f5feb73';
const response = await fetch(
`https://platform.timeback.com/curriculum/1.0/courses/${courseId}/students/${studentId}/progress`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
},
);
const progress = await response.json();
// Count completed items
function countCompleted(node) {
let count = node.completed ? 1 : 0;
for (const child of node.children) {
count += countCompleted(child);
}
return count;
}
Related Endpoints
GET /curriculum/1.0/documents/{documentId}/courses— List available courses for a documentGET /curriculum/1.0/documents/{documentId}/courses/{courseId}— Get the full curriculum tree for a course (without progress)
