> ## Documentation Index
> Fetch the complete documentation index at: https://docs.timeback.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Completion

> Finalize a lesson, interpret results, and understand Caliper behavior

When the [question loop](/beta/build-on-timeback/sdk/managed-lessons/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

```typescript theme={null}
const result = await session.complete()
```

The result includes everything you need to render a results screen: `score`, `accuracy`, `totalQuestions`, `correctQuestions`, `timeSpentSeconds`, and more.

<Info>
  See the [reference](/beta/build-on-timeback/sdk/managed-lessons/reference#lessonsessioncompleteresult) for the full return type.
</Info>

## What happens under the hood

`session.complete()` does three things in sequence:

```mermaid theme={null}
graph LR
    A["session.complete()"] --> B["PowerPath finalize"]
    B --> C["Flush time data"]
    C --> D["Return merged result"]
```

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:

| Concern         | Handled by              | Event                                              |
| --------------- | ----------------------- | -------------------------------------------------- |
| Time tracking   | SDK (automatic)         | `TimeSpentEvent` heartbeats throughout the session |
| Completion + XP | PowerPath (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`:

```typescript theme={null}
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:

```typescript theme={null}
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

<CardGroup cols={2}>
  <Card title="Attempt history" icon="clock-rotate-left" href="/beta/build-on-timeback/sdk/managed-lessons/attempt-history">
    Review past attempts and per-question data
  </Card>

  <Card title="Reference" icon="code" href="/beta/build-on-timeback/sdk/managed-lessons/reference">
    Parameters, properties, methods, and return types
  </Card>
</CardGroup>
