Get Started

Billing

Credit-based metering across compute, orchestration, model calls, and storage. Theazo tracks every resource consumed — per user, per session, per run — so you can enforce budgets, fire threshold alerts, and re-bill your users with a single API call.

All monetary values use { amount: number, currency: string } where amount is integer cents. 500 = $5.00. Never strings.

Credit system

Theazo uses a credit system where 1 credit = $0.01. Credits are dollar-denominated, not unit-denominated — there is no conversion math specific to model calls or compute events. Credits are purchased in advance and drawn down as your agents run. All API responses report costs as credits and as the { amount, currency } pair.

credits.ts
// Credits are dollar-denominated: 1 credit = 1 cent
const usage = await theazo.billing.getCreditBalance()

console.log(usage.credits)   // 4823 — credits remaining
console.log(usage.currency)  // 'usd'

Rate card

Four billing categories. Costs accrue automatically regardless of which mode you operate in. BYOI compute is not billed by Theazo — see the BYOI section.

Category
Rate
Notes
Compute
$0.005 / min
0.5 credits/min per running sandbox
Orchestration
$0.002 / min
Control plane overhead; workflow steps, fleet dispatch
Model (pass-through)
cost + 10%
Managed model calls only. BYOI model = no markup.
Storage
$0.10 / GB / mo
Snapshots, knowledge base embeddings, file storage

Plan tiers

Credits are included in each plan. Overages draw from your credit balance. You can purchase additional credit packs at any time from the dashboard or via the billing API.

Plan
Monthly fee
Included credits
Notes
Free
$0
1,000
No credit card required. No overages.
Pro
$99
10,000
Overage billed at standard rate card. BYOI supported.
Enterprise
Custom
Custom
Volume discounts, SLA, dedicated support, SSO.

Budget hierarchy

Budgets enforce spending limits at four levels. Each level constrains everything below it. When a budget is exhausted the enforcement happens atomically via Redis INCRBY — there is no race window.

Level
Scope
SDK call
Platform
All usage across your entire platform
theazo.billing.setBudget()
User
One end-user across all their sessions
theazo.billing.setUserBudget()
Session
One session and all agents within it
session limits on forUser()
Run
One agent.run() or workflow.run() call
maxCost on run options

Setting budgets

budgets.ts
import { Theazo } from 'theazo'

const theazo = new Theazo({ apiKey: 'th_live_...' })

// Platform-wide budget — the monthly spend ceiling for the whole platform
await theazo.billing.setBudget({
  monthly: { amount: 50000, currency: 'usd' },  // $500/mo across the platform
})

// Per-user budget — the monthly ceiling applied to each end-user
await theazo.billing.setUserBudget({
  monthly: { amount: 2000, currency: 'usd' },    // $20/mo per user
})

// Session-level limit — caps a single session
const session = await theazo.sessions.forUser('user_alice', {
  limits: {
    maxCost: { amount: 500, currency: 'usd', period: 'day' },  // $5/day
    maxAgents: 3,
    maxComputeMinutes: 60,
  },
})

// Run-level limit — caps one agent.run() call
const agent = await session.agents.create({ compute: 'python' })
const result = await agent.run('Summarize this codebase', {
  maxCost: { amount: 50, currency: 'usd' },  // $0.50 max per run
})

Threshold alerts

Theazo fires budget webhooks at 50%, 80%, and 100% of any budget level. Use these to warn users before they hit their limit, or to trigger auto top-ups. The budget.exhausted event fires when the limit is reached and agents are paused.

budget.threshold

Fires at 50% and 80% of any budget level. Includes level, userId (if user budget), current spend, and limit.

budget.exhausted

Fires when a budget is fully consumed. All running agents in scope are paused. Resume by updating the limit.

budget-webhook.json
// Example budget.threshold payload
{
  "event": "budget.threshold",
  "level": "user",                           // 'platform' | 'user' | 'session' | 'run'
  "userId": "user_alice",
  "threshold": 80,                           // percent consumed
  "consumed": { "amount": 1600, "currency": "usd" },
  "limit":    { "amount": 2000, "currency": "usd" },
  "period": "month"
}

// Example budget.exhausted payload
{
  "event": "budget.exhausted",
  "level": "user",
  "userId": "user_alice",
  "consumed": { "amount": 2001, "currency": "usd" },
  "limit":    { "amount": 2000, "currency": "usd" },
  "agentsPaused": ["agt_x1", "agt_x2"]
}

After a budget is exhausted, update the limit and call session.resume() to unpause agents.

