MPP Paid API
Gate API endpoints with HTTP 402 micropayments using the Machine Payments Protocol (MPP).
Overview
@cron/x402-api uses mppx (Tempo's Machine Payments Protocol) to gate API endpoints behind HTTP 402 micropayments. MPP supports both per-request charges and sessions for high-frequency agent queries. MPP is an IETF standards-track protocol.
Quick start
bash
cd packages/x402-api
cp .env.example .envEdit .env:
bash
MPP_SECRET_KEY=0x... # Server signing key for MPP
PAYMENT_ADDRESS=0x... # Your wallet — receives micropayments
CHAIN=base
CRON_REGISTRY_ADDRESS=0x...
PRICE_PLANS=0.01 # Per-request charge for /api/plans
PRICE_CHARGEABLE=0.02 # Session price for /api/chargeable
PRICE_PLANS_STREAM=0.005 # Session price for /api/plans/stream
PORT=4020bash
npm run startEndpoints
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /health | None (free) | Service health check |
| GET | /api/plans | Charge $0.01 | List all active plans on-chain |
| POST | /api/chargeable | Session $0.02 | Filter subscriber-planId tuples by chargeability |
| GET | /api/plans/stream | Session $0.005/plan | Stream plan data via SSE |
Calling from an AI agent
typescript
import { Mppx, tempo } from "mppx/client";
import { privateKeyToAccount } from "viem/accounts";
const mppx = Mppx.create({
methods: [tempo({ account: privateKeyToAccount(process.env.AGENT_KEY!) })],
});
// fetch automatically handles 402 challenges
const res = await fetch("https://api.cronprotocol.xyz/api/plans");
const plans = await res.json();Using CronAgent with MPP
typescript
import { CronAgent } from "@cron/sdk";
const agent = new CronAgent({
chain: "base",
privateKey: process.env.AGENT_KEY!,
mpp: {
apiBaseUrl: "https://api.cronprotocol.xyz",
maxSessionDeposit: "5",
},
});
const plans = await agent.searchPlansViaApi();Sessions vs Charges
MPP supports two payment modes depending on the endpoint's access pattern:
| Mode | How it works | Best for |
|---|---|---|
| One-time charge | Client pays per request. Each call settles independently. | Low-frequency reads, simple queries |
| Session | Client opens a session with a deposit. Subsequent requests use signed vouchers — no per-request blockchain transactions. | High-frequency agent queries, streaming, real-time data |
Adding custom paid routes
Use mppx.charge() and mppx.session() Express middleware to add your own paid endpoints:
typescript
import { mppx } from "mppx";
// Per-request charge — $0.05
app.get(
"/api/premium-data",
mppx.charge({ amount: "0.05", asset: "USDC" }),
async (req, res) => {
const data = await fetchPremiumData();
res.json(data);
}
);
// Session-based — $0.01 per use within session
app.post(
"/api/agent-query",
mppx.session({ amount: "0.01", asset: "USDC" }),
async (req, res) => {
const result = await runQuery(req.body);
res.json(result);
}
);Testing
bash
npx mppx http://localhost:4020/api/plans[i] Backwards compatible with x402
MPP is backwards-compatible with x402 — MPP clients can consume x402 services. If you are migrating from Coinbase x402, no client-side changes are required for existing integrations.