The flat-rate billing trap

Most AI agent products start with simple pricing: $X per month, agent gets Y API calls. This works until it doesn't. The moment your customers start running autonomous agents — especially production agents that run 24/7 — flat-rate pricing becomes a liability.

A customer on a $99/month plan can run a loop that costs you $2,000 in OpenAI calls before the month ends. You discover it when your vendor invoice arrives. The customer doesn't owe you anything — they paid their flat fee. You ate the overage.

This is a billing architecture problem, not a pricing problem. The fix is to model billing around per-agent spending limits, not customer subscription tiers. Each agent has a wallet with a hard budget. The wallet enforces the limit. When the budget runs out, the agent stops.

The principle: Your customer pays for access. Your agent wallets enforce consumption limits. The two are separate. This is how you prevent billing surprises — for both sides.

Why standard billing tools break for AI agents

Stripe, Recurly, Chargebee: customer-level billing

They track what customers pay, not what agents spend

Standard billing tools charge a customer $99 on the 1st of the month and send an invoice. They don't know that Agent A spent $340, Agent B spent $12, and Agent C is looping and burning your budget. The consumption data lives in your vendor dashboards, not your billing system. You can't enforce plan limits because you don't have a system that tracks limits per agent.

The gap is atomic spend enforcement. Every dollar an AI agent spends must be deducted from a wallet that has a hard ceiling. When the ceiling is hit, the deduction fails with a 402. This enforces the limit at the infrastructure level — not in a billing report you read the next morning.

The wallet-per-agent billing model

Trove: per-agent wallets with hard budget limits

Every agent has its own wallet. Every wallet has a budget.

When a customer signs up, provision a wallet for each of their agents. Set the budget limit based on their plan tier. The agent spends from the wallet. When the wallet is empty, the agent stops. You bill the customer for their subscription fee (Stripe), and the wallet enforces consumption limits (Trove). Separate systems, separate jobs.

Wallet hierarchy for a customer on the $99/mo Pro plan:

Customer: Acme Corp
  Wallet: parent (subscription credit, $99)
    └── Wallet: agent-research-1  (budget: $35/mo)
    └── Wallet: agent-support-1  (budget: $35/mo)
    └── Wallet: agent-crawler-1  (budget: $35/mo)

Plan: Pro ($99/mo, 3 agents, $35 agent budget)

Agent "research-1" calls OpenAI
  → POST /api/wallets/{id}/purchase  amount_usd: 0.15
  → Deducted from agent-research-1 wallet
  → Transaction logged: vendor, amount, description, timestamp
  → If remaining_budget < 0.15 → HTTP 402, agent stops

Step 1: Provision wallets at customer sign-up

When a customer signs up or upgrades, create a wallet for each agent slot in their plan. The wallet's budget limit is the per-agent allocation from their plan tier.

Node.js
// Provision a wallet for each agent in the customer's plan async function provisionAgentWallets(customerId, plan) { const agentCount = plan.max_agents; // 1 for Starter, 5 for Pro, etc. const perAgentBudget = plan.budget_per_agent_usd; // e.g., $50 for Starter const wallets = []; for (let i = 1; i <= agentCount; i++) { const res = await fetch('https://trove-qjow.polsia.app/api/wallets', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Trove-Key': process.env.TROVE_API_KEY }, body: JSON.stringify({ agent_id: `${customerId}-agent-${i}`, name: `Agent ${i} - ${plan.name}`, budget_limit_usd: perAgentBudget }) }); const { wallet } = await res.json(); wallets.push(wallet); } // Store wallet IDs in your DB for billing reconciliation await db.customers.update(customerId, { wallet_ids: wallets.map(w => w.id) }); return wallets; }

Step 2: Route every agent purchase through the wallet

Your agent's code wraps every API call in a purchase request. This does two things: deducts the cost from the wallet and enforces the budget limit atomically.

Node.js
async function callWithBudget(walletId, model, prompt) { const cost = estimateCost(model, prompt.length); // Deduct from wallet first — enforces budget limit atomically const purchaseRes = await fetch( `https://trove-qjow.polsia.app/api/wallets/${walletId}/purchase`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Trove-Key': process.env.TROVE_API_KEY }, body: JSON.stringify({ amount_usd: cost, vendor: model,// 'anthropic', 'openai', 'serper' description: `${model} inference, ${prompt.length} tokens` }) } ); // 402 = budget exhausted — stop the agent gracefully if (purchaseRes.status === 402) { const err = await purchaseRes.json(); sendAlert(`Agent wallet exhausted. ${err.available} remaining.`); throw new Error('Budget exhausted — agent paused'); } // Purchase succeeded — call the model return await callModel(model, prompt); }

Step 3: Generate billing reports at month-end

Once a month, aggregate each customer's agent wallets to generate a usage report. This tells you and your customer where every dollar went.

Node.js
async function generateMonthlyReport(customerId) { const customer = await db.customers.findById(customerId); const start = '2026-05-01T00:00:00Z'; const end = '2026-05-31T23:59:59Z'; const reports = await Promise.all( customer.wallet_ids.map(walletId => async () => { const res = await fetch( `https://trove-qjow.polsia.app/api/wallets/${walletId}/transactions?from=${start}&to=${end}&limit=500`, { headers: { 'X-Trove-Key': process.env.TROVE_API_KEY } } ); const { transactions } = await res.json(); const total = transactions.reduce((s, t) => s + t.amount_usd, 0); return { walletId, total_spent: total, tx_count: transactions.length }; })() ); const totalBilled = reports.reduce((s, r) => s + r.total_spent, 0); // Generate invoice: base subscription + any overage await createInvoice(customerId, { base_fee: customer.plan.price_usd, usage_charges: Math.max(0, totalBilled - customer.plan.budget_pool_usd), agent_breakdown: reports }); return { totalBilled, reports }; }

The overage question: flat fee vs. metered billing

Two billing models work for AI agents:

Flat fee (cap at plan budget). Customer pays $99, gets $99 worth of agent wallet budget. If they run over, agents stop. No overage billing. This is simple and predictable — good for products where you want customers to optimize their usage, not pay for excess.

Metered (charge overage). Customer pays a base fee, plus per-dollar charges for what agents actually spend. If they spend $150 against a $99 plan, they pay $150. This captures more revenue but requires transparent usage reporting so customers don't feel blindsided.

Recommendation: Start with the flat-fee cap model. It's simpler to implement and doesn't require complex usage reconciliation. Once you have billing reports, you can add a metered option as a plan upgrade. The infrastructure is identical — you just change whether you bill the overage or cap it.

What this replaces

Without per-agent wallets, you'd track spending by querying each vendor's API dashboard — OpenAI, Anthropic, Serper — and trying to attribute costs to customers without per-agent granularity. You'd find out about a runaway agent from the vendor invoice, not from your own monitoring.

With wallets, every purchase call is a line item: wallet ID, amount, vendor, timestamp. Pull the report, see exactly what happened, charge accordingly. The billing system doesn't need to guess — the transaction ledger is the source of truth.

Try the billing model in the playground

Create two wallets with $10 budgets. Hit one with purchase calls until it rejects. Watch the transaction ledger build in real time.

Open the Playground

For the full API reference on wallet provisioning, balance checks, and transaction queries, see the Trove documentation. Billing implementation questions? Email the team.