MPP
Pay for AgentMail per request from your agent's wallet, with no API key.
MPP (Machine Payments Protocol) is an open standard from Stripe and Tempo that lets machines pay for HTTP requests. Over MPP, your agent buys each AgentMail call with a signed payment from its own wallet, so it needs no API key and no plan. If you have an API key, follow the Quickstart instead. If your agent’s wallet is on a chain like Base or Solana, use x402.
On this page, your agent buys its own @agentmail.to inbox with its wallet and starts watching it for new email.
0. Fund a Tempo account
AgentMail charges MPP requests in USDC.e, a bridged form of USDC, on the Tempo blockchain. You need:
- Node.js
- An EVM private key you control
- A USDC.e balance on Tempo, held by that key’s address
Tempo’s funding guide shows how: onramp with fiat through Tempo Wallet, or bridge from another chain. USDC bridged over Stargate appears on Tempo as USDC.e.
A few dollars covers this walkthrough. The inbox you create in step 2 costs $2.00, and every other request on this page is free.
1. Create a paying client
Install the AgentMail SDK, the MPP client, and viem:
npm install agentmail mppx viemPut your private key in an environment variable, wrap it in an MPP client, and hand that client to the SDK. Then make a free call to check that the payment loop works end to end.
import { privateKeyToAccount } from "viem/accounts";
import { Mppx, tempo } from "mppx/client";
import { AgentMailClient } from "agentmail";
const account = privateKeyToAccount(process.env.TEMPO_PRIVATE_KEY as `0x${string}`);
const mppx = Mppx.create({ methods: [tempo({ account })] });
const client = new AgentMailClient({ mppx });
const inboxes = await client.inboxes.list();
console.log(inboxes.count);When you pass mppx, the SDK sends API requests to https://mpp.api.agentmail.to and WebSocket connections to wss://mpp.ws.agentmail.to. The paths, methods, and responses are the same as the regular API. Only the host and the authentication change.
A count in the output (0 on a fresh wallet) means the client completed a full challenge and credential exchange with AgentMail.
2. Test creating an inbox with a paid request
The create is the one paid call in this walkthrough, and it costs $2.00 from your wallet.
const inbox = await client.inboxes.create({ displayName: "Support agent" });
console.log(inbox.inboxId);A returned inboxId means the payment settled and the inbox exists:
{
"organization_id": "1a2b3c4d-5e6f-4a1b-8c2d-3e4f5a6b7c8d",
"pod_id": "1a2b3c4d-5e6f-4a1b-8c2d-3e4f5a6b7c8d",
"inbox_id": "faircost773@agentmail.to",
"email": "faircost773@agentmail.to",
"display_name": "Support agent",
"created_at": "2026-08-25T11:00:52Z",
"updated_at": "2026-08-25T11:00:52Z"
}That call ran MPP’s challenge and credential loop. AgentMail answered the first attempt with a 402 carrying a WWW-Authenticate: Payment header, whose base64 request parameter decodes to the payment terms:
{
"amount": "2000000",
"currency": "0x20C000000000000000000000b9537d11c60E8b50",
"methodDetails": { "chainId": 4217 },
"recipient": "0x6e3184C204e596dED89E8A5693B602097F4Ab687"
}amount is the price in the currency’s 6-decimal units, so 2000000 is $2.00. currency is the USDC.e token address on Tempo (chain id 4217), and recipient is AgentMail’s wallet. The mppx client signed a payment matching these terms and retried the request with the credential attached. Each request gets its own challenge, which expires five minutes after it is issued. You only handle a challenge yourself if you call the API without the SDK.
The inbox belongs to the wallet that paid for it, so run your agent with the same key everywhere and it sees the same inboxes.
To pick the address yourself, pass a username (the part before @agentmail.to). Omit username and AgentMail generates one.
3. Test receiving events over the WebSocket
Subscribe to your new inbox, then send it an email from whatever mailbox you already use.
You should see a Subscribed to line as soon as the socket is ready, and a New email from line moments after your email arrives.
const socket = await client.websockets.connect();
socket.on("message", (event) => {
if (event.type === "subscribed") {
console.log("Subscribed to", event.inboxIds);
} else if (event.type === "event" && event.eventType === "message.received") {
console.log("New email from", event.message.from);
}
});
socket.sendSubscribe({ type: "subscribe", inboxIds: [inbox.inboxId] });Connecting is free. The SDK completes the same challenge and credential exchange before the socket opens, so the connection is tied to your wallet like every other request.
4. Know what each request costs
The price of a request is the amount in its challenge. Your client reads it before it pays, and it pays exactly what the challenge asks.
| Request | Price |
|---|---|
| Create an inbox | $2.00 |
| Send an email (send, reply, forward, or send a draft) | $0.01 |
| Create a draft, webhook, pod, or inbound-control entry | $0.01 |
| Add a custom domain | $10.00 |
| Everything else, including reads and WebSocket connections | Free |
Free requests run the same challenge and credential loop with an amount of 0. That zero-amount credential is still signed by your wallet, and the signature is how AgentMail knows which wallet is calling.