Skip to main content

Getting Started

Add usage-based credits to your AI SaaS in minutes — not weeks.

bursar is a drop-in credit calculation engine. Define pricing as math expressions (per-model, per-tool, search/RAG, cache, fixed jobs), connect a database, and start deducting credits. For streaming and agentic workloads, the lease pattern (reserve → settle / release) lets you hold credits during execution and bill the actual cost at the end — with atomic admission control and no double-charges.

Installation

Python:

pip install bursar

# With Supabase store
pip install "bursar[supabase]"

# With PostgreSQL store
pip install "bursar[postgres]"

TypeScript:

npm install @zonastery/bursar

Quick Start — Calculation Only

from bursar import PricingEngine, UsageMetrics

engine = PricingEngine.from_dict({
"version": 1,
"models": {"_default": "input_tokens * 0.001 + output_tokens * 0.003"},
})

result = engine.calculate(
UsageMetrics(model="gpt-4", input_tokens=500, output_tokens=200),
)
print(f"Total credits: {result.total}")
import { PricingEngine } from "@zonastery/bursar";

const engine = PricingEngine.fromDict({
version: 1,
models: { "_default": "input_tokens * (0.001 / 1000) + output_tokens * (0.003 / 1000)" },
});

const cost = engine.calculate({
model: "gpt-4",
inputTokens: 500,
outputTokens: 200,
});
console.log(`Total: ${cost.total}`);

Quick Start — Full Credit Lifecycle

1. Migrate the database

DATABASE_URL="postgresql://user:pass@host:5432/db" bursar migrate

Creates user_credits, credit_transactions, credit_reservations tables (and the pricing, plan, team, cap and analytics objects) — idempotent, safe to run on every deploy. The connection string comes from DATABASE_URL, not the command line.

2. Seed pricing

bursar pricing set - <<'JSON'
{
"version": 1,
"models": {
"gpt-4": "input_tokens * 0.01 + output_tokens * 0.03",
"_default": "input_tokens * 0.001 + output_tokens * 0.003"
}
}
JSON

3. Deduct credits

from bursar import CreditManager, UsageMetrics
from bursar.interface.postgres import PostgresStore

store = PostgresStore("postgresql://user:pass@host:5432/db")
manager = CreditManager(store=store)
manager.load_pricing_from_store()
manager.add_credits("user_abc", 1000)

result = manager.deduct(
user_id="user_abc",
metrics=UsageMetrics(model="gpt-4", input_tokens=500, output_tokens=200),
idempotency_key="chat_session_42",
)
print(f"Deducted {result.amount} credits. Balance: {result.balance_after}")
import { CreditManager, UsageMetrics, HttpxSupabaseStore } from "@zonastery/bursar";

const store = new HttpxSupabaseStore(url, serviceRoleKey);
const manager = new CreditManager(store);
await manager.loadPricingFromStore();
await manager.addCredits("user_abc", 5000);

const result = await manager.deduct(
"user_abc",
{ model: "gpt-4", inputTokens: 500, outputTokens: 200 },
"idempotency-key-123",
);

Language Guides

What's Next?