A budget the database refuses to break.
Stub sits between your AI agents and the money they spend. Every spend is recorded as a double-entry transaction, and one that would exceed your budget never commits. Here's the whole idea, top to bottom.
One budget, the whole fleet
You set a single company-wide budget and split it into teams and agents. A spend is bound by the tightest cap along that chain (agent, then team, then org), and all of it is checked inside one database transaction before any money moves.
Every spend is double-entry
A spend debits the agent's budget and credits the vendor in the same atomic transaction. The entries table is append-only and hash-chained, so it doubles as a tamper-evident audit log. Balances are derived from it, never edited by hand.
A breach fails the transaction
When two agents race the same dollars across regions, Amazon Aurora DSQL's optimistic concurrency control lets one commit and returns a serialization error (SQLSTATE 40001) to the other. Stub retries against the fresh balance or records a denial. The balance never goes negative. There's no window where an overspend is briefly real.
Policies and safety run on every spend
Per-transaction caps, rolling-window limits, vendor allow/blocklists, and approval thresholds are evaluated in the same transaction. A velocity breaker auto-freezes a runaway agent, and a kill switch freezes one agent or the whole fleet instantly.
Ask the ledger in plain English
“How much did Marketing's agents spend on data APIs?” The model fills a constrained, parameterized query over the ledger and answers. It never writes raw SQL against your data.
Try it in 60 seconds
The dashboard runs on a live Aurora DSQL cluster with sample data. Nothing you do spends real money.
- 1Run a spendIn “Simulate a spend,” authorize a small amount; it commits and appears in the ledger instantly.
- 2Trip a limitAuthorize more than an agent's remaining budget. It's denied and recorded, and the balance holds.
- 3Ask the ledgerType a question in “Ask your ledger” and get an answer drawn straight from the entries.
Drop it into an agent
Put the budget gate in front of any paid call. The money moves only after the spend commits.
import { StubClient } from "trystub";
const stub = new StubClient({ apiKey: process.env.STUB_API_KEY });
if (await stub.guard({ vendorAccountId, amountUsd: 0.02, intent: "fetch market data" })) {
await doThePaidThing();
}