Skip to main content

Outcome-based AI-agent billing

Most AI pricing charges for activity, not for what the activity was worth. Outcome-based pricing is the opposite axis: you pay only when an AI agent produced a verified business result — a resolved ticket, a booked appointment, a confirmed identity. On Orbit the charge gate is the same rubric evaluator you use for QA: a conversation becomes billable only when the LLM judge marks it PASSED against one of your rubrics, and only if you turned outcome charging on. Three pricing models live side by side on Orbit, and this page is about the third:
  • Seat pricing — a flat monthly cost per human workspace member, independent of how much they do. Agents that replace headcount do not fit this model at all.
  • Per-token pricing — the LLM-spend meter. It tracks cost truthfully but charges for attempts, pass or fail: a conversation that burned tokens and resolved nothing costs the same as one that closed the ticket. That meter is LLM spend attribution and it keeps running unchanged — token costs are an input to your cost-to-serve view, not a revenue line.
  • Outcome pricing — one fixed-rate charge per confirmed resolution, attached to the rubric that judged the conversation. If nothing passes, nothing bills.
A rubric is a set of success criteria you author (in markdown) and attach to an agent — for example, “the caller’s issue is resolved, the answer stayed in scope, no incorrect escalation.” The judge evaluates every completed conversation against the rubric and records one row per conversation-rubric pair with a passed flag and a confidence score. Outcome billing consumes exactly those rows: passed = true plus tenant opt-in is the only combination that produces a charge.

Where the opt-in lives

Outcome charging is off for every workspace until you enable it, and it stays tenant-owned: you read and write two settings keys on your organization through the self-serve API, and no other tenant’s config affects yours.
  • outcome_charge_enabled — the top-level boolean gate. While it is false, the metering pipeline never emits a charge for your conversations, whatever the rate config says.
  • outcome_pricing — the rate object, { defaultRateMicroCents, perOutcomeRateMicroCents }.
Both keys are managed through one resource:
Owner, admin, or billing role required for both verbs — enabling this changes how your workspace is charged, so it sits behind the billing role rather than a developer scope. Every successful PUT is written to your audit log, and an audit-log write failure does not roll back the config change (it is logged and the write stands), so the toggle can never wedge on a logging hiccup. Responses use the standard { data, meta } envelope. A workspace that has never touched the config reads back the opt-out defaults, so a settings form always renders a stable shape:
Writes are idempotent: a PUT validates the full config object, replaces exactly those two settings keys (every unrelated settings key — auto-top-up, billing flags, and so on — survives untouched), and returns the config re-read from the persisted state. Retrying a timed-out PUT with the same body is a no-op write, and the read-back you get is what the metering pipeline will actually use.

The pricing model

Rates are integer micro-cents — the same unit the wallet ledger runs on. One US dollar is 100,000,000 micro-cents (one cent = 1,000,000 micro-cents), so the default rate of 500,000 micro-cents is $0.005 per resolved outcome. Two fields price every charge:
  • defaultRateMicroCents — applied to any resolved outcome whose rubric has no explicit override. Default 500,000 ($0.005).
  • perOutcomeRateMicroCents — a map from an outcome key to a rate. The outcome key is the rubric’s stable id, so renaming a rubric never re-prices its historical charges and your per-rubric override keeps holding. Price a “booked-appointment” rubric higher than a “resolved-ticket” rubric by key, not by display name.
Both rates are bounded to $10.00 (1,000,000,000 micro-cents) per outcome. The ceiling exists to stop a fat-fingered config from producing absurd charges; a value above it is rejected with a 422 before anything persists.

Where charges come from

The metering producer is wired into the rubric evaluator itself and runs after the outcome row is already written:
  1. A conversation completes and the judge evaluates it against your rubric, persisting the outcome row (passed, confidence, rubric id).
  2. If — and only if — that row was newly written with passed = true, the producer checks your two settings keys through the shared organization-settings read cache.
  3. When outcome_charge_enabled is true, it resolves the rate for the rubric’s outcome key (per-outcome override first, then the default) and emits exactly one billable usage event: quantity 1, the resolved rate carried in the event metadata, currency USD.
  4. The charge lands in the same append-only wallet ledger every other Orbit charge uses — Wallets, credits, and charges — and you read it back from the same places, including GET /api/v1/billing/transactions.
Three lines on the idempotency and failure envelope, because they decide what you observe:
  • One charge per conversation-rubric pair. The usage event’s idempotency key is derived from the conversation id plus the rubric id — the same pair the outcome row’s uniqueness constraint keys on, so the DB and the billing feed dedupe identically. A replayed evaluation of the same conversation collapses to a single charge; you never get billed twice for one resolution.
  • Fail-open on the pipeline, not on the gate. If the usage-event feed hiccups or your settings row can’t be loaded, the error is logged and swallowed — the conversation-close path is never blocked by a billing problem, and the missing-charge fallback is “not enabled,” never “charge by accident.”
  • Metering is best-effort, the opt-in is not. You see a skipped charge as a zero row, not as a conversation failure; the audit surface for passed conversations is the outcome row itself (with the judge’s confidence), which is written before metering fires.

Worked example

Enable outcome charging and price your two rubrics differently:
This flips the gate on, leaves every outcome at the default 0.005,andpricesthebookedappointmentrubric(rubappointment)at0.005, and prices the booked-appointment rubric (`rub_appointment`) at 0.02. From the next completed conversation on, a PASSED evaluation on rub_appointment debits 2,000,000 micro-cents; a PASSED evaluation on any other rubric debits 500,000; anything that fails the judge debits nothing. The response returns the persisted config re-read from the settings row. After an agent conversation passes, read the debit back from the ledger the same way you read any other charge:
Each resolution is its own row in your transaction history — one append-only ledger entry per confirmed outcome, with the resolved rate and outcome key carried in the row’s metadata — so the spend view and the evaluators’ outcomes view reconcile to the penny.

How it reads next to LLM spend

Outcome charges and LLM-spend attribution are two different feeds on purpose. The LLM spend feed attributes token costs by feature × model × conversation — it tells you what a resolution cost. Outcome charges are the revenue complement — they tell you what a resolution billed. Because both feeds key on the same conversation id, you can stack them: a conversation’s P&L line pairs the LLM tokens it consumed against the outcome charge it produced, and the conversations that pass nothing carry only their (still accurate) token costs.

Limits

  • No money moves on the config endpoints. GET/PUT on /api/v1/billing/outcome-pricing only reads and writes the two settings keys; charges fire downstream in the metering producer when a rubric marks a conversation PASSED.
  • Opt-in is a precondition to any charge. If enabled is false, the metering pipeline records the outcome rows but emits no billable event — enabling is always your explicit action.
  • Rates are integers in micro-cents, bounded to $10/outcome. A non-integer rate or a value over the ceiling is rejected with 422 before persistence.
  • The rubric is the gate. A conversation that never gets evaluated, or evaluates to not-passed, bills zero regardless of pricing config.

Cross-references