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

# Attempt history

> Review past lesson attempts and per-question results

After a student completes one or more lesson attempts, you can retrieve their history and review per-question results. This is useful for building review screens, progress dashboards, or retry flows.

## List past attempts

Call `lessons.attempts()` to get all attempts for a lesson:

```typescript theme={null}
const attempts = await timeback.lessons.attempts({
	lessonId: lesson.id,
})
```

Each attempt includes `attempt` number, `score`, `finalized` status, `totalQuestions`, and `correctQuestions`.

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

## Get attempt details

To see per-question data for a specific attempt, call `lessons.attemptDetails()`:

```typescript theme={null}
const details = await timeback.lessons.attemptDetails({
	lessonId: lesson.id,
	attempt: 1,
})
```

### Extract questions

Use `getLessonAttemptQuestions()` to get a flat list of questions from the response:

```typescript theme={null}
import { getLessonAttemptQuestions } from '@timeback/sdk'

const questions = getLessonAttemptQuestions(details)
```

Each question includes `id`, `correct`, `studentResponse`, and `content.rawXml` for re-rendering.

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

<Accordion title="Why do I need a helper for this?">
  The raw response shape differs by lesson type. Adaptive lessons (`powerpath-100`) return
  `seenQuestions`, which is only the questions PowerPath actually served (the count varies per
  student). Linear lessons (`quiz`, `test-out`, etc.) return `questions`, which is the full
  fixed set for the attempt.

  `getLessonAttemptQuestions()` normalizes both into a single `LessonAttemptQuestion[]`. If you
  need to distinguish the two (e.g., to show "X of Y questions seen" for adaptive lessons),
  check `details.lessonType` and access the raw fields directly.
</Accordion>

## Build a review screen

A typical review flow:

```typescript theme={null}
// 1. Load attempts
const attempts = await timeback.lessons.attempts({ lessonId })

// 2. Let the student pick an attempt to review
const selected = attempts[0]

// 3. Load details
const details = await timeback.lessons.attemptDetails({
	lessonId,
	attempt: selected.attempt,
})

// 4. Get questions
const questions = getLessonAttemptQuestions(details)

// 5. Render review cards
for (const q of questions) {
	renderReviewCard({
		questionXml: q.content.rawXml,
		studentAnswer: q.studentResponse,
		wasCorrect: q.correct,
	})
}
```

## Next steps

<CardGroup cols={2}>
  <Card title="Lesson discovery" icon="magnifying-glass" href="/beta/build-on-timeback/sdk/managed-lessons/lesson-discovery">
    Start a new lesson
  </Card>

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