Blog · · 11 min read

AI agent pricing without double-charging for retries

AI agent pricing without double-charging for retries

AI agent pricing breaks when a SaaS product sends raw model tokens or tool calls straight to the customer invoice. One user action can branch into several model turns, tools, retries, and a human review. The customer did not choose that execution plan, and a retry should not create a second charge. Meanwhile, a flat feature fee can hide expensive workflows until margins disappear. The fix is to keep two linked ledgers: one for the real cost of each agent run and another for customer-visible billable outcomes. This guide shows how to choose the unit, meter it once, handle failures and reversals, enforce plan limits, and verify margin before launch.

Separate cost attribution from customer billing

The run-cost ledger answers internal questions. Which tenant, workflow, model, tool, agent release, and review step created cost? The OpenAI Usage API and Costs API cookbook shows provider usage and cost data grouped by fields such as model and project. That data is useful for reconciliation and routing decisions. It is not automatically a good customer unit.

The billing ledger answers a customer contract question. What understandable unit did the product deliver, under which price and entitlement rules, and has that unit already been charged or reversed?

Keep both ledgers immutable. Corrections should append adjustment events instead of rewriting prior events. Link them with run_id, tenant_id, workflow_id, and agent_release_id, but never require one cost event to equal one billable event. A successful outcome may use several providers and tools. A failed run may create cost without creating anything billable.

This separation closes the main forecasting problem in a direct Hacker News practitioner question: one SaaS action can generate an unpredictable number of LLM requests and tokens. Your product should absorb that execution variability inside a defined unit, then manage it through internal budgets and routing.

Choose the right AI agent pricing unit

Current AI agent pricing pages already describe many models. Sierra compares traditional, consumption, and outcome-based pricing, while a Forbes contributor catalogs conversation, labor-replacement, outcome, blended, and agentic-seat approaches. The product decision is which unit your workflow can accept or reject consistently.

UnitUse it whenMain risk
SeatAgent value is broadly available to each licensed userHeavy users can make the plan unprofitable
RequestOne request has a stable scope and cost envelopeRetries and multi-step requests make the unit ambiguous
Provider tokenCustomers explicitly buy raw inference capacityBills expose implementation detail and become hard to predict
ConversationA conversation has a clear start, end, and service boundaryLong or repeated conversations can vary widely in cost and value
Accepted outcomeThe product can verify a durable business resultSubjective or delayed acceptance can create disputes

For an existing SaaS product, start with a hybrid contract: a base subscription includes a defined number of accepted outcome units, with an overage price or credit draw after the allowance. Keep provider tokens, tool fees, infrastructure, and review time inside the cost ledger.

Do not use outcome pricing when acceptance is subjective or cannot be observed within a reasonable reconciliation window. In that case, choose a bounded product unit such as a completed workflow, reviewed document, or processed record batch. Define its maximum scope so one unit cannot expand without limit.

A practitioner analysis of AI coding tools reports unpredictable credit burn and compares included completions, overages, throttling, hybrid, and outcome approaches. Treat that as one author's experience, not a market statistic. Customers need to know what consumes a unit, while the platform needs a hard ceiling on the work hidden inside it.

Define an accepted-outcome contract

Write the acceptance contract before integrating a billing provider. Product, engineering, support, and finance should be able to evaluate the same event and reach the same result.

For each workflow, specify:

  1. The object being changed or produced.
  2. The evidence required for acceptance.
  3. The actor allowed to accept it automatically or manually.
  4. The deadline after which the outcome becomes rejected or expired.
  5. The retry and correction work included in the original unit.
  6. The conditions that create a reversal or credit.
  7. The price and entitlement versions applied at acceptance time.

Use a state machine such as pending, accepted, rejected, expired, disputed, and reversed. Only the transition into accepted creates a positive billable unit. reversed creates a compensating negative adjustment. A later retry does not create a new unit unless it delivers a separately accepted result under a new customer request.

A portable event can look like this:

