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

# Configuration

> Complete reference for timeback.config.json

## Overview

The `timeback.config.json` file configures your Timeback integration, defining courses, sensors, and environment-specific overrides.

## Location

This file is generated by [`timeback init`](/beta/build-on-timeback/cli/init) during project setup and typically lives in your project root:

<Tree>
  <Tree.Folder name="my-app" defaultOpen>
    <Tree.File name="timeback.config.json" />

    <Tree.File name="package.json" />

    <Tree.Folder name="src" />
  </Tree.Folder>
</Tree>

## Schema

Use the JSON schema for autocompletion and validation:

```json timeback.config.json theme={null}
{
	"$schema": "https://timeback.dev/schema.json"
}
```

## Complete example

```json timeback.config.json theme={null}
{
	"$schema": "https://timeback.dev/schema.json",
	"name": "My Learning App",
	"sensor": "https://my-app.example.com/sensors/default",
	"launchUrl": "https://my-app.example.com/start",
	"defaults": {
		"level": "Elementary"
	},
	"courses": [
		{
			"subject": "Math",
			"grade": 3,
			"courseCode": "MATH-3",
			"level": "Elementary",
			"sensor": "https://my-app.example.com/sensors/math",
			"launchUrl": "https://my-app.example.com/math",
			"metadata": {
				"courseType": "base",
				"publishStatus": "testing",
				"contactEmail": "math-team@example.com",
				"goals": {
					"dailyXp": 100,
					"dailyLessons": 3,
					"dailyActiveMinutes": 25,
					"dailyAccuracy": 80,
					"dailyMasteredUnits": 2
				},
				"metrics": {
					"totalXp": 2500,
					"totalLessons": 42,
					"totalGrades": 1
				}
			},
			"overrides": {
				"staging": {
					"level": "Staging",
					"sensor": "https://staging.my-app.example.com/sensors/math",
					"metadata": {
						"publishStatus": "draft",
						"metrics": {
							"totalLessons": 10
						}
					}
				},
				"production": {
					"metadata": {
						"publishStatus": "published"
					}
				}
			}
		}
	]
}
```

## Root properties

<ResponseField name="name" type="string" required>
  Display name for your application.
</ResponseField>

