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

# Commitments

> Represent minimum spend commitments on a subscription, with postpaid true-ups or prepaid credit pools.

<Info>
  **This feature is in early access.**

  Commitments are currently available to a limited set of customers. If you're interested in enabling this feature or have feedback, please reach out to your Orb account team or [contact support](https://support.withorb.com/).
</Info>

## What it does

A **commitment** is a minimum spend that a customer agrees to over a defined window. It comes in two forms, distinguished by when the payment takes place.

* A **postpaid commitment** settles at the end. As usage on the subscription accrues, it draws down against the committed amount; if cumulative usage falls short of the commitment, Orb bills the difference as a true-up. It's the natural fit for an annual (or multi-period) minimum spend floor negotiated as part of an enterprise contract.
* A **prepaid commitment** settles at the start: the customer is invoiced upfront for a pool of credits that usage draws down over the window. Usage beyond the pool is billed as regular usage at each price's own rate, and unused credits expire by the end of the commitment. The pool can be denominated in the settlement currency or in a virtual unit like tokens, at a cost basis set per unit.

## Boundaries during early access

**One active commitment per subscription at a time.** A subscription can carry several commitments, including back-to-back terms scheduled upfront, but their windows can't overlap (canceled commitments excepted).

**Window constraints.** A commitment can't start before the subscription starts or end after it ends, and its start and end must fall on midnight in the [customer's timezone](/essentials/timezones). When a commitment repeats on a cadence, its term must be a whole number of months and a whole multiple of that cadence. A recurring true-up cadence also requires the subscription's billing schedule to line up with the commitment's boundaries, so that each true-up lands on an invoice date.

<Note>
  **Revenue reporting doesn't yet cover prepaid drawdowns granted on a cadence.** Revenue is recognized correctly as usage consumes each grant, but the upfront billing is attributed entirely to the first grant, so deferred revenue appears overstated on the first grant and understated on the later ones. The amounts reconcile in aggregate, but reporting does not surface this movement at the individual grant level.
</Note>

## Configuring a commitment

Commitments are managed as part of creating or editing a subscription. In the creation or edit flow, find the Commitments section and click Add commitment.

The first choice is the commitment type: post-paid, where Orb bills a true-up at the end if usage falls short, or pre-paid, where the customer funds a credit pool upfront.

For a **postpaid commitment**, the dialog configures:

* Amount - the committed minimum, in the subscription's currency.
* Effective and expiry dates - the commitment window.
* Filters - leave empty to include all usage-based prices, or scope to a subset.
* Invoice cadence - invoice the true-up once at the end of the commitment, or on a recurring basis for prorated true-ups.
* True-up line item - include the true-up on the billing cycle's invoice, or bill it on its own invoice.
* True-up handling - whether prorated true-ups bill as standalone revenue or roll over as balance that future usage draws down.

For a **prepaid commitment**, the dialog configures:

* Currency and amount - the size of the funded pool, denominated in the settlement currency or a virtual unit like tokens.
* Per-unit cost basis - the price per credited unit. The customer is invoiced pool size × cost basis when the commitment starts.
* Effective and expiry dates - the commitment window.
* Filters - leave empty to include all usage-based prices, or scope to a subset.
* Credit granting - grant all credits upfront, or on a recurring cadence. Either way, the full amount is invoiced upfront.
* Underage handling - what happens to credits that go unused: forfeit them at the end of each grant period, roll them over until the end of the commitment, or roll them over and expire them a set number of days or months after each grant (never later than the commitment end).

To remove a commitment on a live subscription, use the subscription edit flow. What removal does depends on the commitment type, because only a prepaid commitment has already moved money.

Removing a postpaid commitment deletes it outright.

Removing a prepaid commitment cancels it as of the removal time: credits granted to-date expire, and scheduled grants are voided. If the commitment hasn't started yet, its funding charge is dropped and never bills. Otherwise the funding invoice is left as is, and the unconsumed balance is credited to the customer's balance.

## Tracking drawdown

The subscription page has a dedicated Commitments tab showing each commitment's progress alongside its date range, status, and tracked prices. Beneath the progress card sits the full ledger: every entry that minted or drew down balance, filterable by entry type and time window, with CSV export for offline reconciliation. The commitment also appears as a bar on the subscription timeline, spanning its window.

For a prepaid commitment, the ledger reports activity in the commitment's credited unit: a pool funded in tokens reports tokens. Progress also accounts for credits that left the pool without being used, whether through expiration, voids, or cancellation, so drawn down, remaining, and expired amounts sum to the original target.

## True-up invoicing

