MPP metered payment sessions
When a buyer agent consumes your agent services call after call, authorizing each checkout separately is the wrong shape: a checkout is discrete, tool calls stream. A metered agent-payment session (MPP session) is the per-call shape: the buyer pre-authorizes a spend envelope once — a spend cap, a per-call ceiling, and a required expiry — and every call the seller agent makes from then on is metered against that envelope and settled as a micropayment over x402. This page explains the model; the endpoint surface lives in the Commerce API reference.Where MPP sits
Orbit ships three payment primitives for agent-driven commerce, and each answers a different question:- One-shot checkout — the commerce checkout spine prices a cart and captures one payment on whichever rail wins. One checkout, one charge.
- Federated authorization — the agentic commerce model lets a principal issue an AP2-style mandate a buyer agent presents across a federation boundary, with W3C verifiable-credential shapes for cross-network counterparts.
- Metered sessions — this page. No cart, no checkout: a standing spend envelope that many calls draw down, each settled as its own micropayment.
The session model
Open a session withPOST /commerce/mpp-session:
spendCap and maxPerCall must both be positive, and maxPerCall
may not exceed spendCap. expiresAt is a future epoch-ms timestamp and it
is required: unlike a checkout mandate, a streaming pre-authorization is
always bounded in time.
The response is a session snapshot, and storage is yours. Orbit does not
persist the session for you — you round-trip the snapshot in the body of
every later /meter, /call, /revoke, and /verify request, exactly as
you round-trip the cart snapshot on the checkout spine. Round-tripping is
safe because the snapshot carries a SHA-256 consent digest over its
immutable scope: the id, the agent, the principal, both caps, the currency,
the expiry, and the creation time. Every meter decision recomputes that
digest before anything else, so a snapshot whose cap or expiry was altered
after open fails integrity and is declined; the server re-verifies the
consent on every call and never trusts the client’s copy of a cap. Only
spent, callCount, status, and the timestamps advance. A session is
single-currency: price each call in the session’s currency before metering
it.
A session holds exactly one of four statuses:
Terminal means terminal: once a session leaves
active, no later call
meters under it.
POST /commerce/mpp-session/meter is the dry-run: it evaluates one call
against the snapshot — integrity, then status, expiry, amount, per-call
ceiling, cumulative cap, in that order — and returns the decision without
advancing spend. The decision carries a deterministic meter id
(<sessionId>-call-<n>), so a dry-run and the committing call line up one
to one in your audit trail.
Settlement flow
POST /commerce/mpp-session/call meters and settles one call. When x402
settlement is not enabled for the deployment, the route answers 503
MPP_SETTLEMENT_NOT_ENABLED and touches nothing — the settlement surface
stays dark until it is switched on.
When it is on, an authorized call rides the standard x402 two-step:
- Challenge. A
/callwithout anX-PAYMENTheader answers 402 with the payment requirements for this one call: the scheme, the network, the settlement asset, the amount in the asset’s atomic units, and the payee. The challenge isCache-Control: no-store. - Verify, then settle. The client retries with a signed
X-PAYMENTpayload. The facilitator verifies it against the requirements; a missing, malformed, or invalid payment is re-challenged with a fresh 402. Only a verified payment is settled, and only once settlement reports success is the spend committed to the session.
spent advances only after
settlement succeeds. If a payment verifies but settlement fails — a rail
outage, a reverted transaction — the call returns with the failed
settlement and the session’s headroom is untouched. A facilitator failure
never burns cap against money that did not move. On success the response
carries the committed session, the meter decision, and the on-chain
receipt: the network the payment settled on and the transaction hash.
Session bookkeeping runs in major units; the x402 wire amount runs in the
settlement asset’s own atomic units — for example USDC’s six-decimal base
units on Base. You supply the atomic amount per call; Orbit never assumes
an asset’s decimal count.
A declined call never reaches settlement. When the meter declines a call —
over the per-call ceiling, over the remaining cap, expired, revoked, or
tampered — /call answers 200 with authorized: false, the decline reason,
and settlement: null. No 402 is shaped for money the session did not
authorize.
The money-safety model
Four controls bound every session, all fixed at open and all yours to set:- Spend cap. Cumulative
spentcan never crossspendCap; a call that would cross it declines withexceeds_session_cap, and reaching it flips the session toexhausted. - Per-call ceiling. A single call above
maxPerCalldeclines withexceeds_per_call_cap, however much headroom remains. - Expiry.
expiresAtis mandatory at open, and once the clock passes it every call declines withexpired, even while the stored status still readsactive. - Revocation.
POST /commerce/mpp-session/revokeflips the session torevokedimmediately and terminally; revoking an already-revoked session is an error, not a silent no-op.
spendCap or
pushing expiresAt in a stored snapshot authorizes nothing — the call
declines with integrity_failed.
Reconcile against your own ledger. spent and callCount advance only on
settled calls, and each settlement carries a transaction hash, so the
session’s counters match your own record of on-chain receipts line for
line; POST /commerce/mpp-session/verify recomputes a snapshot’s digest
for your auditors.
Worked example
Open a five-dollar session with a ten-cent per-call ceiling, expiring in an hour (theexpiresAt value is epoch-ms). The open response is the snapshot
to store: spent 0, callCount 0, status "active", plus the consent
digest.
Stream three calls — $0.02, $0.03, $0.04 — each through the 402 →
X-PAYMENT round trip above. All three settle and commit: spent advances
0.02 → 0.05 → 0.09, callCount reaches 3, and remainingCap reports 4.98,
4.95, then 4.91.
Now a $0.25 call. It is inside the remaining cap but above the per-call
ceiling, so /call declines it without shaping a settlement:
revoked with revokedAt set; every later call declines with reason
revoked whatever the headroom.
See also
- Agentic commerce authorization and checkout model — the mandate plane MPP sessions complement.
- Commerce checkout spine — the one-cart checkout a metered session deliberately is not.
- A2A federation model — the federation boundary buyer and seller agents meet at.
- Commerce API reference — the endpoint surface for open, meter, call, revoke, and verify.