MPP (Machine Payments Protocol)
MPP (the Machine Payments Protocol) carries pay-per-request payments through HTTP's standard authentication headers: a 402 challenges with WWW-Authenticate: Payment, the client answers with an Authorization: Payment credential, and the settled response returns a signed Payment-Receipt. Its evm method settles USDC by EIP-3009; its tempo method settles natively on Tempo.
Payment as an HTTP auth scheme
The web already has a way for a server to say "you need to present something before I answer": the WWW-Authenticate and Authorization headers defined in RFC 9110, the mechanism behind login prompts. MPP adds a scheme to it called Payment. A server challenges with WWW-Authenticate: Payment, the client answers with Authorization: Payment, and a successful answer carries a signed Payment-Receipt.
MPP and x402 express the same idea in different headers. A server can speak both on one route at one price, and every paid route on this server does.
Anatomy of a challenge
This is the challenge this server sends for POST /api/hash:
WWW-Authenticate: Payment id="8w5V62E37kA2OiliORKf6BFEX56u4_eomTkyMpYJDeY",
realm="agent402.tools", method="evm", intent="charge",
request="eyJhbW91bnQiOiIxMDAwIi...", expires="2026-09-24T12:41:07.520Z",
opaque="eyJ4NDAyIjoie1wic2NoZW1l..."
method: how the payment settles.evmis an EIP-3009 USDC authorization;tempois a native transfer on the Tempo chain.intent:chargeis a one-off payment for this request.request: base64url JSON with the amount, currency, recipient and chain.id: a signed binding, so the server can check it minted this challenge.expires: after this time the challenge is no longer accepted.
// base64url-decoded "request" parameter of the challenge above
{
"amount": "1000",
"currency": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"methodDetails": { "chainId": 8453, "credentialTypes": ["authorization"], "decimals": 6 },
"recipient": "0xPAYTO..."
}
Paying it
The mppx client wraps fetch and pays whichever method it has configured. With both methods listed it can pay on Tempo or on an EVM chain from the same key.
import { Fetch, evm, tempo } from "mppx/client";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.AGENT_KEY);
const mppFetch = Fetch.from({ methods: [tempo.charge({ account }), evm.charge({ account })] });
const res = await mppFetch("https://agent402.tools/api/hash", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text: "hello world" }),
});
console.log(res.headers.get("payment-receipt")); // signed receipt on success
When a credential is refused
A refused credential is answered with a 402, fresh challenges and an application/problem+json body in the RFC 9457 shape: a type URL naming the reason (for example verification-failed or payment-insufficient), a title and a detail sentence. Nothing is charged, and the client can retry with the new challenge.
Related
- What is MPP? (the full explainer)
- x402 and MPP on one route
- Sellers on the MPP wire
- agent402-client over MPP
- MPP over MCP
- Glossary entry
More explainers: x402 · HTTP 402 Payment Required · Agent payments · Pay-per-call API · MCP payments