> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Outcome-based AI-agent billing: pay per resolved conversation, not per token

> The outcome pricing model for AI agents — a charge fires only when a rubric evaluator marks a conversation PASSED and the tenant has opted in, with versioned rubric keys, micro-cent rates, and the same append-only wallet ledger every other charge lands in.

# 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](/concepts/llm-spend-cost-attribution-model) 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:

```
GET /api/v1/billing/outcome-pricing
PUT /api/v1/billing/outcome-pricing
```

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:

```json theme={null}
{
  "data": {
    "enabled": false,
    "defaultRateMicroCents": 500000,
    "perOutcomeRateMicroCents": {}
  }
}
```

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](/concepts/wallets-credits-and-charges) 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](/concepts/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:

```http theme={null}
PUT /api/v1/billing/outcome-pricing
{
  "enabled": true,
  "defaultRateMicroCents": 500000,
  "perOutcomeRateMicroCents": {
    "rub_appointment": 2000000
  }
}
```

This flips the gate on, leaves every outcome at the default $0.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:

```http theme={null}
GET /api/v1/billing/transactions
```

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](/concepts/llm-spend-cost-attribution-model) 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

* [Wallets, credits, and charges](/concepts/wallets-credits-and-charges) — the append-only ledger outcome charges settle into.
* [LLM spend attribution](/concepts/llm-spend-cost-attribution-model) — the cost-side feed outcome billing complements.
* [QA evaluations and the performance leaderboard](/concepts/qa-leaderboard-and-evaluations) — the rubric scorecard pipeline the PASSED gate rides on.
* [The call-quality evaluation lifecycle](/concepts/quality-evaluation-lifecycle) — the operations layer around those scorecards.
* [AI agent architecture](/concepts/ai-agent-architecture) — where the evaluator and the run lifecycle meet.
