Skip to main content
When the question loop is done, call session.complete() to finalize the lesson. This triggers server-side scoring, flushes the final time tracking data, and returns a comprehensive result object.

Complete a lesson

const result = await session.complete()
The result includes everything you need to render a results screen: score, accuracy, totalQuestions, correctQuestions, timeSpentSeconds, and more.
See the reference for the full return type.

What happens under the hood

session.complete() does three things in sequence:
  1. Server: calls PowerPath finalStudentAssessmentResponse() to lock in the score, calculate XP, and update the gradebook
  2. Client: calls activity.end() to flush the final time tracking window as a TimeSpentEvent
  3. Client: returns a merged result combining the server response with client-side timing data

Caliper event flow

Managed Lessons split Caliper responsibility between the SDK and PowerPath:
ConcernHandled byEvent
Time trackingSDK (automatic)TimeSpentEvent heartbeats throughout the session
Completion + XPPowerPath (server-side)ActivityEvent with calculated XP
The SDK does not send an ActivityCompletedEvent for Managed Lessons. PowerPath is the source of truth for scoring, XP calculation, and OneRoster gradebook updates. This means you do not need to calculate XP or report completion metrics yourself — PowerPath handles it when session.complete() calls the finalization endpoint.

Handle time tracking errors

The final time flush can fail independently of the lesson completion. When this happens, the result still contains valid scoring data, but timeTrackingSent will be false:
const result = await session.complete()

if (!result.timeTrackingSent) {
	console.warn('Time tracking flush failed:', result.error)
	// Scoring data is still valid -- the lesson completed successfully
	// The last ~15s of time data may be missing from analytics
}
This is a best-effort operation. The lesson result itself is always reliable.

Render results

Use the completion result to build a results screen:
const result = await session.complete()

// Use the discriminated LessonCompletionPayload for UI rendering
const payload = {
	status: 'completed' as const,
	score: result.score,
	totalQuestions: result.totalQuestions,
	correctQuestions: result.correctQuestions,
	accuracy: result.accuracy,
	timeSpentSeconds: result.timeSpentSeconds,
}

Next steps

Attempt history

Review past attempts and per-question data

Reference

Parameters, properties, methods, and return types