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

# Introduction

> Track your own learning content with time tracking and completion metrics

Custom Activities let you record learning sessions, measure time spent, and report completion metrics to the Timeback platform. You own your content and learning logic, while the SDK handles time tracking and event reporting.

<Tip>
  This section covers the SDK implementation for **Custom Activities**
  ([Level 1](/beta/build-on-timeback/integration-levels#level-1-minimal-viable)). For the
  step-by-step setup guide, see [Integrating existing apps](/beta/build-on-timeback/start-building/existing-apps).
  If you want Timeback to manage the lesson engine, see [Managed Lessons](/beta/build-on-timeback/sdk/managed-lessons/intro).
</Tip>

## When to use

|                       | Custom Activities                                                            | [Managed Lessons](/beta/build-on-timeback/sdk/managed-lessons/intro)       |
| --------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| **Content**           | Your own content and logic                                                   | Timeback's course builder                                                  |
| **Platform role**     | Time and completion reporting                                                | Sequencing, scoring, and XP                                                |
| **Integration level** | [Level 1](/beta/build-on-timeback/integration-levels#level-1-minimal-viable) | [Level 2](/beta/build-on-timeback/integration-levels#level-2-fully-native) |

## Choose your model

The SDK supports two activity models. Both use the same continuous time tracking under the hood; the difference is in how completion is handled.

<CardGroup cols={2}>
  <Card title="Single-session" icon="bolt" href="/beta/build-on-timeback/sdk/activity-tracking/single-session">
    Completed in one sitting. Client tracks time and reports completion.
  </Card>

  <Card title="Stateful" icon="arrows-rotate" href="/beta/build-on-timeback/sdk/activity-tracking/stateful">
    Spans multiple sessions. Client tracks time, server records completion.
  </Card>
</CardGroup>

<Tip>
  Not sure which to choose? See [Activity Models](/beta/about-timeback/concepts/activity-models)
  for a conceptual comparison.
</Tip>

## How time tracking works

Both models use **continuous heartbeat-based time tracking**. Rather than accumulating time and reporting it once at the end, the SDK sends periodic updates throughout the session. Each update reconciles a time window, reporting how many milliseconds were active and how many were inactive.

Heartbeats begin automatically when you call `activity.start()` and repeat at a regular interval (default 15s), and are sent as [`TimeSpentEvents`](/beta/build-on-timeback/reference/events#timespentevent).

```mermaid theme={null}
graph LR
    A["activity.start()"] --> B["Periodic heartbeats"]
    B --> C["activity.end()"]
    C --> D["Final heartbeat flush"]
    style A fill:#3b82f6,stroke:#2563eb,color:#fff
    style B fill:#8b5cf6,stroke:#7c3aed,color:#fff
    style C fill:#10b981,stroke:#059669,color:#fff
    style D fill:#f59e0b,stroke:#d97706,color:#fff
```

### Why this matters

* **Maximum 15s of data loss** if a student closes the tab unexpectedly (vs. losing the entire session)
* **Accurate per-window timestamps**: each event represents the actual engagement window
* **Visibility-aware**: time is only counted when the tab is in the foreground

### Abandoned tab detection

If a tab stays hidden for an extended period (default 10 minutes), the SDK stops heartbeats entirely. When the student returns, tracking resets from a clean slate. This prevents counting hours of abandoned-tab time.

## Event correlation with `runId`

Every activity is identified by a `runId`, a unique identifier generated at `activity.start()`.

All heartbeats, as well as the final completion event, share the same `runId`, which allows downstream systems to correlate time-spent data with completion results.

For [stateful activities](/beta/build-on-timeback/sdk/activity-tracking/stateful), the `runId` is persisted and reused when the student resumes, so heartbeats from different sessions are still correlated with the same completion event.

## Pause and resume

Both models support pause and resume. Paused time is not counted as active. The SDK distinguishes active and inactive milliseconds in every heartbeat.

When paused, the SDK flushes accumulated time and stops heartbeats. On resume, it starts a fresh tracking window. Optional `onPause` and `onResume` callbacks fire on both explicit calls and automatic state changes like [hidden timeouts](#abandoned-tab-detection).

See [`pause()` and `resume()`](/beta/build-on-timeback/sdk/activity-tracking/reference#methods) in the reference for usage.

## Configuration

Custom activity tracking requires a Caliper sensor URL in your [`timeback.config.json`](/beta/build-on-timeback/reference/configuration).

<Info>
  See the [configuration reference](/beta/build-on-timeback/reference/configuration#sensor-resolution) for sensor resolution rules and environment overrides.
</Info>

## Next Steps

<CardGroup cols={2}>
  <Card title="Single-session" icon="bolt" href="/beta/build-on-timeback/sdk/activity-tracking/single-session">
    Client-driven activities completed in one sitting
  </Card>

  <Card title="Stateful" icon="arrows-rotate" href="/beta/build-on-timeback/sdk/activity-tracking/stateful">
    Multi-session activities with server-side completion
  </Card>

  <Card title="Reference" icon="code" href="/beta/build-on-timeback/sdk/activity-tracking/reference">
    Parameters, properties, methods, and callbacks
  </Card>

  <Card title="Configuration" icon="gear" href="/beta/build-on-timeback/reference/configuration">
    Full timeback.config.json reference
  </Card>

  <Card title="Getting started" icon="rocket" href="/beta/build-on-timeback/start-building/existing-apps">
    Step-by-step setup guide for integrating existing apps
  </Card>
</CardGroup>
