> ## 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.

# The pricing-preview pipeline: projected margin and payout before close

> The five read-only preview endpoints that project what a billing period would look like before it closes — AIaaS usage charges, marketplace rev-share with builder payouts, resolution metering, reseller margin rollup with partner revenue share, and the partner payout ledger — and how they differ from the ledger, the invoices, and the what-if rate simulator.

# The pricing-preview pipeline

Most billing surfaces answer one of two backward-looking questions: "what did
we already charge" (the wallet ledger, the usage-records feed, invoices) or
"what has been invoiced so far" (billing documents). The pricing-preview
pipeline answers the forward-looking question finance ops actually asks at
period close: **what would this month look like if we closed it right now**.

Five scoped preview endpoints project the answer, each over one billing
engine's inputs:

* `POST /billing/aiaas-usage-pricing/preview` — AI usage charges
* `POST /billing/marketplace-rev-share/preview` — marketplace builder payouts
* `POST /billing/resolution-usage-meter/preview` — pay-per-resolution metering
* `POST /billing/margin-rollup/preview` — reseller margin + revenue share
* `POST /billing/payout-ledger/preview` — partner payout ledger + statement

Every one is a **pure, read-only estimate**. No money moves, no database row
is written, no Stripe or Orb event is emitted, and nothing is debited from a
wallet. Each is gated by billing-read auth. This page frames them as one
projection layer, distinct from the ledger (money that moved) and from the
what-if rate simulator (hypothetical rate cards). The worked examples at the
end show the two reseller-side projections — a leaf-tenant margin statement
and a marketplace builder payout.

## Purpose — a projection oracle, not a ledger and not a simulator

Orbit has three forward/backward-looking layers that are easy to confuse:

| Layer                      | Surface                                                                                                                                            | Question answered                                   |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
| **Ledger (backward)**      | [Billing and wallet](/concepts/billing-and-wallet), [usage records](/concepts/usage-records-model), [documents](/concepts/billing-documents-model) | What already posted, debited, or invoiced           |
| **Projection (forward)**   | The five preview endpoints on this page                                                                                                            | What the period would look like if it closed now    |
| **What-if (hypothetical)** | [Pricing calculator](/billing/pricing-calculator), [what-if simulator](/guides/whatif-pricing-simulator)                                           | What a rate would do under a hypothetical rate card |

The pricing-preview layer is the middle row: a **projection oracle**. It
reads no live ledger state and writes nothing back. A tenant or reseller
posts candidate usage inputs (messages, voice minutes, invocations,
resolutions, margin lines, payout entries) and gets back the exact billing
breakdown the live engine would compute for those inputs. Read it before
enabling a charge path, before paying a partner, or before telling a
leaf-tenant what its month will look like.

## Input catalog — the six engines each fan-in reads

The preview controller is a fan-in over six billing calculators. Each
endpoint composes one of them; reading the controller's imports is the whole
input catalog:

* `resolution-usage-meter` — `projectResolutionUsageEvents`,
  `aggregateResolutionMeter`, `buildResolutionInvoiceLineItems`: projects
  confirmed AI resolutions into idempotent usage events, rolls them into a
  meter, see them as line items.
* `margin-rollup` — `computeMarginRollup`,
  `computeResellerRevenueShareStatement`, and the `MarginLine` / `MarginGroup`
  types: rolls reseller lines (revenue, COGS) into sub-account / channel /
  region margins, and computes a partner revenue-share statement from the
  same rollup.
* `payout-ledger` — `computePartnerPayoutLedger`,
  `computePartnerPayoutStatement`, and the
  `PayoutLedgerEntry` / `PayoutLedgerComputedEntry` types: folds accrual,
  payout, and adjustment events into a running balance, then cuts a period
  statement.
* `marketplace-rev-share` — `computeMarketplaceRevShare`,
  `aggregateBuilderPayouts`: splits metered marketplace invocations into
  gross, platform fee, and per-builder payout.
* `aiaas-usage-pricing` — `computeAiaasUsageCharges`: estimates AI usage
  across the three billable axes (messages, voice minutes, resolved outcomes).
* `outcome-pricing` — `outcomePricingConfigSchema`: the config schema the
  resolution-meter preview validates against.

The request-body validation lives in a shared schemas module that reuses each
engine's canonical config schemas, so the preview can never drift from the
engine it estimates.

## Aggregation envelope — one org-scoped response per endpoint