resume-budget.ts
// Raise the budget and resume the paused session
await theazo.billing.setUserBudget({
  monthly: { amount: 5000, currency: 'usd' },
})

const session = await theazo.sessions.forUser('user_alice')
await session.resume()

Environment separation

Agent runs are tagged with an environment. Development runs are free and do not count toward credits. Staging and production runs are billed separately so you can track them independently.

Environment
Billed
Counter
dev
No — always free
Logged but not counted against credits
staging
Yes — separate counter
Visible in dashboard, separate from production totals
production
Yes — full billing
All budgets enforced, all webhooks fire
environments.ts
// Set the environment when the session is created — agents inherit it
const session = await theazo.sessions.create({
  userId: 'user_alice',
  environment: 'development',   // 'development' | 'staging' | 'production'
})

// Every agent in this session runs (and bills) under that environment
await session.agents.create({ compute: 'python' })

BYOI cost split

When you bring your own infrastructure (BYOI), the usage response includes a cost split: theazoBilled is what Theazo charges you (orchestration only), and providerDirect is what your BYOI provider charges you directly. The two never overlap.

byoi-usage.ts
const usage = await theazo.usage.forUser('user_alice', { period: 'month' })

// With BYOI compute, the provider (E2B/Fly/…) bills you for compute directly;
// usage.compute is that portion, usage.total is everything (compute + models + storage).
console.log(usage.compute)   // { minutes: 202, cost: { amount: 870, currency: 'usd' } }
console.log(usage.models)    // { calls: 87, tokens: { input, output }, cost: {...} }
console.log(usage.total)     // { amount: 1010, currency: 'usd' } — full picture

Cost webhooks

When an agent run completes, Theazo fires agent.run.completed with a full cost breakdown. Use this to update your own billing records or trigger downstream re-billing flows — no polling required.

agent.run.completed

Fires when a run finishes (completed, failed, or cancelled). Includes full cost breakdown: compute, model, storage, orchestration, and total.

workflow.run.completed

Same as above but for workflow runs. Also includes per-step cost breakdown.

cost-webhook.json
// agent.run.completed payload
{
  "event": "agent.run.completed",
  "agentId": "agt_abc123",
  "runId":   "run_xyz789",
  "userId":  "user_alice",
  "status":  "completed",
  "cost": {
    "compute":       { "amount": 15,  "currency": "usd" },   // sandbox runtime
    "model":         { "amount": 42,  "currency": "usd" },   // model tokens
    "storage":       { "amount": 2,   "currency": "usd" },   // snapshot size
    "orchestration": { "amount": 8,   "currency": "usd" },   // control plane
    "total":         { "amount": 67,  "currency": "usd" },
    "theazoBilled":  { "amount": 67,  "currency": "usd" },
    "providerDirect":{ "amount": 0,   "currency": "usd" }    // 0 = managed compute
  },
  "duration": 43,      // seconds
  "environment": "production"
}

Credit balance

Credit enforcement is Redis-local for low latency. Theazo reconciles with Dodo Payments asynchronously. The local counter can drift by at most one usage event before reconciliation fires. Enterprise customers can configure synchronous reconciliation.

credit-balance.ts
// Get current balance
const balance = await theazo.billing.getCreditBalance()

console.log(balance.credits)   // 4823
console.log(balance.currency)  // 'usd'

Per-user usage

Query usage for any individual end-user. Use this to build usage meters in your product UI, enforce per-user limits, or generate itemized invoices for your users.

per-user.ts
// Query usage for one user (period: 'today' | 'week' | 'month')
const usage = await theazo.usage.forUser('user_alice', { period: 'month' })

console.log(usage.total)      // { amount: 1010, currency: 'usd' }
console.log(usage.compute)    // { minutes: 202, cost: {...} }
console.log(usage.models)     // { calls: 87, tokens: {...}, cost: {...} }
console.log(usage.breakdown)  // [{ date, total }, ...] — per-day

// Session-level usage
const session = await theazo.sessions.forUser('user_alice')
const sessionUsage = await session.usage()

console.log(sessionUsage.cost)                // { amount: 234, currency: 'usd' }
console.log(sessionUsage.computeMinutes)      // 47
console.log(sessionUsage.activeAgents)        // 2
console.log(sessionUsage.totalAgentsCreated)  // 12

Usage export

Export usage data for re-billing your users. Three formats: Stripe-compatible line items (ready to attach to invoices), CSV for spreadsheets, and raw JSON. All exports can be grouped by user, session, provider, or day.

