x402 lets HTTP APIs charge micropayments on-chain. Agent Kit exposes discovery and payment tools over MCP so your LLM can find services, pay for them, and read responses — using the agent’s server wallet and stored access key.

Tools involved

ToolRole in x402 flow
discover_servicesSearch the x402 service catalog (query, network, max price)
get_serviceResolve one service by resource URL before calling
paid_fetchHTTP request; handles 402 → pay → retry
get_token_priceFixed-price MCP tool (internal x402, ~$0.001)
transfer and wallet read tools are separate — used for moving funds, not for paying x402 merchants.

High-level flow

Step 1 — Discover payable services

Call discover_services to search the service catalog Agent Kit exposes for x402 merchants. Pass a semantic query and optional filters:
{
  "agent_id": "AGENT_UUID",
  "query": "token price oracle",
  "network": "eip155:84532",
  "maxUsdPrice": "0.10",
  "limit": 5
}
The response includes a catalog summary and services[] entries (each with service_id as the resource URL, accepts, paymentsProtocolConfig, and metadata). Pick a service_id or endpoint URL for the next step. Optionally confirm details with get_service:
{
  "agent_id": "AGENT_UUID",
  "resource": "https://merchant.example.com/api/v1/..."
}

Step 2 — Probe with paid_fetch

First call without paymentPayload:
{
  "name": "paid_fetch",
  "arguments": {
    "agent_id": "AGENT_UUID",
    "url": "https://merchant.example.com/api/v1/data",
    "method": "GET"
  }
}
If the origin requires payment, MCP returns payment required (JSON-RPC error -32402 or a paymentRequired object) including:
  • x402Version
  • accepts[] (network, asset, payTo, amount)
  • resource metadata
Your integration must not treat this as a hard failure — it is the signal to sign and retry.

Step 3 — Sign paymentPayload on your backend

Payments must be signed with the agent’s server wallet access key (from createAgent). Never do this in the browser. The sample backend API implements this in AgentSigningService.createX402PaymentPayloadForAgent:
  1. Load agent row with encrypted accessKey.
  2. Decrypt with ENCRYPTION_KEY.
  3. AgentKitClient.getServerSigner().authenticate({ userIdentity, accessKey }).
  4. Build viem public client for the chain in accepts[0].network.
  5. Sign EIP-712 typed data required by x402 v2.
  6. Return PaymentPayload for MCP retry.
Conceptually:
import { AgentKitClient } from '@abstraxn/agent-kit';
import { x402Client } from '@x402/core/client';
import { registerExactEvmScheme } from '@x402/evm/exact/client';

// After paid_fetch returns paymentRequired:
const paymentPayload = await agentSigningService.createX402PaymentPayloadForAgent(
  localAgentId,
  paymentRequired,
);
Fund the agent’s EVM address with native gas on the payment network before first x402 payment.

Step 4 — Retry paid_fetch with payment

Pass paymentPayload at the top level of tools/call params (same level as name / arguments):
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "paid_fetch",
    "arguments": {
      "agent_id": "AGENT_UUID",
      "url": "https://merchant.example.com/api/v1/data",
      "method": "GET"
    },
    "paymentPayload": { }
  }
}
On success, paid_fetch returns fields such as:
FieldMeaning
status / okHTTP outcome
dataResponse body from the merchant
payment_madeWhether x402 settlement ran
payment_detailsSettlement summary
hintHuman-readable guidance on failure

Fixed-price MCP tools (get_token_price)

Tools with a listed price in the dashboard (e.g. $0.001 for get_token_price) use Agent Kit’s internal x402 facilitator:
  1. First tools/callpaymentRequired with accepts built by Agent Kit.
  2. Backend signs paymentPayload (same access key flow).
  3. Retry with paymentPayload.
  4. Spend policy may block the call if the agent exceeded budgetUsd (SDK updateSpendPolicy).
paid_fetch to third-party URLs does not use the same spend-policy price table — filter expensive services in discover_services (maxUsdPrice).

MCP client example (NestJS)

From the sample backend’s McpClientService:
// Optional paymentPayload for x402 retries
const rpcParams: Record<string, unknown> = {
  name: 'paid_fetch',
  arguments: { agent_id, url, method: 'GET' },
};
if (paymentPayload) {
  rpcParams.paymentPayload = paymentPayload;
}

const response = await fetch(process.env.MCP_SERVER_URL!, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: process.env.MCP_SERVER_AUTH_TOKEN!,
  },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: Date.now(),
    method: 'tools/call',
    params: rpcParams,
  }),
});
Handle error.code === -32402 by signing and retrying once.

Facilitator (verify / settle)

Hosted facilitators process payment verification and on-chain settlement.
TierURLWhen usedAuth
Testnethttps://x402.org/facilitatorGateway: /v1/x402-testnet/…. Agent Kit: X402_NETWORK is Base Sepolia, Solana Devnet, etc.None
Mainnethttps://api.cdp.coinbase.com/platform/v2/x402Gateway: /v1/x402-mainnet/…. Agent Kit: X402_NETWORK is Base, Polygon, etc.CDP_API_KEY_ID + CDP_API_KEY_SECRET
Both services pick the facilitator automatically — you do not set a single X402_FACILITATOR_URL for everything. Set CDP_API_KEY_* on the gateway and Agent Kit hosts so mainnet settle/verify works.

Environment (Agent Kit host)

VariablePurpose
X402_TESTNET_FACILITATOR_URLTestnet facilitator (default https://x402.org/facilitator)
CDP_API_KEY_ID / CDP_API_KEY_SECRETRequired for mainnet verify/settle (gateway x402-mainnet + mainnet X402_NETWORK)
X402_NETWORKDefault CAIP-2 network
X402_PAY_TO_ADDRESSOptional fixed pay-to; else agent EVM address
SPEND_POLICY_ENABLEDEnforce per-agent budgets on fixed-price tools
PAID_FETCH_HOST_ALLOWLISTRestrict paid_fetch hosts (recommended in production)

Operational tips

  • Preflight: Use get_balance on the agent’s EVM address before paid calls.
  • Discovery: Prefer URLs from discover_services / get_service over guessing endpoints.
  • GET requests: Put query parameters in the url string, not in custom headers unless the API requires it.
  • Logging: Never log accessKey or full paymentPayload secrets in production.