<ResponseField name="sensor" type="string (URL)">
  Default Caliper sensor endpoint URL for activity tracking. Can be overridden per-course. See
  [Sensor resolution](#sensor-resolution).
</ResponseField>

<ResponseField name="launchUrl" type="string (URL)">
  Default LTI launch URL. Can be overridden per-course.
</ResponseField>

<ResponseField name="defaults" type="CourseDefaults">
  Default values applied to all courses.

  <Expandable title="defaults fields">
    <ResponseField name="courseCode" type="string">
      Default course code.
    </ResponseField>

    <ResponseField name="level" type="string">
      Default course level (e.g., `"Elementary"`, `"AP"`, `"Honors"`).
    </ResponseField>

    <ResponseField name="metadata" type="CourseMetadata">
      Default metadata applied to all courses. See [Course metadata](#course-metadata).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="courses" type="CourseConfig[]" required>
  Array of course definitions (minimum 1). See [Course properties](#course-properties).
</ResponseField>

<ResponseField name="studio" type="object">
  Studio-specific configuration.

  <Expandable title="studio fields">
    <ResponseField name="telemetry" type="boolean" default="true">
      Enable anonymous usage telemetry.
    </ResponseField>
  </Expandable>
</ResponseField>

## Course properties

Each course must have either `grade` or `courseCode` (or both). All `(subject, grade)` pairs must be unique, and all `courseCode` values must be unique.

<ResponseField name="subject" type="TimebackSubject" required>
  Subject area. One of: `"Math"`, `"Reading"`, `"Language"`, `"Vocabulary"`, `"Writing"`,
  `"Science"`, `"Social Studies"`, `"FastMath"`, `"None"`, `"Other"`.
</ResponseField>

<ResponseField name="grade" type="number">
  Grade level. `-1` for Pre-K, `0` for Kindergarten, `1`--`12` for grades, `13` for AP. Required
  if `courseCode` is not provided.
</ResponseField>

<ResponseField name="courseCode" type="string">
  Unique course identifier (e.g., `"MATH-3"`). Required if `grade` is not provided.
</ResponseField>

<ResponseField name="level" type="string">
  Course level description (e.g., `"Elementary"`, `"AP"`, `"Honors"`).
</ResponseField>

<ResponseField name="sensor" type="string (URL)">
  Caliper sensor endpoint URL for this course. Overrides the root `sensor`.
</ResponseField>

<ResponseField name="launchUrl" type="string (URL)">
  LTI launch URL for this course. Overrides the root `launchUrl`.
</ResponseField>

<ResponseField name="ids" type="object">
  Environment-specific course IDs, populated automatically by `timeback sync`.

  <Expandable title="ids fields">
    <ResponseField name="staging" type="string">
      Course ID in the staging environment.
    </ResponseField>

    <ResponseField name="production" type="string">
      Course ID in the production environment.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="metadata" type="CourseMetadata">
  Course metadata including publication status, goals, and metrics. See [Course
  metadata](#course-metadata).
</ResponseField>

<ResponseField name="overrides" type="object">
  Per-environment overrides. See [Overrides](#overrides).

  <Expandable title="overrides fields">
    <ResponseField name="staging" type="CourseEnvOverrides">
      Overrides applied in the staging environment.
    </ResponseField>

    <ResponseField name="production" type="CourseEnvOverrides">
      Overrides applied in the production environment.
    </ResponseField>
  </Expandable>
</ResponseField>

## Course metadata

All metadata fields are optional. Metadata set in `defaults.metadata` is merged into every course.

<ResponseField name="courseType" type="string">
  Course classification: `"base"`, `"hole-filling"`, or `"optional"`.
</ResponseField>

<ResponseField name="isSupplemental" type="boolean">
  Whether this course is supplemental to a base course.
</ResponseField>

<ResponseField name="isCustom" type="boolean">
  Whether this is a custom course generated for an individual student.
</ResponseField>

<ResponseField name="publishStatus" type="string">
  Publication state: `"draft"`, `"testing"`, `"published"`, or `"deactivated"`.
</ResponseField>

<ResponseField name="contactEmail" type="string">
  Contact email for course issues.
</ResponseField>

<ResponseField name="primaryApp" type="string">
  Primary application identifier.
</ResponseField>

<ResponseField name="goals" type="CourseGoals">
  Daily learning goals for students in this course.

  <Expandable title="goals fields">
    <ResponseField name="dailyXp" type="number (positive integer)">
      Target XP to earn per day.
    </ResponseField>

    <ResponseField name="dailyLessons" type="number (positive integer)">
      Target lessons to complete per day.
    </ResponseField>

    <ResponseField name="dailyActiveMinutes" type="number (positive integer)">
      Target active learning minutes per day.
    </ResponseField>

    <ResponseField name="dailyAccuracy" type="number (0--100)">
      Target accuracy percentage per day.
    </ResponseField>

    <ResponseField name="dailyMasteredUnits" type="number (positive integer)">
      Target units to master per day.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="metrics" type="CourseMetrics">
  Aggregate course metrics.

  <Expandable title="metrics fields">
    <ResponseField name="totalXp" type="number (positive integer)">
      Total XP available in the course.
    </ResponseField>

    <ResponseField name="totalLessons" type="number (positive integer)" required>
      Total number of lessons in the course. Used as the denominator when the server
      auto-computes `pctCompleteApp` from
      [`masteredUnits`](/beta/build-on-timeback/sdk/activity-tracking/course-progress).
    </ResponseField>

    <ResponseField name="totalGrades" type="number (positive integer)">
      Total grade levels covered by this course.
    </ResponseField>
  </Expandable>
</ResponseField>

### Course metadata example

```json timeback.config.json (course excerpt) theme={null}
{
	"metadata": {
		"courseType": "base",
		"publishStatus": "published",
		"contactEmail": "math-team@example.com",
		"goals": {
			"dailyXp": 100,
			"dailyLessons": 3,
			"dailyActiveMinutes": 25
		},
		"metrics": {
			"totalXp": 2500,
			"totalLessons": 42,
			"totalGrades": 1
		}
	}
}
```

## Overrides

Each environment override can contain `level`, `sensor`, `launchUrl`, and `metadata`. Metadata in overrides is **merged** with the base metadata — it does not replace it.

```json timeback.config.json (course excerpt) theme={null}
{
	"overrides": {
		"staging": {
			"level": "Staging",
			"sensor": "https://staging.example.com/sensors/math",
			"metadata": {
				"publishStatus": "draft",
				"metrics": {
					"totalLessons": 10
				}
			}
		},
		"production": {
			"metadata": {
				"publishStatus": "published"
			}
		}
	}
}
```

### Merge behavior

Overrides are merged in this order (highest priority last):

1. `defaults` (lowest priority)
2. Course base values
3. `overrides[env]` (highest priority)

| Field       | Merge strategy                                        |
| ----------- | ----------------------------------------------------- |
| `level`     | Replaced entirely                                     |
| `sensor`    | Replaced entirely                                     |
| `launchUrl` | Replaced entirely                                     |
| `metadata`  | Merged — nested `goals` and `metrics` are deep-merged |

## Sensor resolution

Each course must have a resolvable sensor. The SDK checks these sources in order:

1. `course.overrides[env].sensor`
2. `course.sensor`
3. Root `sensor`
4. Derived from `launchUrl` origin (falls back to `course.launchUrl`, then root `launchUrl`)

If no sensor can be resolved, config validation fails.

## Next steps

<CardGroup cols={2}>
  <Card title="Environment" icon="cloud" href="/beta/build-on-timeback/reference/environment">
    Environment variables and credentials
  </Card>

  <Card title="Course progress" icon="chart-pie" href="/beta/build-on-timeback/sdk/activity-tracking/course-progress">
    How `totalLessons` and `masteredUnits` drive `pctCompleteApp`
  </Card>

  <Card title="CLI resources" icon="folder" href="/beta/build-on-timeback/cli/resources">
    Push and pull configurations
  </Card>

  <Card title="Events" icon="bolt" href="/beta/build-on-timeback/reference/events">
    Caliper event schemas
  </Card>
</CardGroup>
