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

# Express

> Integrate Timeback with Express.js

## Overview

The Timeback SDK provides an Express middleware adapter.

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @timeback/sdk express
  ```

  ```bash pnpm theme={null}
  pnpm add @timeback/sdk express
  ```

  ```bash yarn theme={null}
  yarn add @timeback/sdk express
  ```

  ```bash bun theme={null}
  bun add @timeback/sdk express
  ```
</CodeGroup>

## Server Setup

Create a Timeback instance:

```typescript lib/timeback.ts theme={null}
import { createTimeback } from '@timeback/sdk'

export const timeback = await createTimeback({
	env: 'staging',
	api: {
		clientId: process.env.TIMEBACK_API_CLIENT_ID!,
		clientSecret: process.env.TIMEBACK_API_CLIENT_SECRET!,
	},
	identity: {
		mode: 'sso',
		clientId: process.env.AWS_COGNITO_CLIENT_ID!,
		clientSecret: process.env.AWS_COGNITO_CLIENT_SECRET!,
		redirectUri: 'http://localhost:3000/api/timeback/identity/callback',
		onCallbackSuccess: async ({ user, state, redirect }) => {
			await setSession({ id: user.id, email: user.email })
			return redirect(state?.returnTo ?? '/')
		},
		onCallbackError: ({ error, redirect }) => {
			return redirect('/?error=sso_failed')
		},
		getUser: req => getSessionFromRequest(req),
	},
})
```

## Middleware

Add the Timeback middleware to your Express app:

```typescript server.ts theme={null}
import { toExpressMiddleware } from '@timeback/sdk/express'
import express from 'express'

import { timeback } from './lib/timeback'

const app = express()

// Parse JSON bodies
app.use(express.json())

// Mount Timeback routes
app.use('/api/timeback', toExpressMiddleware(timeback))

// Your other routes...
app.get('/', (req, res) => {
	res.send('Hello World')
})

app.listen(3000, () => {
	console.log('Server running on port 3000')
})
```

## Alternative: Mount on Router

For more control, you can mount routes on an Express Router:

```typescript server.ts theme={null}
import { mountExpressRoutes } from '@timeback/sdk/express'
import express from 'express'

import { timeback } from './lib/timeback'

const app = express()
const router = express.Router()

// Mount Timeback routes on router
mountExpressRoutes(router, timeback)

// Use the router
app.use('/api/timeback', router)
```

## Routes

The middleware handles these routes under `/api/timeback`:

| Route                 | Method   | Purpose                    |
| --------------------- | -------- | -------------------------- |
| `/identity/signin`    | GET      | Initiates SSO flow         |
| `/identity/callback`  | GET      | Handles SSO callback       |
| `/identity/signout`   | GET/POST | Signs out user             |
| `/user/verify`        | GET      | Verifies user session      |
| `/user/me`            | GET      | Fetches user profile       |
| `/activity/heartbeat` | POST     | Time-spent heartbeat       |
| `/activity/submit`    | POST     | Activity completion submit |

## Usage

Beyond the HTTP routes, you can use the Timeback instance directly for server-side operations like verifying users, fetching profiles, or recording activity completions:

```typescript server.ts theme={null}
import { timeback } from './lib/timeback'

// Verify a user exists in Timeback
const result = await timeback.user.verify('student@example.com')

if (result.verified) {
	console.log(result.timebackId)
}

// Fetch full enriched profile
const profile = await timeback.user.getProfile('student@example.com')

console.log(profile.xp?.today, profile.courses)
```

<Note>
  See [user profile](/beta/build-on-timeback/sdk/user-profile) for full documentation on
  `verify()` and `getProfile()`.
</Note>

## With Frontend Framework

When using Express with a frontend framework like React:

```typescript server.ts theme={null}
import path from 'path'

import { toExpressMiddleware } from '@timeback/sdk/express'
import express from 'express'

import { timeback } from './lib/timeback'

const app = express()

app.use(express.json())
app.use('/api/timeback', toExpressMiddleware(timeback))

// Serve static files from React build
app.use(express.static(path.join(__dirname, 'dist')))

// Handle client-side routing
app.get('*', (req, res) => {
	res.sendFile(path.join(__dirname, 'dist', 'index.html'))
})

app.listen(3000)
```

## Next Steps

<CardGroup cols={2}>
  <Card title="React Client" href="/beta/build-on-timeback/sdk/client/react">
    Client-side React integration
  </Card>

  <Card title="Identity" href="/beta/build-on-timeback/sdk/identity">
    Authentication options
  </Card>

  <Card title="Custom Activities" href="/beta/build-on-timeback/sdk/activity-tracking/intro">
    Track learning sessions
  </Card>
</CardGroup>
