Core concepts
The ledger
Append-only, and why that is not negotiable.
Every movement of money writes a ledger_entry. Entries are never updated and never deleted, a database trigger refuses both, so the guarantee survives a migration, a psql session, and a future role misconfiguration.
Read one end user's trail
seams users ledger ada
# TYPE AMOUNT USD BALANCE AFTER AT
# grant 5.00 5.00 2026-09-01T10:02:11Z
# usage_debit -0.03 4.97 2026-09-01T10:04:02Z
# usage_debit -0.01 4.96 2026-09-01T10:04:18Zimport { Seams } from "@ourseams/sdk"
const seams = new Seams({ apiKey: process.env.SEAMS_API_KEY! })
const { data } = await seams.users.ledger("ada")
for (const entry of data) {
console.log(entry.kind, entry.amountUnits, entry.balanceAfterUnits)
}import os
from seams import Seams
seams = Seams(api_key=os.environ["SEAMS_API_KEY"])
ledger = seams.users.ledger("ada")
for entry in ledger.data:
print(entry.kind, entry.amount_units, entry.balance_after_units)Entry types
| Type | Means |
|---|---|
topup | The end user paid and their balance was credited |
grant | Credit issued without a payment, a trial, a support gesture |
usage_debit | Inference consumed, at raw provider cost |
refund | Money returned |
reversal | A top-up undone, a chargeback, or a duplicate |
adjustment | A correction, including credit from an orphaned hold |
Idempotency is a unique index, never application logic. A check-then-insert has a race window; a constraint does not.