True-ups apply to postpaid commitments only. A prepaid commitment is paid in full by its funding invoice, so there's no shortfall to bill: usage beyond the pool bills as regular usage, and unused credits expire.

**Where the true-up lands.** By default, each true-up is folded into the regular invoice issued that day; when no invoice falls on that date, the true-up gets its own. A commitment can instead bill every true-up on its own standalone invoice. The amounts are identical either way, so this is a presentation choice, not a billing one.

**One-time true-up.** Orb waits until the commitment window closes and all usage within it has been invoiced, then compares cumulative drawdown to the target and bills any gap as a single true-up.

**Prorated true-ups.** With a recurring cadence, Orb prorates the commitment target across the term and trues up at each boundary so cumulative billing never falls behind the prorated pace.

What happens to a true-up after it's billed is governed by the commitment's rollover behavior:

* Without rollover: each true-up is billed as revenue and counts toward the commitment target. An amount trued up in one month is never re-billed against the commitment, but it does not offset future usage charges. Usage is always billed in full as it accrues.
* With rollover: the trued-up amount instead mints a balance scoped to the commitment's tracked prices. At each subsequent boundary, eligible usage first draws down that balance and only the remainder is billed as usage. Any residual shortfall against the prorated pace mints new balance. Whatever balance remains at term end expires as breakage.

Since the math is cumulative, invoices must be issued in order. Orb enforces this: a true-up invoice cannot finalize while an earlier usage invoice in its window is still in draft, and, for commitments with rollover, a usage invoice cannot finalize ahead of a pending true-up from an earlier boundary.

## Getting the data into your systems