Each preview endpoint owns one engine's aggregation and returns one org-scoped
JSON envelope. There is no cross-engine summation at the controller layer —
each endpoint projects its own shard and returns its own totals inside the
standard `{ data, meta }` envelope.

| Endpoint                         | Aggregation                                                                                     | Response shape                                                                   |
| -------------------------------- | ----------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| `aiaas-usage-pricing/preview`    | `computeAiaasUsageCharges` over message/voice/outcome counts                                    | `totalMicroCents` + per-axis breakdown                                           |
| `marketplace-rev-share/preview`  | `computeMarketplaceRevShare` → `aggregateBuilderPayouts`                                        | `{ breakdown, payouts }`                                                         |
| `resolution-usage-meter/preview` | `projectResolutionUsageEvents` → `aggregateResolutionMeter` → `buildResolutionInvoiceLineItems` | `{ events, rollup, lineItems }`                                                  |
| `margin-rollup/preview`          | `computeMarginRollup` (+ optional `computeResellerRevenueShareStatement`)                       | totals + by-subaccount/channel/region groups; optional `revenue_share_statement` |
| `payout-ledger/preview`          | `computePartnerPayoutLedger` (+ optional `computePartnerPayoutStatement`)                       | entries with running balance + totals; optional `statement` with opening/closing |

Because each response is org-scoped and billing-read-gated, a reseller
re-reads only its own branch of the tree, and a tenant re-reads only its own
usage. All validation errors return `422` with a single `VALIDATION_ERROR`
code, and margin-preview rejects mixed-currency inputs rather than summing
across them — a cross-currency sum would be meaningless.

## Reading it — preview vs dashboard calculator vs the real charge path

Use the layer for the question you actually have:

* **"What did I already spend?"** — read the wallet ledger or the
  [usage-records feed](/concepts/usage-records-model). The preview never
  substitutes for the posted record.
* **"What would this month look like?"** — post the candidate usage to the
  relevant preview endpoint and read the projected breakdown.
* **"What if I change the rate?"** — use the [pricing
  calculator](/billing/pricing-calculator) / [what-if
  simulator](/guides/whatif-pricing-simulator), which vary the rate card, not
  the usage.

The dashboard billing calculator and record simulations layer over the same
pure engines the preview endpoints expose — the numbers agree with the
projection layer by construction, because both call the same calculators.
The real charge path is separate: it consumes posted usage records through
the metering pipeline and debits the wallet, and reads none of the preview
responses.

## Glossary

* **Margin line** — one reseller profitability input: a sub-account, channel,
  optional region, its revenue, and its cost of goods. `margin-rollup` folds
  a set of these into margins.
* **Revenue share** — a partner's negotiated percentage (basis points) of the
  net margin a reseller earned, computed from the same margin rollup so the
  statement agrees with the rollup.
* **Payout ledger entry** — one accrual, payout, or adjustment event on a
  partner's ledger, with a running balance after each entry.
* **Projected invoice line item** — a line the resolution meter would emit on
  an invoice if the period closed now; a descriptor, not a posted line.

## Worked example — reseller margin + partner revenue share

A reseller projects one leaf-tenant's month before close and asks for its
white-label partner's statement in the same call.

```http theme={null}
POST /billing/margin-rollup/preview
Authorization: Bearer <api key>
Content-Type: application/json

{
  "currency": "usd",
  "lines": [
    {
      "subaccount_id": "leaf_acme",
      "channel": "sms",
      "region": "US",
      "currency": "usd",
      "revenue_minor": 120000,
      "cost_minor": 82000,
      "quantity": 4000
    },
    {
      "subaccount_id": "leaf_acme",
      "channel": "voice",
      "region": "US",
      "currency": "usd",
      "revenue_minor": 30000,
      "cost_minor": 19100,
      "quantity": 600
    }
  ],
  "revenue_share": {
    "partner_id": "partner_wl",
    "partner_revenue_share_bps": 2500,
    "period_start": "2026-09-01",
    "period_end": "2026-09-30"
  }
}
```

The abbreviated response rolls totals, per-channel groups, and — because
`revenue_share` was supplied — the partner statement computed from the same
rollup:

