Assistant Billing

SDK

npm install @assistant-billing/sdk

Three clients: GatewayClient for AI requests, BillingClient for workspace billing, AdminBillingClient for operator-level customer management.

GatewayClient

Proxy AI requests through the gateway. One request shape reaches every provider you have configured.

import { GatewayClient } from "@assistant-billing/sdk"
 
const gateway = new GatewayClient({
  apiKey: "sk_ab_live_xyz789",
  baseURL: "https://gateway.assistant-billing.dev",
})

Constructor Options

OptionTypeDefaultDescription
apiKeystringASSISTANT_BILLING_GATEWAY_API_KEY envGateway API key
baseURLstring?https://gateway.assistant-billing.devGateway URL
appTitlestring?—App name (X-Title header)
appUrlstring?—App URL (HTTP-Referer header)
defaultHeadersRecord<string, string>?—Extra headers
timeoutnumber?60000Timeout in ms

Chat Completions

// Non-streaming
const response = await gateway.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello!" }],
})
console.log(response.choices[0].message.content)
 
// Streaming
const stream = await gateway.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello!" }],
  stream: true,
})
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "")
}

Embeddings

const result = await gateway.embeddings.create({
  model: "text-embedding-3-small",
  input: "The quick brown fox",
  dimensions: 256,
})

List Models

const models = await gateway.models.list()
// → [{ id: "gpt-4o", object: "model", created: 1715367049, owned_by: "openai" }, ...]

Feedback and Scores

// Single numeric feedback
await gateway.feedback("rl_a1b2c3d4e5f6", 5, { session: "abc" })
 
// Multiple named scores
await gateway.scores("rl_a1b2c3d4e5f6", {
  quality: 5,
  relevance: 3,
  thumbs_up: true,
})

Context Methods

Return a new GatewayClient instance with the context applied. Chainable.

const customGateway = gateway
  .withMetadata({ session: "abc" })   // attach metadata to request log
  .withUser("user_456")               // set X-AB-User-Id header
  .withProvider("anthropic")          // prefer a specific provider
  .withNoCache()                      // bypass cache

Provider Preferences

Pass provider in the request body for per-request routing control.

await gateway.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello!" }],
  provider: {
    order: ["openai", "azure"],
    allow_fallbacks: true,
  },
})
FieldTypeDescription
orderstring[]Ordered list of provider slugs to try
onlystring[]Only allow these providers
ignorestring[]Skip these providers
allow_fallbacksbooleanAllow fallback to other providers (default: true)

BillingClient

Manage workspace billing from your backend. Supports both platform key auth (server-side) and session token auth (client-side).

import { BillingClient } from "@assistant-billing/sdk"
 
// Server-side: platform key auth
const billing = new BillingClient({
  platformKey: "sk_pj_live_abc123",
  workspaceId: "ws_team_123",
  userId: "user_456",
})
 
// Client-side: session token auth
const billing = new BillingClient({
  getToken: () => fetchSessionToken(),
})

Constructor Options

OptionTypeDefaultDescription
platformKeystring?ASSISTANT_BILLING_PLATFORM_API_KEY envPlatform key (sk_pj_*)
workspaceIdstring?—Customer workspace ID
userIdstring?—User performing the action
getToken() => Promise<string>?—Session token callback (client-side)
baseURLstring?https://api.assistant-billing.dev/v1/platformAPI URL
timeoutnumber?30000Timeout in ms

Sessions

const { token, expires_at } = await billing.sessions.create({
  expiresIn: 3600, // optional, seconds (default: 1 hour)
})
// → { token: "sess_eyJhbG...", expires_at: "2026-03-15T00:00:00Z" }

Wallet

const balance = await billing.wallet.getBalance()
// → { currency: "USD", amount: "100.00" }
 
const transactions = await billing.wallet.getTransactions({ limit: 20, offset: 0 })
// → { data: [{ type: "credit", amount_usd: "50.00", ... }] }

Checkout

const checkout = await billing.checkout.create({
  amount: 50,
  successUrl: "https://yourapp.com/billing?status=success",
  cancelUrl: "https://yourapp.com/billing?status=cancelled",
})
// → { url: "https://checkout.stripe.com/...", base_amount: "50.00",
//      platform_fee: "2.50", markup: "5.00", total_amount: "57.50" }

API Keys

const keys = await billing.apiKeys.list()
// → [{ id: "key_0...", name: "default", suffix: "x1y2z3", lastAccessedAt: "..." }]
 
const { id, key } = await billing.apiKeys.create({ name: "production" })
// → { id: "key_0...", key: "sk_ab_gw01_0a1b2c3d..." }  ← shown once only
 
