# How We Built x402 Payments for AI Agents
*From 402 header to USDC on-chain in 30 lines of code*
---
AI agents need to pay for things. Data APIs, compute, storage, other agents' services. But traditional payment systems (Stripe, PayPal) require human intervention. Credit cards, accounts, KYC — none of that works for autonomous agents.
Enter **x402**: a protocol that turns HTTP 402 (Payment Required) into a crypto payment rail. No accounts. No API keys. Just a wallet and a request.
We built an open-source implementation with two public SDKs (TypeScript + Python). Here's how it works.
## The Problem
Imagine an AI agent that needs real-time market data. It calls an API. The API wants $0.05 per request. How does the agent pay?
- **Stripe?** Requires account setup, API keys, human approval.
- **Crypto wallet?** Requires gas, complex signing, on-chain tx for every $0.05.
- **x402?** One header. One signature. Done.
## The Architecture
agent server facilitator
| GET /resource | |
|------------------------->| |
| 402 + requirements | |
|<-------------------------| |
| sign EIP-3009 (off-chain) |
| GET /resource + X-PAYMENT |
|------------------------->| verify + settle |
| |--------------------------->|
| | on-chain USDC transfer |
| 200 + resource | |
|<-------------------------| |
1. **Agent** requests a paid resource
2. **Server** responds 402 with payment requirements (amount, network, recipient)
3. **Agent SDK** signs an EIP-3009 TransferWithAuthorization off-chain (gasless!)
4. **Agent** retries with X-PAYMENT header
5. **Server** forwards to **facilitator**, which verifies the signature and settles on-chain
6. **Server** returns 200 + resource
The seller receives USDC. The facilitator pays gas. The agent pays nothing extra.
## The Code (Python)
python
from netthouse import X402Client
client = X402Client(private\_key="0x...")
\# Any paid URL. The SDK pays automatically on HTTP 402.
result = client.fetch("https://api.example.com/market-data")
if result.response.ok:
  print(result.response.json()) # the paid resource
  print("paid:", result.paid) # True
That's it. Three lines. The SDK handles discovery, signing, retry.
The Code (TypeScript)
import { X402Client } from "@netthouse/sdk";
const client = new X402Client({ privateKey: "0x..." });
const result = await client.fetch("https://api.example.com/market-data");
if (result.response.ok) {
  console.log(await result.response.json());
  console.log("paid:", result.paid);
}
Same API. Same flow. Different language.
The EIP-3009 Signature
The magic is in the signature. EIP-3009 TransferWithAuthorization is an off-chain authorization that a facilitator can execute on-chain. It includes:
from: payer address
to: seller address
value: amount in USDC (6 decimals)
validAfter / validBefore: time window
nonce: unique per transaction
The SDK signs this with the payer's private key. The facilitator verifies the signature and submits the on-chain transaction. The seller receives USDC. The facilitator pays gas.
The Facilitator
The facilitator is a trusted third party that:
Verifies the EIP-3009 signature
Checks the nonce hasn't been used
Submits the on-chain transaction
Pays gas (reimbursed by the seller via a separate mechanism)
In our implementation, the facilitator is a Fastify module that runs alongside the API. For production, you'd run it as a separate service.
The Discovery
How does an agent know what resources are available and how much they cost? The /discover endpoint:
{
  "x402Version": 1,
  "items": \[
  {
  "resource": "/market-data",
  "type": "http",
  "x402Version": 1,
  "accepts": \[
  {
  "scheme": "exact",
  "network": "base-sepolia",
  "payTo": "0x34798CCeF50aaa45194E5E20008711A5Fbfd182C",
  "maxAmountRequired": "50000",
  "resource": "/market-data",
  "description": "Crypto market snapshot",
  "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
  }
  ]
  }
  ]
}
The agent calls /discover, sees the catalog, picks a resource, and pays.
The First Payment
We tested the Python SDK against our live API. The first payment:
Resource: /market-data ($0.05 USDC)
Network: Base Sepolia (testnet)
Transaction: https://sepolia.basescan.org/tx/0xf9f7589adeb5e10019cd95b871cb74b3b3e3b54b5940964bae2794ce912eb0e8
Status: Success ✅
The agent paid. The seller received USDC. The facilitator paid gas. Everything worked.
What's Next
Mainnet launch: Switch from Base Sepolia to Base mainnet (need ETH for facilitator gas)
More resources: Add /news, /weather, /sentiment to the catalog
Dashboard: Seller analytics (revenue, requests, popular resources)
Webhooks: Notify sellers when payments arrive
Rust SDK: For high-performance agents
Try It
TypeScript SDK: npm install @netthouse/sdk
Python SDK: pip install netthouse
Live API: https://netthouse-api.onrender.com/discover
GitHub: https://github.com/Zhasulan391/sdk-typescript
Both SDKs are MIT licensed. Both are public. Both are working.
Built with Fastify, viem, eth-account, and a lot of coffee.
Top comments (0)