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 API endpoints are available through both protocols. 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
Swap execution chainsAny EVM chain supported by Swap APIAny EVM chain supported by Swap API
Standardx402.orgmpp.dev

Prefer the command line? The 0x CLI implements both rails natively — run 0x price/0x swap with --pay x402-evm or --pay mpp to pay per request from a funded wallet, no API key and no code. It enforces a --max-payment cap before signing.

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

URL
Pricehttps://agent.api.0x.org/v1/x402/swap-allowance-holder-price/
Quotehttps://agent.api.0x.org/v1/x402/swap-allowance-holder-quote/

The same URLs are used regardless of payment network. The payment scheme your client registers (EVM or Solana) determines which chain the payment runs on. The swap execution chain is controlled by the chainId query parameter.

Cost

Payment 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" + // Base — any EVM chain supported by 0x Swap API works here
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(
31 `${BASE}/swap-allowance-holder-price/${params}`,
32);
33const price = await priceRes.json();
34
35// Quote — firm quote with transaction calldata
36const quoteRes = await x402Fetch(
37 `${BASE}/swap-allowance-holder-quote/${params}&taker=${account.address}`,
38);
39const 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(
3 "utf8",
4 ),
5);
6
7console.log(settlement.success); // true
8console.log(settlement.transaction); // on-chain tx hash
9console.log(settlement.network); // e.g. "eip155:8453" or "solana:5eykt4..."
10console.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). The chainId parameter controls which EVM chain the swap executes on — check valid chains in the Supported Chains list.

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", // Base — any EVM chain supported by 0x Swap API works here
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(
27 `${BASE_URL}/swap-allowance-holder-price/?${params}`,
28);
29const price = await priceRes.json();
30
31// Quote — add taker address for firm quote with calldata
32params.set("taker", account.address);
33const quoteRes = await mppx.fetch(
34 `${BASE_URL}/swap-allowance-holder-quote/?${params}`,
35);
36const quote = await quoteRes.json();
37
38console.log(quote.transaction.to); // AllowanceHolder contract
39console.log(quote.transaction.data); // calldata to submit

Tempo Mainnet (chainId 4217) is the payment network — USDC.e on Tempo pays for API access. The swap itself executes on the EVM chain you specify via chainId. Any chain listed in Supported Chains is valid.


Next steps