> ## 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.

# Lesson discovery

> List available lessons and start a session

This guide covers how to discover available lessons and start a lesson session. By the end, you will have a `LessonSession` object ready for the [question loop](/beta/build-on-timeback/sdk/managed-lessons/question-loop).

## List available lessons

Lessons are resolved from the courses defined in your [config file](/beta/build-on-timeback/reference/configuration).

Call `lessons.list()` to fetch lessons across all configured courses:

```typescript theme={null}
const lessons = await timeback.lessons.list()
```

Each lesson includes an `id`, `name`, `type`, and `questionCount`.

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

<Tip>
  If your app configures multiple courses, you can narrow to a specific one:

  ```typescript theme={null}
  const mathLessons = await timeback.lessons.list({
  	course: { subject: 'Math', grade: 5 },
  })
  ```

  The `course` parameter matches against your configured courses; in other words, it's a filter, not an override.
</Tip>

### Where lessons come from

Lessons are derived from your course structure in OneRoster:

1. The SDK resolves course IDs from [`timeback.config.json`](/beta/build-on-timeback/reference/configuration)
2. It lists active **course components**
3. For each component, it lists active **component resources**
4. Each resource maps to a `Lesson` object

This structure is created during the [setup phase](/beta/build-on-timeback/start-building/native-apps). Course builder tooling to manage it is in development.

<Info>
  Courses must be set up before `lessons.list()` returns results. See the [onboarding
  guide](/beta/build-on-timeback/start-building/native-apps) for how to get started.
</Info>

## Start a lesson

Call `lessons.start()` with the lesson you want to begin:

```typescript theme={null}
const session = await timeback.lessons.start({
	lessonId: lesson.id,
	lessonType: lesson.type,
	course: { subject: 'Math', grade: 5 },
	name: lesson.name,
	forceNew: true,
})
```

This returns a `LessonSession`, a stateful object that manages the entire lesson lifecycle.

<Info>
  See the [reference](/beta/build-on-timeback/sdk/managed-lessons/reference#lessons-start) for
  full parameter documentation.
</Info>

### What happens under the hood

When you call `lessons.start()`, two things happen:

1. **Server**: the SDK calls PowerPath to check for an existing attempt or create a new one
2. **Client**: the SDK starts an activity tracker automatically, so `TimeSpentEvent` heartbeats begin immediately

The returned `LessonSession` tracks `score`, `attempt`, `finalized`, and other state that updates automatically as the session progresses.

<Info>
  See the [reference](/beta/build-on-timeback/sdk/managed-lessons/reference#lesson-session) for
  all properties and methods.
</Info>

### Resume vs new attempt

By default, `lessons.start()` resumes an existing in-progress attempt if one exists. Set `forceNew: true` to always start a fresh attempt:

<CodeGroup>
  ```typescript Resume existing attempt (default) theme={null}
  const session = await timeback.lessons.start({
  	lessonId: lesson.id,
  	course: { subject: 'Math', grade: 5 },
  })
  ```

  ```typescript Force new attempt theme={null}
  const session = await timeback.lessons.start({
  	lessonId: lesson.id,
  	course: { subject: 'Math', grade: 5 },
  	forceNew: true,
  })
  ```
</CodeGroup>

## Framework integration

<Tabs>
  <Tab title="React">
    ```tsx theme={null}
    import { useTimeback } from '@timeback/sdk/react'
    import { useState } from 'react'

    function LessonPicker() {
    	const timeback = useTimeback()
    	const [lessons, setLessons] = useState([])
    	const [session, setSession] = useState(null)

    	async function loadLessons() {
    		if (!timeback) return
    		const result = await timeback.lessons.list()
    		setLessons(result)
    	}

    	async function startLesson(lesson) {
    		if (!timeback) return
    		const s = await timeback.lessons.start({
    			lessonId: lesson.id,
    			lessonType: lesson.type,
    			course: { subject: 'Math', grade: 5 },
    			name: lesson.name,
    			forceNew: true,
    		})
    		setSession(s)
    	}

    	if (session) {
    		return <QuestionLoop session={session} />
    	}

    	return (
    		<div>
    			<button onClick={loadLessons}>Load lessons</button>
    			{lessons.map(lesson => (
    				<button key={lesson.id} onClick={() => startLesson(lesson)}>
    					{lesson.name}
    				</button>
    			))}
    		</div>
    	)
    }
    ```
  </Tab>
</Tabs>

## Next steps

<CardGroup cols={2}>
  <Card title="Question loop" icon="arrows-rotate" href="/beta/build-on-timeback/sdk/managed-lessons/question-loop">
    Fetch questions and submit answers
  </Card>

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