{
  "billing_event_id": "outcome:tenant_42:ticket_817:resolution:v1",
  "tenant_id": "tenant_42",
  "workflow_id": "support_resolution",
  "subject_id": "ticket_817",
  "run_id": "run_29a4",
  "agent_release_id": "release_2026_08_05_1",
  "outcome_state": "accepted",
  "acceptance_rule_version": "support-resolution-v3",
  "price_version": "agent-plus-2026-08",
  "entitlement_version": "pro-plan-v5",
  "quantity": 1,
  "accepted_at": "2026-08-05T14:03:00Z"
}

The identifier is deterministic for the billable outcome, not for each execution attempt. If a worker crashes after sending the event and sends it again on resume, both attempts carry the same identifier.

Meter once across retries and resumes

Stripe's meter-event API documentation says to use idempotency identifiers to prevent reporting usage more than once. It also notes that meter events are processed asynchronously, so an upcoming invoice may not immediately reflect a newly accepted event. Design your product ledger as the source of truth for what you emitted and what the billing provider acknowledged.

Use this sequence:

  1. Create a run with its tenant, workflow, entitlement snapshot, and internal cost budget.
  2. Reserve the required customer allowance or credit before expensive work starts.
  3. Append model, tool, infrastructure, and review costs to the run-cost ledger.
  4. Evaluate the workflow's versioned acceptance rule.
  5. Create one deterministic billable event when the outcome becomes accepted.
  6. Deliver it through an outbox and record the provider acknowledgement.
  7. Release the reservation if the outcome is rejected, expired, or cancelled.
  8. Append a reversal if an accepted outcome is later invalidated under policy.

The write that accepts the outcome and inserts the billing outbox record should be atomic in your product database. Delivery to the external billing system can then retry safely.

def accept_outcome(tx, run, evidence):
    rule = load_acceptance_rule(run.acceptance_rule_version)
    if not rule.accepts(evidence):
        tx.mark_outcome(run.id, "rejected")
        tx.release_reservation(run.entitlement_reservation_id)
        return

    event_id = deterministic_outcome_id(
        tenant_id=run.tenant_id,
        workflow_id=run.workflow_id,
        subject_id=run.subject_id,
        acceptance_rule_version=run.acceptance_rule_version,
    )

    tx.insert_billable_event_if_absent(
        event_id=event_id,
        run_id=run.id,
        quantity=1,
        price_version=run.price_version,
    )
    tx.consume_reservation(run.entitlement_reservation_id, event_id)
    tx.enqueue_billing_delivery_if_absent(event_id)

The if_absent checks must be backed by unique constraints. An in-memory duplicate check is not enough after a process restart or concurrent resume.

Decide which failures are billable

  • A provider or platform retry does not create another unit. The customer requested one result, and the platform chose to retry its execution.
  • A rejected or expired result releases the reserved unit. Internal cost remains in the run-cost ledger.
  • A partial result is billable only if the plan names it as a separate accepted unit. Do not invent a fractional charge after the fact.
  • A customer-requested revision reuses the original unit when it corrects an unaccepted result. Create a new unit only when the customer accepts a new scope and the product records that decision.
  • Required human review is internal cost. Price it separately only when the customer explicitly purchases a review service with its own acceptance contract.
  • A disputed accepted result moves to disputed with its evidence and applied rule version. Append a reversal if policy grants the credit.

Never delete an accepted event to make an invoice match. A reversal preserves the audit chain from acceptance to adjustment and lets finance reconcile the product ledger with the billing provider.

Enforce plan gates before the agent runs

Stripe's usage-based billing overview supports usage pricing and adding it to existing flat-rate subscriptions. Your product still owns the entitlement decision that happens before work begins.

Evaluate these gates in order:

  1. Is the workflow included in the customer's plan?
  2. Is an included unit, prepaid credit, or approved overage available?
  3. Does the run fit the plan's maximum scope, tool, and review policy?
  4. Does the tenant remain below its hard spend or unit limit?
  5. Does the internal cost budget permit the chosen model and tool plan?

Return a typed product outcome such as upgrade_required, credit_required, limit_reached, or cheaper_mode_available. Do not let the agent discover a billing denial halfway through side effects.

Use soft warnings before a hard limit. Show consumed units, pending reservations, accepted units, reversals, and the next reset date. Pending reservations must be visible because several long-running tasks can otherwise appear to fit the same final allowance.

Work through a support-agent example

