Blog
    Guides9 min read

    How Usage-Based Pricing Models Work for AI Automation Platforms

    A technical guide to building credit-based ledgers for token-consuming AI agents — metering, billing, and reconciliation with cred.diy.

    By cred.diy Team

    How Usage-Based Pricing Models Work for AI Automation Platforms

    AI automation platforms — agents, copilots, workflow orchestrators — burn through model tokens, tool calls, and compute the moment a user hits "run". Flat subscriptions break under that variance: power users lose money for you, light users overpay and churn. Usage-based pricing fixes the mismatch, but only if you have a ledger that can meter every token, deduct atomically, and reconcile against your upstream model bills.

    This guide walks through how usage-based pricing models work for AI automation platforms, and how to implement one end-to-end using cred.diy as the off-chain ledger.

    Why usage-based pricing fits AI agents

    A single agent run can span dozens of LLM calls, retrieval lookups, and external tool invocations. Costs vary by:

    • Model tier (GPT-4 class vs. small/fast models)
    • Input/output tokens per call
    • Tool calls (search, code execution, browsing, vector DB)
    • Retries and self-correction loops

    Charging per seat hides that variance from the user and from your margin. Charging per credit exposes it — users see exactly what an automation costs, and you bill in proportion to what you spent.

    The credit-ledger model

    A credit ledger is a double-entry record of every issue and deduct against a user's balance. For AI workloads it needs four properties:

    1. Atomicity — a deduct either fully succeeds or fully fails. No partial debits when a model call errors mid-stream.
    2. Idempotency — replaying a webhook or retrying an agent step must not double-charge.
    3. Auditability — every transaction is traceable to a run, a model call, and a price.
    4. Multi-currency — separate ledgers for "AI credits", "storage credits", or per-tenant tokens.

    cred.diy implements all four out of the box: balances live in numeric(20,6) columns, deducts go through an atomic_balance_update RPC with row-level locks, and each credit type is an independent currency.

    Architecture

    User → Your Agent Runtime → Model Provider (OpenAI, Anthropic, ...)
                  │
                  ├── pre-check: GET /balance
                  ├── per-step: POST /credits/deduct  (idempotent)
                  └── on-error: POST /credits/refund
    

    The agent runtime is the only thing that talks to cred.diy. The browser never holds an API key.

    Step 1: Define a credit type for AI usage

    Create a credit type that represents 1 unit of internal cost. One workable choice is "1 credit = $0.001 of upstream spend" — small enough to price cheap calls, large enough to avoid floating-point noise.

    // One-time setup in Dashboard → Credit Types; copy its ID for the calls below
    const aiCredit = {
      symbol: "AIC",
      name: "AI Credits",
      description: "Credits consumed by agent runs",
    };
    

    Pricing tiers map dollars to credits — e.g. $10 = 12,000 AIC (a 20% bonus on bulk top-ups).

    Step 2: Price each model call

    Build a small pricing table keyed by model. Convert tokens to credits at request time:

    const MODEL_PRICING = {
      "gpt-4o":        { in: 0.0025, out: 0.01 },   // per 1K tokens
      "claude-sonnet": { in: 0.003,  out: 0.015 },
      "gpt-4o-mini":   { in: 0.00015, out: 0.0006 },
    };
    
    function costInCredits(model, usage) {
      const p = MODEL_PRICING[model];
      const dollars = (usage.input_tokens  / 1000) * p.in
                    + (usage.output_tokens / 1000) * p.out;
      // 1 credit = $0.001 — add your margin here
      return Math.ceil(dollars * 1000 * 1.30);
    }
    

    The 1.30x multiplier is your margin. Tune it per model or per plan.

    Step 3: Pre-check the balance

    Before kicking off an expensive run, confirm the user can afford the expected cost. This avoids starting a 30-second agent loop only to fail at the last step.

    const API = "https://eutdgemlrpvnxfkkpvlu.supabase.co/functions/v1/credits-api";
    const AIC = "your_ai_credit_type_id";
    
    const { balances } = await fetch(
      `${API}/balance?email=${encodeURIComponent(email)}&credit_type_id=${AIC}`,
      { headers: { "x-api-key": API_KEY } }
    ).then(r => r.json());
    const balance = balances[0]?.balance ?? 0;
    
    if (balance < estimatedCost) {
      return { error: "insufficient_credits", topupUrl: "/billing" };
    }
    

    Step 4: Deduct after each model call

    The cleanest pattern is post-paid per step: run the call, read usage from the provider response, then deduct. Send the provider's response id as the Idempotency-Key so a retried deduct is only charged once.

    const completion = await openai.chat.completions.create({ ... });
    
    await fetch(`${API}/deduct`, {
      method: "POST",
      headers: {
        "x-api-key": API_KEY,
        "Content-Type": "application/json",
        "Idempotency-Key": completion.id,      // provider request id
      },
      body: JSON.stringify({
        user_email: email,
        credit_type_id: AIC,
        amount: costInCredits(completion.model, completion.usage),
        reason: `${completion.model} · run ${agentRunId} step ${stepNumber}`,
        reference_id: completion.id,
      }),
    });
    

    If the deduct returns 400 with code INSUFFICIENT_CREDITS, the user ran out mid-run — stop the agent, surface a top-up prompt, and refund any partial output you don't want to charge for.

    Step 5: Refund on failure

    When a tool call errors after a model deduction, refund all or part of it. cred.diy treats refunds as first-class transactions, so the audit trail stays clean:

    await fetch(`${API}/refund`, {
      method: "POST",
      headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
      body: JSON.stringify({
        reference_id: completion.id,   // reverses the deduct carrying this reference
        amount: lastDeductAmount,      // omit to refund the whole deduction
        reason: "tool_call_failed",
      }),
    });
    

    Step 6: Reconcile against upstream bills

    At the end of each billing period, compare the sum of credit deducts (converted back to dollars) against your OpenAI / Anthropic invoices. A persistent gap usually means:

    • A model price changed and MODEL_PRICING is stale
    • Retries aren't being deducted
    • A tool integration is bypassing the ledger

    Every deduct carries the provider request id as its reference_id, so you can match GET /transactions against your own log of model and token counts per request.

    Off-chain by default

    For most AI platforms, an off-chain ledger is the right call. You get fast reads, no gas, no chain reorgs, and full control over refunds and disputes. cred.diy's email-first identity model means a user keeps the same balance across every app they sign into — no wallet popups, no signature prompts inside an agent run.

    If you later want on-chain settlement (e.g. for a token launch or cross-app rewards), the same ledger powers presales and credit swaps without rewriting your agent code.

    Common pitfalls

    • Deducting before the call returns — you'll over-charge on errors. Always read usage from the response.
    • Forgetting idempotency keys — a retried webhook will double-charge. Always pass the provider's request id.
    • Mixing margin into the credit price — keep the credit unit stable ($0.001) and apply margin in the deduct math. It makes pricing changes a one-line edit.
    • No pre-check — long agent runs that fail at step 12 because the user ran out at step 3 are the #1 source of support tickets.

    Wrapping up

    Usage-based pricing for AI automation platforms comes down to three things: a stable credit unit, atomic per-step deducts, and clean reconciliation against upstream bills. cred.diy gives you the ledger so you can focus on the agent.

    Create a credit type and start metering in under ten minutes.

    Try it on a real project.