x402 in Python
Add x402 payments to a Python API with the official SDK — gate a FastAPI route behind USDC on the server, and pay endpoints automatically on the client.
How do I use x402 in Python?
Install the official package with pip install x402. On the server, wrap a FastAPI route with the require_payment middleware, passing a price and your wallet address; unpaid requests get HTTP 402. On the client, attach x402_payment_hooks from x402.clients.httpx to an httpx.Client — it detects the 402, pays in USDC, and retries automatically.
Which approach should you use?
Install
pip install x402 Server (FastAPI)
The route returns HTTP 402 until a USDC payment is made, then runs normally.
# FastAPI server that charges for a route
from fastapi import FastAPI
from x402.fastapi.middleware import require_payment
app = FastAPI()
# Gate this route behind a USDC payment
app.middleware("http")(
require_payment(
path="/weather",
price="$0.01",
pay_to_address="0xYourReceivingWalletAddress",
network="base-sepolia", # use "base" in production
)
)
@app.get("/weather")
def weather():
# Runs only after a valid payment
return {"city": "Tokyo", "forecast": "sunny"} Client (httpx)
Attach payment hooks and the client pays on its own — the same pattern an AI agent uses.
# A Python client that pays automatically
import httpx
from x402.clients.httpx import x402_payment_hooks
from eth_account import Account
account = Account.from_key("0xYOUR_PRIVATE_KEY")
client = httpx.Client()
client.event_hooks = x402_payment_hooks(account)
r = client.get("http://localhost:8000/weather")
print(r.json()) # {"city": "Tokyo", ...} Async client (agents)
An autonomous agent usually wants this over the sync client — it can await a paid call inside an async loop instead of blocking the thread while payment settles.
# Same thing, but async — how an autonomous agent typically calls it
import asyncio
import httpx
from x402.clients.httpx import x402_payment_hooks
from eth_account import Account
account = Account.from_key("0xYOUR_PRIVATE_KEY")
async def main():
async with httpx.AsyncClient(event_hooks=x402_payment_hooks(account)) as client:
r = await client.get("http://localhost:8000/weather")
r.raise_for_status()
return r.json()
print(asyncio.run(main())) # {"city": "Tokyo", ...} Flask / no official package
There's no official Flask middleware yet, but x402 is protocol-level: a before_request hook that returns a 402 with the right JSON body works in any WSGI framework.
# Flask (or any WSGI framework) — no x402 package required.
# The protocol is just HTTP 402 + a JSON body, so you can implement it
# by hand in a before_request hook if you're not on FastAPI/ASGI.
from flask import Flask, request, jsonify
app = Flask(__name__)
PRICE_ATOMIC = "10000" # $0.01 USDC, 6 decimals -> 10_000 base units
@app.before_request
def require_payment():
if request.path != "/weather":
return
proof = request.headers.get("X-PAYMENT")
if not proof or not verify_payment(proof, PRICE_ATOMIC): # your verification
return jsonify({
"accepts": [{
"scheme": "exact",
"network": "base-sepolia",
"maxAmountRequired": PRICE_ATOMIC,
"payTo": "0xYourReceivingWalletAddress",
"asset": "USDC",
}]
}), 402
@app.get("/weather")
def weather():
return {"city": "Tokyo", "forecast": "sunny"} You still need something to implement verify_payment() — either call a facilitator's verify endpoint or check the on-chain transfer yourself. See facilitators for hosted options.
Troubleshooting
Why: The client never actually sends a payment — usually a missing or misconfigured private key/account, or the wrong network in the hooks vs. the server (one says base, the other base-sepolia).
Fix: Log the raw 402 body once and confirm the network field matches your client account’s chain; confirm the account has funds on that network.
Why: Your Base Sepolia test wallet has no faucet USDC (or no ETH for gas, depending on the facilitator’s settlement path).
Fix: Fund the address from a Base Sepolia USDC faucet before retrying — this never touches real money.
Why: USDC uses 6 decimals. "price" strings like "$0.01" are converted for you, but if you build the accepts body by hand, maxAmountRequired must be an integer in base units, not dollars.
Fix: Use the free base-unit converter (linked below) to get the integer right.
Why: The facilitator settled the payment, but your server is checking the proof against the wrong route/price, or the X-PAYMENT header got stripped by a proxy in front of your app.
Fix: Confirm the price/path in your middleware config match the actual route, and that X-PAYMENT survives any reverse proxy/CDN in front of the app.
Get amounts right with the free base-unit converter.
Real Python x402 projects
Curated from the 137 Python projects we track that reference x402 — stars live from GitHub.
The A2A x402 Extension brings cryptocurrency payments to the Agent-to-Agent (A2A) protocol, enabling agents to monetize their services through on-chain payments. This extension revives the spirit of HTTP 402 "Payment Required" for the decentralized agent ecosystem.
⭐ 541Drop-in x402 payment middleware for Flask APIs. Machine-to-machine payments on Base chain.
⭐ 69AWS payment demo of x402 using Bedrock AgentCore, Strands SDK, and CloudFront.
⭐ 24Test for free on Base Sepolia, then set network="base" for production. For TypeScript, Go and Rust see the SDK guide; for the full walkthrough see the tutorial.
Frequently asked questions
Does x402 have a Python SDK?
Yes. The official x402 Python package provides both server-side helpers (middleware for FastAPI/Flask-style apps that require payment on a route) and client-side hooks that pay automatically. Install it with pip install x402 and wrap the routes you want to charge for.
How do I add x402 to a FastAPI app?
Install the x402 package, then apply the require_payment middleware to the route you want to monetize, passing the path, price, your receiving wallet address, and the network. Unpaid requests get HTTP 402; paid ones reach your handler. Use network "base-sepolia" to test for free and "base" in production.
How does a Python client pay an x402 endpoint?
Attach the x402 payment hooks to an httpx client with a funded account. When the server responds with 402, the hooks read the payment requirements, sign a USDC payment, and retry the request automatically — so your code just calls the endpoint and gets the result.
Can I test the Python x402 flow without real money?
Yes. Set the network to "base-sepolia" and fund a test wallet from a free faucet. The full 402 → pay → 200 flow behaves exactly like mainnet, so you can develop for free and switch network to "base" when going live.
Does x402 Python work with Flask or Django?
The Python package centers on ASGI/FastAPI-style middleware, but the protocol is just HTTP 402, so you can implement the same flow in any framework: return a 402 with payment requirements, verify the payment via a facilitator, then serve the response. FastAPI is the smoothest path today.
Should I use the official x402 package or write my own Flask handler?
Use the official package if you’re on FastAPI/ASGI — it handles the 402 body, verification and settlement calls for you. On Flask, Django or another WSGI framework, write the check by hand in a before_request-style hook (shown above); it’s a small amount of code because the protocol itself is simple.
How do I call an x402 endpoint from an async agent?
Use httpx.AsyncClient with the same x402_payment_hooks used for the sync client. Each call awaits the request; on a 402 the hooks sign and retry transparently, so an async agent loop can fire many paid calls concurrently without blocking.