**Warehouse exports.** Two tables are available through [Orb data exports](/data-exports/resource-types#commitment), each synced daily: `commitment` and `commitment_ledger_entry_event`, allowing you to store the full audit trail in your own warehouse.

**Salesforce.** Orb's [Salesforce provisioning integration](/integrations-and-exports/salesforce/salesforce-cpq) automates commitment creation from your Salesforce instance.

## Working with commitments via the Orb API

Commitments are managed through the subscription create and edit flows, and read through two dedicated endpoints. Commitment payloads reject unknown fields with a 400 (`Extra inputs are not permitted`), so a retired or misspelled field name fails loudly instead of being silently dropped.

### 1. Create a subscription with a commitment attached

Include a `commitments` list on `POST /v1/subscriptions`. This creates the commit in the same transaction as the subscription. `commit_type` is required (`postpaid` or `prepaid`), and `target_amount` is required for postpaid commits. `start_date` is inclusive and `end_date` exclusive, and both must fall on midnight in the customer's timezone; the examples below assume a UTC customer.

True-up behavior is set through the optional `true_up_configuration` object. When omitted, you get a single true-up at commitment end, folded into the regular invoice and billed as revenue.

```bash theme={null}
curl https://api.withorb.com/v1/subscriptions \
  -H "Authorization: Bearer $ORB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "CUSTOMER_ID",
    "plan_id": "PLAN_ID",
    "start_date": "2026-09-01",
    "commitments": [
      {
        "commit_type": "postpaid",
        "target_amount": "500000.00",
        "start_date": "2026-09-01T00:00:00Z",
        "end_date": "2027-09-01T00:00:00Z",
        "true_up_configuration": {
          "cadence": "one_time",
          "on_separate_invoice": true
        }
      }
    ]
  }'
```

### 2. Create a prepaid commitment

Prepaid commits describe the funded pool instead of a target: `credited_quantity` and `per_unit_cost_basis` are required, and the customer is invoiced quantity × cost basis at term start. The pool's unit is set by `credited_currency`, which accepts any pricing unit on the account (a virtual unit like tokens); when omitted, the pool is denominated in the settlement currency.

What happens to unused credits is set through the optional `expiration` object, discriminated on `expiration_type`: `end_of_commitment` (the default) expires credits when the commitment ends, `end_of_grant_period` expires each grant at the next grant boundary (requires `grant_cadence`), and `custom` expires each grant a set `duration` and `duration_unit` after it lands, capped at the commitment end.

```bash theme={null}
curl https://api.withorb.com/v1/subscriptions \
  -H "Authorization: Bearer $ORB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "CUSTOMER_ID",
    "plan_id": "PLAN_ID",
    "start_date": "2026-09-01",
    "commitments": [
      {
        "commit_type": "prepaid",
        "start_date": "2026-10-01T00:00:00Z",
        "end_date": "2027-10-01T00:00:00Z",
        "credited_quantity": "1000000",
        "credited_currency": "tokens",
        "per_unit_cost_basis": "1.00",
        "grant_cadence": "monthly",
        "expiration": { "expiration_type": "end_of_grant_period" }
      }
    ]
  }'
```

### 3. Scope a commitment to specific prices

By default only the subscription's eligible usage-based spend draws down the commit. To scope it, pass `eligible_price_filters`:

```json theme={null}
{
  "commit_type": "postpaid",
  "target_amount": "250000.00",
  "start_date": "2026-09-01T00:00:00Z",
  "end_date": "2027-09-01T00:00:00Z",
  "eligible_price_filters": [
    { "field": "item_id", "operator": "includes", "values": ["ITEM_ID_1", "ITEM_ID_2"] }
  ]
}
```

### 4. Add a commitment to an existing subscription

Use the price-intervals edit endpoint with `add_commitments`. Multiple commitments on one subscription are supported as long as their windows don't overlap; a canceled commitment doesn't count against the overlap check.

```bash theme={null}
curl https://api.withorb.com/v1/subscriptions/$SUBSCRIPTION_ID/price_intervals \
  -H "Authorization: Bearer $ORB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "add_commitments": [
      {
        "commit_type": "postpaid",
        "target_amount": "120000.00",
        "start_date": "2027-10-01T00:00:00Z",
        "end_date": "2028-10-01T00:00:00Z",
        "true_up_configuration": { "cadence": "quarterly" }
      }
    ]
  }'
```

### 5. Remove (or replace) a commitment

To change a commit, remove it and add the corrected one in a single call.

```bash theme={null}
curl https://api.withorb.com/v1/subscriptions/$SUBSCRIPTION_ID/price_intervals \
  -H "Authorization: Bearer $ORB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "remove_commitment_ids": ["COMMITMENT_ID"],
    "add_commitments": [ { "...": "corrected commitment here" } ]
  }'
```

Removal behaves differently by type. A postpaid commitment is deleted outright. A prepaid commitment is instead canceled as of the removal time; see [Configuring a commitment](#configuring-a-commitment) for what happens to its credits and funding invoice.

### 6. List commitments on a subscription

```bash theme={null}
curl "https://api.withorb.com/v1/subscriptions/$SUBSCRIPTION_ID/commitments" \
  -H "Authorization: Bearer $ORB_API_KEY"
```

This returns commitments newest-window-first. The response shape follows `commit_type`: postpaid commitments carry `true_up_configuration`, while prepaid commitments instead carry their funding configuration (`credited_quantity`, `credited_currency`, `per_unit_cost_basis`, `grant_cadence`, `expiration`). `status` is `active` or `canceled`, and `currency` is the subscription's settlement currency, in which `target_amount` and the balance figures are denominated. Live balances appear in the `balance` object, whose `remaining`, `drawn_down`, and `expired` figures sum to `target_amount`. This endpoint is the only place balances are reported: commitments embedded on the subscription resource carry configuration only.

```json theme={null}
{
  "data": [
    {
      "id": "COMMITMENT_ID",
      "customer_id": "...",
      "subscription_id": "...",
      "commit_type": "postpaid",
      "status": "active",
      "currency": "USD",
      "target_amount": "500000.00",
      "start_date": "2026-09-01T00:00:00+00:00",
      "end_date": "2027-09-01T00:00:00+00:00",
      "drawdown_basis": "post_prepaid",
      "commitment_price_id": "PRICE_ID",
      "true_up_configuration": {
        "cadence": "one_time",
        "on_separate_invoice": true,
        "creates_credit_block": false
      },
      "eligible_price_filters": [
        { "field": "price_type", "operator": "includes", "values": ["usage"] }
      ],
      "balance": {
        "remaining": "342100.50",
        "drawn_down": "157899.50",
        "expired": "0.00"
      }
    }
  ],
  "pagination_metadata": { "has_more": false, "next_cursor": null }
}
```

### 7. Fetch the commitment ledger

Every drawdown against the commit is a ledger entry. The result is cursor-paginated, newest first, with optional time-window filters:

```bash theme={null}
curl -g "https://api.withorb.com/v1/subscriptions/$SUBSCRIPTION_ID/commitments/$COMMITMENT_ID/ledger?limit=100&operation_timestamp[gte]=2026-09-01T00:00:00Z&operation_timestamp[lt]=2026-10-01T00:00:00Z" \
  -H "Authorization: Bearer $ORB_API_KEY"
```

For a postpaid commitment, entries are denominated in the settlement currency and the only entry type is `decrement`. For a prepaid commitment, the ledger reports the funded pool's credit activity in the credited unit, using the credit ledger's entry types (increments, decrements, expirations, voids, and amendments).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.