MPP
The Machine Payments Protocol on Tenzro: HTTP 402 challenges, signed credentials, receipts and capped sessions for streams of machine payments.
MPP, the Machine Payments Protocol, is an open protocol for machine-to-machine payments over HTTP. Like x402 it uses 402 Payment Required, but it is built around a session: a buyer opens a capped session once and then pays for many calls against it. That suits the way agents actually use services, such as a long conversation with a model, a stream of tool calls or a batch of storage writes.
On Tenzro Network, MPP is served by every node alongside x402, and it settles on the Tenzro ledger in TNZO or in stablecoins.
Challenge, credential, receipt
MPP has three messages:
| Message | Sent by | Carries |
|---|---|---|
| Challenge | The server, in the 402 response | Resource, amount, asset, payee, expiry and a challenge id |
| Credential | The client, on retry | The challenge id, the payer's identity and a signature from the paying account |
| Receipt | The server, with the response | Receipt id, amount settled and the settlement transaction |
The node checks that the credential answers a challenge it issued for this resource and payee, that the signature comes from the account being debited, and that the payer's delegation scope allows the payment. It then settles and returns the receipt. A receipt is issued only once the settlement has landed in a finalised block.
Sessions
A session lets a buyer authorise a spending cap once and then consume it call by call. On Tenzro a session runs over a payment channel, and its challenge carries intent session and the channel's escrow id:
- The buyer funds an escrow to the payee up to a cap and opens a channel over it.
- Each later call is paid with the buyer's next cumulative voucher. The node meters each call, for example by tokens generated or bytes written, and the voucher covers the running total.
- When the channel closes, the highest voucher is claimed on-chain and the rest of the escrow returns to the buyer when it expires.
# Fund the cap and open the channel (the escrow id is the channel id)
tenzro escrow create --payee <payee-address> --amount 500000 --expires-at <unix-ms> --rpc https://rpc.tenzro.com
tenzro escrow open-channel --channel-id <escrow-id> --rpc https://rpc.tenzro.com
# Pay a call: the channel's new cumulative total and what this call adds
tenzro escrow voucher <escrow-id> --cumulative 20000 --charge 20000 --rpc https://rpc.tenzro.com
# Close it, signed by the payer
tenzro escrow close-channel <escrow-id> --rpc https://rpc.tenzro.comSessions are the natural fit for metered, per-use settlement, which is the default for Machine Economy services. The cap is bounded by the payer's spending limits, so an agent can never open a session larger than its delegation allows.
List the channels you have funded with tenzro escrow by-payer --payer <address> (JSON-RPC tenzro_listEscrowsByPayer).
Paying with MPP
The payer answers a challenge with a credential it signs on its own device. From TypeScript, with npm install tenzro-sdk (and @tenzro/device-key for the hardware key):
import { HardwareKeySigner, TenzroClient, openHardwareSigner, type PaymentChallenge } from "tenzro-sdk";
import { web } from "tenzro-sdk";
const client = new TenzroClient({ endpoint: "https://rpc.tenzro.com" });
const signer = openHardwareSigner({ label: "tenzro/wallet" });
if (!(signer instanceof HardwareKeySigner)) throw new Error("no TPM or Secure Enclave on this machine");
// The challenge from the resource's 402 answer, or one a payee created with
// client.payment.createChallenge(resource, amount, asset, "mpp").
declare const challenge: PaymentChallenge;
const credential = await web.signChallengeCredential(challenge, signer, "did:tenzro:human:<you>", 100_000n);
// The payee checks it without settling: `verified`, the amount and the account
// it would debit, or the `reason` it would not pay.
const check = await client.payment.verifyPayment({ credential });
console.log(check);A ceiling above the challenge amount makes a metered credential. The credential must be signed by the paying account. Reading a settled payment's record (tenzro_getPayment, tenzro payment record) is open.
Charging with MPP
If you serve a resource, issue a challenge for it. The amount is in the asset's smallest unit:
tenzro payment challenge /tenzro/forecasts \
--protocol mpp \
--amount 250000 \
--asset TNZO \
--recipient <your-address> \
--rpc https://rpc.tenzro.comThe node returns a challenge id and a 402 body for your client. Paid routes on a Tenzro node, such as the OpenAI-compatible APIs, issue MPP and x402 challenges automatically when a request arrives without a credential.
Assets and settlement
MPP payments can be made in TNZO or in stablecoins. Stablecoin payments come from wallets provisioned through Bridge.xyz and settle on the Tenzro ledger, with TNZO paying the network fees underneath. The payer can also pay those fees in the same stablecoin. See Stablecoin payments.
Useful methods
| Method | Class | Purpose |
|---|---|---|
tenzro_createPaymentChallenge | Open | Issue a challenge for a resource (protocol mpp; intent charge or session) |
tenzro_verifyPayment | Open | Check a credential without settling |
tenzro_openPaymentChannel | Open | Open a session's channel over an escrow the payer funded |
tenzro_updatePaymentChannel | Owner | Pay a call on the channel with the payer's next voucher |
tenzro_closePaymentChannel | Owner | Close the channel and claim the highest voucher |
tenzro_getPayment | Open | Read one payment's consensus record |
tenzro_listPayments | Open | List payment records by payee, payer, agent or asset |
See Payments for identity binding and spending limits, and x402 for the stateless alternative.