```json theme={null}
{
  "data": {
    "currency": "usd",
    "totals": {
      "revenue_minor": 150000,
      "cost_minor": 101100,
      "margin_minor": 48900,
      "margin_pct_bps": 3260,
      "quantity": 4600,
      "line_count": 2
    },
    "by_channel": [
      {
        "key": "sms",
        "revenue_minor": 120000,
        "cost_minor": 82000,
        "margin_minor": 38000,
        "margin_pct_bps": 3167,
        "quantity": 4000,
        "line_count": 1
      }
    ],
    "revenue_share_statement": {
      "partner_id": "partner_wl",
      "currency": "usd",
      "period_start": "2026-09-01",
      "period_end": "2026-09-30",
      "partner_revenue_share_bps": 2500,
      "gross_revenue_minor": 150000,
      "cost_of_goods_minor": 101100,
      "net_margin_minor": 48900,
      "partner_share_minor": 12225,
      "platform_retained_minor": 36675,
      "line_items": [
        {
          "subaccount_id": "leaf_acme",
          "revenue_minor": 150000,
          "cost_minor": 101100,
          "margin_minor": 48900,
          "partner_share_minor": 12225
        }
      ]
    }
  }
}
```

Reseller reads at a glance: net 48,900 minor units of margin for the leaf,
and the partner is owed 25% of that — 12,225.

## Worked example — marketplace builder payout projection

A platform projects what it owes marketplace builders before running a payout.
It posts metered invocations and per-listing pricing and gets back the gross,
the platform fee, and each builder's payout.

```http theme={null}
POST /billing/marketplace-rev-share/preview
Authorization: Bearer <api key>
Content-Type: application/json

{
  "invocations": [
    { "listingId": "lst_recorder", "builderOrgId": "org_builder1", "consumerOrgId": "org_acme" },
    { "listingId": "lst_recorder", "builderOrgId": "org_builder1", "consumerOrgId": "org_acme" },
    { "listingId": "lst_summary", "builderOrgId": "org_builder2", "consumerOrgId": "org_acme" }
  ],
  "pricingByListing": {
    "lst_recorder": { "enabled": true, "perCallPriceMicroCents": 120000, "platformFeeBps": 1500 },
    "lst_summary":   { "enabled": true, "perCallPriceMicroCents": 50000,  "platformFeeBps": 1500 }
  }
}
```

The abbreviated response splits each listing's gross into platform fee and
builder payout, then aggregates builders (here, builder1's two calls and
builder2's one):

```json theme={null}
{
  "data": {
    "breakdown": {
      "totalGrossMicroCents": 290000,
      "totalPlatformFeeMicroCents": 4350,
      "items": [
        { "listingId": "lst_recorder", "builderOrgId": "org_builder1", "grossMicroCents": 240000, "platformFeeMicroCents": 3600 },
        { "listingId": "lst_summary", "builderOrgId": "org_builder2", "grossMicroCents": 50000, "platformFeeMicroCents": 750 }
      ]
    },
    "payouts": [
      { "builderOrgId": "org_builder1", "netMicroCents": 236400, "grossMicroCents": 240000 },
      { "builderOrgId": "org_builder2", "netMicroCents": 49250, "grossMicroCents": 50000 }
    ]
  }
}
```

The platform knows before close: it invoices 290,000 total, retains 4,350 as
its fee, and owes builder1 236,400 and builder2 49,250.

## Boundary — what the projection layer is not

* **Not the ledger.** The [billing and wallet](/concepts/billing-and-wallet)
  model and [wallets, credits, and
  charges](/concepts/wallets-credits-and-charges) cover money that moved. A
  preview never reads or writes the wallet.
* **Not an invoice.** [Billing documents](/concepts/billing-documents-model)
  owns the post-close receivable a provider issues. A preview is pre-close by
  definition and becomes non-authoritative at close.
* **Not the raw usage feed.** [Usage metering
  pipeline](/concepts/usage-metering-pipeline) owns the raw usage record feed
  the meters roll. A preview consumes candidate inputs, never the posted
  feed.
* **Not a rate simulator.** The [pricing
  calculator](/billing/pricing-calculator) varies the rate card; the preview
  varies the usage. They answer different "what if" questions.

## Related

* [Billing and wallet](/concepts/billing-and-wallet) — what moved
* [Usage metering pipeline](/concepts/usage-metering-pipeline) — raw usage
  feed
* [Billing documents model](/concepts/billing-documents-model) — post-close
  invoice
* [Usage records model](/concepts/usage-records-model) — per-record billing
  feed
* [Pricing calculator](/billing/pricing-calculator) — what-if rate simulation
* [Wallets, credits, and charges](/concepts/wallets-credits-and-charges) —
  ledger attribution
