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 .env

Edit .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=4020
bash
npm run start

Endpoints

MethodPathAuthDescription
GET/healthNone (free)Service health check
GET/api/plansCharge $0.01List all active plans on-chain
POST/api/chargeableSession $0.02Filter subscriber-planId tuples by chargeability
GET/api/plans/streamSession $0.005/planStream 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:

ModeHow it worksBest for
One-time chargeClient pays per request. Each call settles independently.Low-frequency reads, simple queries
SessionClient 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.