Autonomous Agent Payments

View as Markdown

AI agents need to call APIs autonomously — without human-managed API keys, billing accounts, or pre-authorized subscriptions. Two open standards, x402 and MPP (Machine Payments Protocol), solve this by embedding micropayments directly into HTTP requests.

0x swap endpoints are available through both protocols via the Alchemy AgentPay proxy. Agents pay $0.01 per request in USDC. No 0x API key required — payment is the authentication.

x402MPP
Payment networkBase or SolanaTempo Mainnet
Payment tokenUSDCUSDC.e
Wallet typeEVM or SolanaEVM
Standardx402.orgmpp.dev

Using an AI coding agent?

Install the 0x-agentic-gateway skill. Your agent will handle protocol selection, package installation, wallet setup, and code generation automatically.

$npx skills add 0xProject/0x-ai

Then activate it in your agent session:

/0x-agentic-gateway

Manual integration

The sections below cover endpoints, wallet requirements, and working code examples for both protocols.

How it works

Both protocols follow the same HTTP-native pattern:

1

Agent makes a request

The agent calls a 0x swap endpoint with no credentials.

2

Server returns 402

The proxy responds with 402 Payment Required and machine-readable payment requirements (amount, network, recipient).

3

Agent signs and pays

The agent signs a USDC payment using its wallet and retries the request with a PAYMENT-SIGNATURE (x402) or Authorization: Payment (MPP) header.

4

Server verifies and responds

The proxy verifies the on-chain payment, forwards the request to 0x, and returns the swap data. The response includes a transaction hash for the payment.

Every payment includes the agent’s wallet address and an on-chain transaction hash in the PAYMENT-RESPONSE header — giving cryptographically verifiable per-caller attribution without API key management.


x402

x402 is an open standard that repurposes the HTTP 402 Payment Required status code for real-time stablecoin payments. Agents sign a USDC EIP-3009 transferWithAuthorization payload (EVM) or a Solana USDC transfer transaction (SVM), then retry the request with the encoded signature.

Endpoints

NetworkPriceQuote
Base (mainnet)https://agent.api.0x.org/v1/x402/swap-allowance-holder-price/https://agent.api.0x.org/v1/x402/swap-allowance-holder-quote/
Solana (mainnet)https://agent.api.0x.org/v1/x402/swap-allowance-holder-price/https://agent.api.0x.org/v1/x402/swap-allowance-holder-quote/

Both networks share the same URLs. The payment scheme your client registers determines which chain the payment runs on.

Cost

NetworkCurrencyPrice per request
Base (mainnet)USDC$0.01
Solana (mainnet)USDC$0.01

Wallet requirement: EVM wallet funded with USDC on Base (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913), or a Solana wallet funded with USDC on Solana mainnet (EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v). When paying via Solana, an EVM wallet is also required — swap execution runs on EVM, so the taker in the quote must be an EVM address.

Get a swap price and quote

1import { createPublicClient, http } from "viem";
2import { base } from "viem/chains";
3import { privateKeyToAccount } from "viem/accounts";
4import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
5import { ExactEvmScheme, toClientEvmSigner } from "@x402/evm";
6
7const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY);
8const publicClient = createPublicClient({ chain: base, transport: http() });
9
10const signer = toClientEvmSigner(account, publicClient);
11const core = new x402Client();
12
13core.register("eip155:8453", new ExactEvmScheme(signer));
14
15// Refuse to sign any payment over $0.02
16core.registerPolicy((_version, requirements) =>
17 requirements.filter((r) => BigInt(r.amount) <= 20_000n),
18);
19
20const x402Fetch = wrapFetchWithPayment(fetch, core);
21
22const BASE = "https://agent.api.0x.org/v1/x402";
23const params =
24 "?chainId=8453" +
25 "&sellToken=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" + // USDC on Base
26 "&buyToken=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" + // ETH
27 "&sellAmount=100000"; // 0.1 USDC
28
29// Price — indicative, no taker required
30const priceRes = await x402Fetch(`${BASE}/swap-allowance-holder-price/${params}`);
31const price = await priceRes.json();
32
33// Quote — firm quote with transaction calldata
34const quoteRes = await x402Fetch(
35 `${BASE}/swap-allowance-holder-quote/${params}&taker=${account.address}`,
36);
37const quote = await quoteRes.json();

Reading the payment response

After a successful request, the PAYMENT-RESPONSE header contains base64-encoded settlement data:

1const settlement = JSON.parse(
2 Buffer.from(priceRes.headers.get("PAYMENT-RESPONSE"), "base64").toString("utf8"),
3);
4
5console.log(settlement.success); // true
6console.log(settlement.transaction); // on-chain tx hash
7console.log(settlement.network); // e.g. "eip155:8453" or "solana:5eykt4..."
8console.log(settlement.payer); // agent's wallet address

The 0x API key is managed server-side — do not pass it from the client.


MPP

MPP (Machine Payments Protocol) is an open standard for machine-to-machine HTTP payments. It uses an extensible challenge–credential–receipt pattern: the server issues a WWW-Authenticate challenge, the client returns a credential (payment proof), and the server confirms with a receipt.

0x MPP endpoints use Tempo Mainnet (chainId 4217) as the payment rail, settled in USDC.e.

Endpoints

EndpointDescription
https://agent.api.0x.org/v1/mpp-tempo/swap-allowance-holder-price/Indicative price — no taker required
https://agent.api.0x.org/v1/mpp-tempo/swap-allowance-holder-quote/Firm quote with transaction calldata

Both endpoints proxy the 0x Swap API v2 (AllowanceHolder flow) on Base.

Cost

NetworkCurrencyPrice per request
Tempo MainnetUSDC.e$0.01

Wallet requirement: EVM wallet funded with USDC.e on Tempo Mainnet (0x20C000000000000000000000b9537d11c60E8b50).

Get a swap price and quote

1import "dotenv/config";
2import { Mppx, tempo } from "mppx/client";
3import { privateKeyToAccount } from "viem/accounts";
4
5const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
6
7const mppx = Mppx.create({
8 methods: [
9 tempo.charge({
10 account,
11 mode: "push", // client broadcasts the tx and sends the hash to the proxy
12 }),
13 ],
14});
15
16const BASE_URL = "https://agent.api.0x.org/v1/mpp-tempo";
17
18const params = new URLSearchParams({
19 chainId: "8453",
20 sellToken: "0x4200000000000000000000000000000000000006", // WETH on Base
21 buyToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
22 sellAmount: "1000000000000000", // 0.001 WETH
23});
24
25// Price — indicative, no taker required
26const priceRes = await mppx.fetch(`${BASE_URL}/swap-allowance-holder-price/?${params}`);
27const price = await priceRes.json();
28
29// Quote — add taker address for firm quote with calldata
30params.set("taker", account.address);
31const quoteRes = await mppx.fetch(`${BASE_URL}/swap-allowance-holder-quote/?${params}`);
32const quote = await quoteRes.json();
33
34console.log(quote.transaction.to); // AllowanceHolder contract
35console.log(quote.transaction.data); // calldata to submit

Tempo Mainnet (chainId 4217) is the payment network. Swap execution always runs on Base (chainId 8453) — USDC.e on Tempo pays for API access; the swap itself settles on Base.


Next steps