Skip to main content

Getting Started

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

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

Installation

Python:

pip install ducto

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

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

TypeScript:

npm install @apoorwv/ducto

Quick Start — Calculation Only

from ducto 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 "@apoorwv/ducto";

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

ducto migrate "postgresql://user:pass@host:5432/db"

Creates user_credits, credit_transactions, credit_reservations tables — idempotent, safe to run on every deploy.

2. Seed pricing

ducto 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 ducto import CreditManager, UsageMetrics
from ducto.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 {abs(result.amount)} credits. Balance: {result.balance_after}")
import { CreditManager, UsageMetrics, HttpxSupabaseStore } from "@apoorwv/ducto";

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?