Get Started

Sessions

A session is an isolated container for a single end-user. Every agent runs inside a session, and every cost, log, and snapshot is scoped to it. Sessions let you enforce per-user spend limits, provide multi-tenant isolation, and produce billing data you can pass through to your users.

forUser — the common pattern

forUser is idempotent: if a session already exists for the given userId it is returned; otherwise a new one is created. Call it on every request — it is safe to call many times.

session.ts
import { Theazo } from 'theazo'

const theazo = new Theazo({ apiKey: process.env.THEAZO_API_KEY! })

// Idempotent — safe to call on every request
const session = await theazo.sessions.forUser('user_123', {
  limits: {
    maxCost: { amount: 500, currency: 'usd', period: 'day' },  // $5.00/day
    maxAgents: 3,
    maxComputeMinutes: 60,
  },
  metadata: {
    plan: 'pro',
    email: 'alice@example.com',
  },
})
maxCost.amount is in integer cents — 500 means $5.00. All monetary values in Theazo use { amount: number, currency: string }, never plain strings.

Explicit creation

Use sessions.create when you need to create a session without a user ID, or when you need precise control over when a new session starts.

session.ts
const session = await theazo.sessions.create({
  userId: 'user_123',     // optional — omit for anonymous sessions
  limits: {
    maxCost: { amount: 1000, currency: 'usd', period: 'month' },
    maxAgents: 10,
  },
  metadata: { source: 'api' },
})

console.log(session.id)        // 'ses_...'
console.log(session.status)    // 'active'
console.log(session.createdAt) // Date

Environment parameter

Every session can specify an environment to separate dev, staging, and production workloads. The default is 'production'.

session.ts
const session = await theazo.sessions.create({
  userId: 'user_123',
  environment: 'development',   // 'production' | 'staging' | 'development' (default: 'production')
  metadata: { source: 'local' },
})

Dev sessions

Dev sessions automatically apply restrictive limits — 1 agent and a 5-minute max runtime — to prevent runaway usage during local development. They are excluded from billing entirely and use separate Redis counters so they never pollute production metrics.

Staging sessions

Staging sessions behave like production but maintain separate cost counters. Full billing applies — you can use staging to validate spend projections before going live.

Prod sessions

The default. Normal behavior with no auto-applied limits beyond what you configure explicitly.

Dev sessions are perfect for integration tests and local development. Their auto-limits (1 agent, 5 min) cannot be overridden — this is intentional to keep development costs at zero.

Fetching sessions

Get a session

session.ts
const session = await theazo.sessions.get('ses_...')

console.log(session.userId)  // 'user_123'
console.log(session.status)  // 'active' | 'paused' | 'terminated'

List sessions

session.ts
const { sessions, total } = await theazo.sessions.list({
  status: 'active',
  userId: 'user_123',    // filter by user
  limit: 20,
  offset: 0,
})

Usage and limits

session.usage()

Returns current resource consumption for this session. Useful for building usage meters in your product UI.

session.ts
const usage = await session.usage()

console.log(usage.cost)            // { amount: 234, currency: 'usd' }
console.log(usage.computeMinutes)  // 47
console.log(usage.activeAgents)    // 2
console.log(usage.modelCalls)      // 38

session.limits()

Returns configured limits alongside current consumption so you can render progress bars or trigger warnings before a user hits their cap.

session.ts
const limits = await session.limits()

// Each entry: { limit, used, unit }
console.log(limits.maxCost)
// {
//   limit: { amount: 500, currency: 'usd', period: 'day' },
//   used:  { amount: 234, currency: 'usd' },
// }

console.log(limits.maxComputeMinutes)
// { limit: 60, used: 47, unit: 'minutes' }

console.log(limits.maxAgents)
// { limit: 3, used: 2, unit: 'agents' }

session.updateLimits(limits)

Update limits on a live session — for example when a user upgrades their plan. Partial updates are supported; omitted fields are unchanged.

session.ts
await session.updateLimits({
  maxCost: { amount: 2000, currency: 'usd', period: 'day' }, // upgrade to $20/day
  maxAgents: 10,
})

Session lifecycle

Sessions progress through three states: active, paused, and terminated. Pausing preserves all running agents as snapshots; resuming restores them. Termination is permanent.

session-lifecycle.ts
// Pause — suspends all running agents, preserves state as snapshots
await session.pause()

// Resume — restores all paused agents from their snapshots
await session.resume()

// Terminate — permanent, destroys all agents and releases compute
await session.terminate()
terminate() is irreversible. All agent state, files, and browser sessions are destroyed. Snapshots created before termination remain accessible via the API.

Limit enforcement

When a session reaches its maxCost or maxComputeMinutes limit, Theazo automatically pauses all running agents and fires a session.limit_reached webhook. Agents are not terminated — they can be resumed once limits are updated.

webhook-payload.json
// Listen for limit events on your webhook endpoint
// POST https://yourapp.com/webhooks/theazo
{
  "event": "session.limit_reached",
  "data": {
    "sessionId": "ses_...",
    "userId": "user_123",
    "limitType": "maxCost",
    "used": { "amount": 500, "currency": "usd" },
    "limit": { "amount": 500, "currency": "usd", "period": "day" }
  }
}

Cross-session per-user limits

Session-level limits cap spend within a single session. Use userLimits to enforce aggregate limits across all sessions for a given userId. These are checked alongside session-level limits — the stricter of the two always wins.

session.ts
const session = await theazo.sessions.forUser('user_123', {
  limits: {
    maxCost: { amount: 500, currency: 'usd', period: 'day' },  // per-session: $5/day
    maxAgents: 3,
  },
  userLimits: {
    maxCostPerDay: { amount: 5000, currency: 'usd' },  // across ALL sessions: $50/day
  },
})

When the user-level limit is reached, Theazo pauses all active sessions for that user and fires a user.limit_reached webhook. Agents are preserved as snapshots and can be resumed once the limit resets or is updated.

webhook-payload.json
// Webhook payload when a user-level limit is hit
// POST https://yourapp.com/webhooks/theazo
{
  "event": "user.limit_reached",
  "data": {
    "userId": "user_123",
    "limitType": "maxCostPerDay",
    "used": { "amount": 5000, "currency": "usd" },
    "limit": { "amount": 5000, "currency": "usd" },
    "activeSessions": ["ses_a1b2c3", "ses_d4e5f6"]
  }
}
User-level limits are ideal for platforms that allow users to spin up multiple sessions. Without them, a user could bypass a $5/day session cap by creating 10 sessions — userLimits closes that gap.

Method reference

theazo.sessions.forUser(userId, opts?)Promise<Session>Get or create a session for a user. Idempotent — safe to call on every request.
theazo.sessions.create(opts)Promise<Session>Explicitly create a new session. Always creates, even if userId already has one.
theazo.sessions.get(id)Promise<Session>Fetch a session by ID.
theazo.sessions.list(filters?)Promise<{ sessions, total }>List sessions with optional filters: status, userId, limit, offset.
session.usage()Promise<UsageSnapshot>Current consumption: cost, computeMinutes, activeAgents, modelCalls.
session.limits()Promise<LimitsSnapshot>Configured limits alongside current usage for each dimension.
session.updateLimits(limits)Promise<void>Update limits on a live session. Partial updates supported.
session.pause()Promise<void>Suspend all running agents as snapshots. Session transitions to 'paused'.
session.resume()Promise<void>Restore all paused agents from snapshots. Session transitions to 'active'.
session.terminate()Promise<void>Permanently destroy the session and all agents. Irreversible.
Was this page helpful?
Ask anything...⌘I