Skip to main content
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.

List available lessons

Lessons are resolved from the courses defined in your config file. Call lessons.list() to fetch lessons across all configured courses:
const lessons = await timeback.lessons.list()
Each lesson includes an id, name, type, and questionCount.
See the reference for the full return type.
If your app configures multiple courses, you can narrow to a specific one:
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.

Where lessons come from

Lessons are derived from your course structure in OneRoster:
  1. The SDK resolves course IDs from timeback.config.json
  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. Course builder tooling to manage it is in development.
Courses must be set up before lessons.list() returns results. See the onboarding guide for how to get started.

Start a lesson

Call lessons.start() with the lesson you want to begin:
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.
See the reference for full parameter documentation.

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.
See the reference for all properties and methods.

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:
const session = await timeback.lessons.start({
	lessonId: lesson.id,
	course: { subject: 'Math', grade: 5 },
})

Framework integration

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>
	)
}

Next steps

Question loop

Fetch questions and submit answers

Reference

Parameters, properties, methods, and return types