export.ts
// Stripe-compatible — attach directly to Stripe invoice line items
const stripe = await theazo.usage.export({ format: 'stripe', period: 'month' })

// CSV — spreadsheet-friendly rows
const csv = await theazo.usage.export({ format: 'csv', period: 'month' })

// JSON — full usage records
const json = await theazo.usage.export({ format: 'json', period: 'month' })
Stripe-format exports include unit_amount (integer cents), quantity (1), and description fields. Pass them directly to the Stripe invoiceitem.create API.

API reference

GET/v1/billing/balance

Get current credit balance, plan details, and overage usage.

Response

CreditBalance

Example

bash
curl https://api.theazo.com/v1/billing/balance \
  -H "Authorization: Bearer th_live_..."
POST/v1/billing/budget

Set or update the platform-level monthly budget. Fires budget.threshold webhooks at 50% and 80%.

Parameters

monthlyobjectrequiredMonthly spend ceiling (integer cents + currency).

Response

{ ok: true }

Example

bash
curl -X POST https://api.theazo.com/v1/billing/budget \
  -H "Authorization: Bearer th_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "monthly": { "amount": 50000, "currency": "usd" } }'
POST/v1/billing/user-budget

Set or update the per-user monthly spending budget (applies to every end-user under the platform).

Parameters

monthlyobjectrequiredMonthly spend ceiling (integer cents + currency).

Response

{ ok: true }

Example

bash
curl -X POST https://api.theazo.com/v1/billing/user-budget \
  -H "Authorization: Bearer th_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "monthly": { "amount": 2000, "currency": "usd" } }'
GET/v1/usage

Platform-wide usage summary. Filterable by period and environment.

Parameters

startstringISO 8601 start date. Default: start of current month.
endstringISO 8601 end date. Default: now.
environmentstring'dev' | 'staging' | 'production'. Default: all.

Response

UsageSnapshot

Example

bash
curl "https://api.theazo.com/v1/usage?start=2026-06-01&environment=production" \
  -H "Authorization: Bearer th_live_..."
GET/v1/usage/by-user/:userId

Usage for a single end-user across all their sessions. Includes theazoBilled/providerDirect split.

Parameters

startstringISO 8601 start date.
endstringISO 8601 end date.

Response

UserUsageSnapshot

Example

bash
curl "https://api.theazo.com/v1/usage/by-user/user_alice?start=2026-06-01" \
  -H "Authorization: Bearer th_live_..."
GET/v1/usage/daily

Daily aggregated usage for charts. Returns an array of { date, cost, computeMinutes, modelCalls } objects.

Parameters

startstringrequiredISO 8601 start date.
endstringrequiredISO 8601 end date.
environmentstringFilter by environment.

Response

DailyUsage[]

Example

bash
curl "https://api.theazo.com/v1/usage/daily?start=2026-06-01&end=2026-06-30" \
  -H "Authorization: Bearer th_live_..."
GET/v1/usage/export

Export usage data as Stripe line items, CSV, or JSON. All parameters are query-string filters.

Parameters

formatstring'stripe' | 'csv' | 'json'. Default: json.
periodstringAggregation period, e.g. 'month'. Default: month.
userIdstringScope the export to a single end-user.

Response

ExportResult

Example

bash
curl "https://api.theazo.com/v1/usage/export?format=stripe&period=month" \
  -H "Authorization: Bearer th_live_..."

SDK method reference

theazo.billing.getCreditBalance()Promise<{ credits, currency }>Current credit balance.
theazo.billing.setBudget(config)Promise<void>Set the platform monthly budget ({ monthly }). Fires threshold webhooks at 50% and 80%.
theazo.billing.setUserBudget(config)Promise<void>Set the per-user monthly budget ({ monthly }), applied to every end-user.
theazo.usage.forUser(userId, opts?)Promise<UserUsage>Usage for one user: compute, models, storage, total, and a daily breakdown (opts.period: today|week|month).
theazo.usage.export(opts)Promise<unknown>Export usage as Stripe line items, CSV, or JSON. opts: { period: 'month', format }.
theazo.usage.daily(opts)Promise<DailyUsage[]>Daily aggregated usage. Useful for charts and dashboards.
theazo.usage.byProvider(opts)Promise<ProviderUsage>Usage as a { provider: Cost } map (E2B, Fly, Docker, etc.).
session.usage()Promise<UsageSnapshot>Current session 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. Takes effect immediately.
session.resume()Promise<void>Resume agents paused by a budget exhaustion event after limits have been raised.
Was this page helpful?