Suppose an existing help-desk product charges for accepted ticket resolutions. One billable unit is a ticket whose resolution passes the current acceptance rule, regardless of how many model requests, tool calls, or conversations produced it.

A run reads the ticket, customer account, and plan; drafts a response; updates the record; and waits for either an automated policy check or an agent review. Those steps append costs internally. If a provider timeout repeats the draft call, the retry stays inside the same run. When the ticket reaches the accepted resolution state, the product emits one event keyed by tenant, ticket, workflow, and acceptance-rule version.

If the tool update succeeds but billing delivery times out, the outbox retries the same event ID. If the customer reopens the ticket within the contractual reversal window and support determines that the resolution was invalid, the product appends one reversal. Finance can now see the original accepted unit, the reversal, and the total execution cost without pretending that cost disappeared.

This contract also makes pricing experiments safer. A new price can apply to new acceptance events while every old event keeps its original price_version. A plan migration changes future entitlement snapshots, not historical usage.

Verify margin by workflow and cohort

Do not evaluate AI economics only at the provider account level. Reconcile at least by tenant, plan, workflow, agent release, model route, and acceptance-rule version.

Use definitions that finance and engineering share:

run_cost = model_cost + tool_cost + infrastructure_cost + review_cost
accepted_units = distinct accepted outcome IDs
net_units = accepted_units - reversed units
recognized_agent_revenue = billed unit revenue - credits and reversals
contribution = recognized_agent_revenue - run costs for the same cohort

Late provider costs should append to the original run's cohort. Late reversals should adjust the original billable cohort and the current financial period according to your accounting policy. The product analytics layer should preserve both views rather than silently moving the original event.

Review p50, p95, and worst-case run cost alongside acceptance rate and contribution. Averages alone can hide one workflow whose long tail consumes the margin earned elsewhere. Use those observations to change the internal cost budget, route to a cheaper execution path, narrow the unit's allowed scope, or change the next price version. Do not retroactively change what an accepted historical unit meant.

Test the billing contract before launch

Run the same scenarios against the product ledger, delivery outbox, and billing-provider test environment.

ScenarioRequired result
Model or tool retries three timesOne accepted outcome can create at most one positive billable event
Worker crashes after event deliveryResume sends the same event ID and does not duplicate usage
Acceptance and outbox write raceBoth commit together or neither commits
Customer lacks allowanceAgent work does not start and no provider cost is created
Price changes during a long runAcceptance uses the price snapshot promised by policy
Accepted outcome is disputedOne linked reversal is appended without deleting history
Provider cost arrives lateCost attaches to the original run and cohort
Billing provider is unavailableAccepted event remains in the outbox and retries with bounded backoff

After launch, reconcile three counts every day: accepted outcomes in the product ledger, acknowledged positive and negative events in the billing provider, and invoice quantities. Alert on missing acknowledgements, duplicate identifiers, stale reservations, reversals without originals, and costs without a valid run.

Avoid common pricing mistakes

Pass token prices through only when the customer explicitly buys inference capacity. A product that sells results should not charge execution attempts, and every retry should retain the original billing key. Price and acceptance-rule changes apply to new events rather than history. Required human review belongs in the cost ledger. Keep margin reporting separate for each workflow instead of blending them into one average.

Also avoid claiming that outcome pricing solves every product. If acceptance is subjective, delayed for months, or controlled by an external party, a completed workflow or bounded usage unit is easier to audit. The best unit is the narrowest one that customers understand, the product can verify, and the platform can deliver inside a controlled cost envelope.

Make the pricing decision

For AI agent pricing inside an existing SaaS product, use a base subscription with included accepted outcome units and a clear overage or credit rule when three conditions hold: acceptance is objective, the outcome maps to durable product state, and disputes can be reversed through policy. Keep tokens and tool calls internal.

If any condition fails, bill a bounded workflow unit instead. Define its maximum records, actions, runtime, and review scope, then expose that limit before the run starts.

Take one production workflow now and write its acceptance state machine, deterministic billing-event key, reversal rule, entitlement gate, and cost-ledger dimensions. Run the eight test scenarios above before connecting the event to a live invoice.

References

Be first in line.

Join the waitlist and we'll email you the moment it's ready. No sales call.

Try the demo →
or talk to us