await billing.apiKeys.revoke("key_0...")
// → { success: true }

Temporary Keys

Short-lived keys with permissions, rate limits, and budgets.

const { key, id, expires_at } = await billing.tempKeys.create({
  name: "contributor-key",
  ttl: 3600,                          // 1 hour (or use expires_at)
  permissions: { models: ["gpt-4o"] },
  rate_limit_rpm: 30,
  rate_limit_tpm: 100000,
  monthly_budget_usd: 5.0,
})
// → { key: "temp_ab_gw01_...", id: "ak_0...", expires_at: "2026-03-14T01:00:00Z" }
 
const keys = await billing.tempKeys.list()
await billing.tempKeys.revoke("ak_0...")

Provider Keys (BYOK)

const providers = await billing.providerKeys.list()
// → [{ providerId: "openai", name: "OpenAI", hasKey: true, env: ["OPENAI_API_KEY"] }]
 
await billing.providerKeys.set("openai", { OPENAI_API_KEY: "sk-proj-..." })
// → { success: true }
 
const result = await billing.providerKeys.test("openai")
// → { valid: true } or { valid: false, error: "Invalid API key" }
 
await billing.providerKeys.remove("openai")
// → { success: true }

Analytics

const overview = await billing.analytics.getOverview({
  from: "2026-03-01",
  to: "2026-03-14",
})
// → { total_requests: 1500, total_cost: "42.50", avg_latency: 850, ... }
 
const timeseries = await billing.analytics.getTimeseries({
  from: "2026-03-01",
  to: "2026-03-14",
})
// → [{ date: "2026-03-01", request_count: 120, total_cost: "3.50", ... }]

Cache

const stats = await billing.cache.getStats({
  from: "2026-03-01",
  to: "2026-03-14",
})
// → { total_requests: 1500, cache_hits: 300, cache_misses: 1200, hit_rate: 0.2 }

Project Info

const info = await billing.project.getInfo()
// → { name: "My Project", slug: "my-app", gateway_url: "https://gateway.assistant-billing.dev", gateway_custom_domain: null }

Models

const models = await billing.models.list()
// → [{ id: "gpt-4o", object: "model", created: 1715367049, owned_by: "openai" }]

AdminBillingClient

Operator-level customer management. Platform key only, no workspace scope.

import { AdminBillingClient } from "@assistant-billing/sdk"
 
const admin = new AdminBillingClient({
  platformKey: "sk_pj_live_abc123",
})

Constructor Options

OptionTypeDefaultDescription
platformKeystring?ASSISTANT_BILLING_PLATFORM_API_KEY envPlatform key
baseURLstring?https://api.assistant-billing.dev/v1/platformAPI URL
timeoutnumber?30000Timeout in ms

Customers

const { data } = await admin.customers.list({ limit: 50, offset: 0 })
// → { data: [{ workspace_id: "ws_team_123", balance_usd: "100.00", ... }] }
 
const balance = await admin.customers.getBalance("ws_team_123")
// → { workspace_id: "ws_team_123", balance: "100.00", sufficient: true }
 
const transactions = await admin.customers.getTransactions("ws_team_123", { limit: 20 })
// → { data: [{ type: "debit", amount_usd: "0.003", ... }] }
 
const usage = await admin.customers.getUsage("ws_team_123", {
  from: "2026-03-01",
  to: "2026-03-14",
})
// → { total_requests: 500, total_cost: "12.50", total_input_tokens: "150000", total_output_tokens: "80000" }

Error Handling

The SDK throws typed errors for gateway requests.

import {
  GatewayError,
  GatewayAuthError,
  GatewayRateLimitError,
} from "@assistant-billing/sdk"
 
try {
  await gateway.chat.completions.create({
    model: "gpt-4o",
    messages: [{ role: "user", content: "Hello!" }],
  })
} catch (err) {
  if (err instanceof GatewayRateLimitError) {
    // 429 — retry after the specified delay
    console.log(`Rate limited, retry in ${err.retryAfterMs}ms`)
  } else if (err instanceof GatewayAuthError) {
    // 401 — invalid or expired API key
    console.log("Invalid API key")
  } else if (err instanceof GatewayError) {
    // All other gateway errors
    console.log(`Error ${err.status}: ${err.message}`)
    console.log(`Request ID: ${err.requestId}`)
  }
}
Error ClassStatusProperties
GatewayErroranymessage, status, code?, requestId?
GatewayAuthError401message, requestId?
GatewayRateLimitError429message, requestId?, retryAfterMs?