Two approaches
You can report progress in two ways. Both are passed as part of completion metrics (client) ortimeback.activity.record() (server).
masteredUnits (recommended)
If your app tracks mastery at the lesson level, pass masteredUnits and let the server auto-compute pctComplete for you. The SDK reads historical EduBridge analytics and uses a positive totalLessons in the selected course configuration as its denominator. It does not maintain an atomic running total.
pctComplete directly
If your app already tracks overall course progress, you can pass pctComplete (0—100) directly when ending an activity. The SDK skips historical computation for an explicit value. Keep it within 0–100: browser submissions clamp out-of-range numbers, while the TypeScript server API rejects them.
How masteredUnits works
masteredUnits is an incremental count; it represents how many new units (lessons) a student mastered during this specific activity, not a cumulative total.
What the server does
WhenmasteredUnits is provided and pctComplete is omitted, the server:
- Resolves a positive
totalLessons, preferring environment-specific metadata over base metadata. - Finds the student’s enrollment for the synced course and reads its EduBridge enrollment facts.
- Sums historical mastered units. It adds the current count only if weekly facts do not already contain the same activity ID and course/enrollment context. If that weekly check fails, it conservatively omits the current count.
- Computes an integer percentage and clamps it to 0–100, then emits
pctCompleteAppin theActivityCompletedEvent.
Math.round; Python uses round, which differs on exact half ties.
If
pctComplete is provided alongside masteredUnits, the SDK validates the explicit value for the relevant API and
does not run the auto-computation. The explicit value always wins.Configuration
Configuremetadata.metrics.totalLessons for courses that use automatic progress. The fragment below shows the relevant fields; include the other required app/course settings from the configuration reference.
Relevant configuration fields
Example walkthrough
Assume a course hastotalLessons: 10, historical facts are up to date, and each activity is new for this enrollment.
A student completes three activities over time:
After the third submission, the student is 70% through the course.
Best practices
Send masteredUnits as an incremental count
Send masteredUnits as an incremental count
When a student masters one lesson, send
masteredUnits: 1. If they master two lessons in
the same activity session, send masteredUnits: 2. The value always represents how many
new units were mastered during this activity — never a running total.Attribute mastery for a lesson exactly once
Attribute mastery for a lesson exactly once
If a student replays a lesson they already mastered, do not send
masteredUnits again for
that lesson. Double-counting inflates the student’s progress percentage because the server
sums all historical values.Omit masteredUnits when no lessons were mastered
Omit masteredUnits when no lessons were mastered
If no lessons were mastered during the activity, omit
masteredUnits entirely (or send
0). The server only runs the auto-computation when masteredUnits is a number greater
than zero.Next steps
Custom Activities reference
Full API for
activity.end() and timeback.activity.record()Events
Caliper event schemas including
ActivityCompletedEventConfiguration
timeback.config.json reference including totalLessonsStateful activities
Multi-session activities where completion is recorded server-side