Skip to main content

Overview

The Core client (@timeback/core for TypeScript, timeback-core for Python) provides a unified client that aggregates all Timeback API clients with shared OAuth authentication:
  • OneRoster: Rostering and gradebook data
  • EduBridge: Simplified enrollments and analytics
  • Caliper: Learning analytics events
  • QTI: Assessment content management
  • PowerPath: Placement tests and adaptive learning
  • CASE: Competencies and standards
  • CLR: Comprehensive Learner Records
  • Webhooks: Webhook management and filters
  • MasteryTrack: Test inventory and assignments
All sub-clients share a single OAuth token, reducing authentication overhead.

Installation

npm install @timeback/core

Quick Start

import { TimebackClient } from '@timeback/core'

const timeback = new TimebackClient({
	env: 'staging',
	auth: {
		clientId: process.env.TIMEBACK_CLIENT_ID!,
		clientSecret: process.env.TIMEBACK_CLIENT_SECRET!,
	},
})

// Access any API through the unified client
const { data: schools } = await timeback.oneroster.schools.list()
const { data: users } = await timeback.oneroster.users.list({ where: { role: 'student' } })
await timeback.caliper.events.sendActivity(sensorUrl, activityInput)

Configuration

Environment Mode

Connect to Timeback’s hosted APIs:
const timeback = new TimebackClient({
	env: 'staging', // or 'production'
	auth: {
		clientId: process.env.TIMEBACK_CLIENT_ID!,
		clientSecret: process.env.TIMEBACK_CLIENT_SECRET!,
	},
})

Base URL Mode

Connect to a self-hosted or custom endpoint:
const timeback = new TimebackClient({
	baseUrl: 'https://timeback.myschool.edu',
	auth: {
		clientId: process.env.CLIENT_ID!,
		clientSecret: process.env.CLIENT_SECRET!,
		authUrl: 'https://timeback.myschool.edu/oauth/token',
	},
})

Explicit Services Mode

Full control over each service URL. Only configure the services you need:
const timeback = new TimebackClient({
	services: {
		oneroster: 'https://roster.example.com',
		caliper: 'https://analytics.example.com',
		// edubridge not configured — accessing it will throw
	},
	auth: {
		clientId: '...',
		clientSecret: '...',
		authUrl: 'https://auth.example.com/oauth/token',
	},
})
Each service can optionally override the default token URL (TypeScript):
const timeback = new TimebackClient({
	services: {
		oneroster: 'https://roster.example.com',
		caliper: {
			baseUrl: 'https://analytics.example.com',
			authUrl: 'https://analytics-auth.example.com/token',
		},
	},
	auth: {
		clientId: '...',
		clientSecret: '...',
		authUrl: 'https://auth.example.com/oauth/token',
	},
})

Accessing APIs

Each API is lazily initialized on first access:
// OneRoster - rostering and gradebook
timeback.oneroster.users.list()
timeback.oneroster.schools.get(schoolId)
timeback.oneroster.enrollments.list({ where: { role: 'student' } })

// EduBridge - simplified enrollments and analytics
timeback.edubridge.enrollments.list({ userId })
timeback.edubridge.analytics.getActivity({ studentId, startDate, endDate })

// Caliper - learning analytics
timeback.caliper.events.list()
timeback.caliper.events.sendActivity(sensor, input)

// QTI - assessment content
timeback.qti.assessmentItems.list()
timeback.qti.assessmentTests.get(testId)

// PowerPath - adaptive learning
timeback.powerpath.placement.getCurrentLevel({ student, subject })

// CASE - competencies and standards
timeback.case.documents.list()

// CLR - comprehensive learner records
timeback.clr.credentials.upsert(credential)

// Webhooks - webhook management
timeback.webhooks.webhooks.list()

Managing Multiple Clients

For applications that need to manage multiple TimebackClient instances, use TimebackManager:
import { TimebackManager } from '@timeback/core'

const manager = new TimebackManager()
	.register('alpha', {
		env: 'production',
		auth: { clientId: '...', clientSecret: '...' },
	})
	.register('beta', {
		env: 'production',
		auth: { clientId: '...', clientSecret: '...' },
	})

// Target a specific platform
const users = await manager.get('alpha').oneroster.users.list()

// Sync a user across all platforms (uses Promise.allSettled — never throws)
const results = await manager.broadcast(client => client.oneroster.users.create(user))

// Direct property access
if (results.alpha.ok) {
	console.log('Created on alpha:', results.alpha.value.id)
}

// Convenience methods
if (results.allSucceeded) {
	console.log('Synced to all platforms!')
}

results.succeeded.forEach(([name, user]) => {
	console.log(`Created on ${name}:`, user.id)
})

results.failed.forEach(([name, error]) => {
	console.error(`Failed on ${name}:`, error.message)
})

Manager API

MethodDescription
register(name, config)Add a named client
get(name)Retrieve a client by name
has(name)Check if a client is registered
namesGet all registered client names
sizeGet number of registered clients
broadcast(fn)Execute on all clients (never throws), returns BroadcastResults<T>
unregister(name)Remove and close a client
close()Close all clients

BroadcastResults API

Property/MethodDescription
succeededGet successful results as [name, value][]
failedGet failed results as [name, error][]
allSucceededtrue if all operations succeeded
anyFailedtrue if any operation failed
values()Get all values (throws if any failed)

Lifecycle

Check Authentication

Verify OAuth credentials are working:
const result = await timeback.checkAuth()

if (result.ok) {
	console.log('Auth OK, latency:', result.latencyMs, 'ms')
} else {
	console.error('Auth failed:', result.error)
}

Close the Client

Release resources when done:
timeback.close()

// After close(), further API calls will throw
console.log(timeback.closed) // true

Next Steps

OneRoster

Rostering and gradebook API

EduBridge

Simplified enrollments and analytics

Caliper

Learning analytics events

SDK

Full-stack SDK with SSO and activity tracking