
How to Pay for Premium API Access with x402 and USDC
The x402 protocol enables APIs to charge for usage in real‑time using cryptocurrency—specifically, stablecoins like USDC on Ethereum‑compatible chains. This guide walks you through exactly how an autonomous agent (or any software client) can detect an x402 402 Payment Required response and automatically settle the invoice using USDC on the Base mainnet.
Why x402?
Traditional API monetization relies on pre‑paid keys, monthly invoices, or complex billing systems. x402 flips the model: the API remains open, but each request that exceeds the free tier returns a 402 status with a cryptographically signed payment request. The client pays on‑the‑spend, and the API unlocks the requested data immediately.
This is ideal for:
- Microservices and APIs with variable usage
- Autonomous agents that need to acquire data or services without human intervention
- Pay‑per‑call pricing that aligns cost directly with value received
The Jennai x402 API Example
Our API at https://saltsfault.com/api/ offers four premium endpoints:
/v1/regime–$0.002USDC per call/v1/momentum–$0.005USDC per call/v1/trading-signals–$0.003USDC per call/v1/nft-status–$0.01USDC per call
All payments are settled in USDC on the Base mainnet (Chain ID 8453) to the wallet 0xAD63dE06fd51EFCD4170ACB2d1a2De772635c76b.
Step‑by‑Step: How an Agent Pays
1. Detect the 402 Response
When making a request to a premium endpoint, check the HTTP status code. If it is 402, inspect the Payment-Required header (a base64‑url‑encoded JSON object).
import requests
import base64
import json
url = "https://saltsfault.com/api/v1/regime"
resp = requests.get(url)
if resp.status_code == 402:
# Extract and decode the payment request
b64_header = resp.headers.get("Payment-Required")
payment_request = json.loads(base64.b64decode(b64_header))
print("Payment request:", payment_request)
else:
resp.raise_for_status() # Handle other errors
2. Parse the Payment Request
The decoded payment_request follows the x402 v2 schema. Key fields:
network: The blockchain network (e.g.,eip155:8453for Base mainnet)maxAmountRequired: The amount to pay, in wei (smallest unit of USDC)resource: The URL that becomes accessible after paymentmaxTimeoutDelay: How long the quote is valid (seconds)payee: The wallet address that should receive the fundsasset: The USDC contract address on Baseid: A unique identifier for this payment requestsignature: A cryptographic signature proving the API owns the payee wallet
3. Get USDC and Approve the Spend
To pay, your agent needs:
- Some USDC in its wallet on Base mainnet
- Approval for the x402 contract (or the payee directly) to spend that USDC
Since USDC is an ERC‑20 token, you must first approve the spender (the API’s wallet, or a relayer contract) to transfer the required amount.
from eth_account import Account
from web3 import Web3
# Configure web3 for Base mainnet
w3 = Web3(Web3.HTTPProvider("https://base-rpc.publicnode.com")) # Free public RPC
assert w3.is_connected(), "Failed to connect to Base"
# Your agent's private key (NEVER hard‑code in production; use secure storage)
private_key = "0xYOUR_PRIVATE_KEY_HERE"
account = Account.from_key(private_key)
address = account.address
# USDC contract on Base (check https://docs.circle.com/developer/)
usdc_address = Web3.to_checksum_address("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913")
usdc_abi = [
# ERC‑20 minimum abi for approve and balanceOf
{"constant":False,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"type":"function"},
{"constant":True,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},
]
usdc = w3.eth.contract(address=usdc_address, abi=usdc_abi)
# Check balance
balance = usdc.functions.balanceOf(address).call()
print(f"USDC balance: {{balance / 1e6}} USDC") # USDC has 6 decimals
# Amount to pay (from payment_request, in wei)
max_amount_wei = int(payment_request["maxAmountRequired"])
# Convert to human‑readable USDC (6 decimals)
amount_usdc = max_amount_wei / 1e6
print(f"Amount required: {{amount_usdc}} USDC")
# Approve the payee (the API's wallet) to spend this amount
payee = Web3.to_checksum_address(payment_request["payee"])
tx = usdc.functions.approve(payee, max_amount_wei).build_transaction({
"from": address,
"nonce": w3.eth.get_transaction_count(address),
"gas": 100000,
"gasPrice": w3.eth.gas_price,
})
signed_tx = account.sign_transaction(tx)
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
print(f"Approval transaction: {{receipt.transactionHash.hex()}}")
4. Execute the Payment
Now that the API’s wallet is approved to spend the required USDC, we can trigger the actual payment by calling the PUT (or POST) to the resource URL with the appropriate headers. Many x402 implementations accept payment via the X-PAYMENT header or by following a specific payment flow. For the Jennai API, the payment is settled off‑chain via the xpay.sh facilitator, which listens for on‑chain transfers to the payee.
In practice, after you approve and transfer the USDC to the payee wallet (0xAD63...), the API will detect the on‑chain transaction and grant access. The simplest way is to just send the USDC directly:
# Transfer USDC to the payee
tx = usdc.functions.transfer(payee, max_amount_wei).build_transaction({
"from": address,
"nonce": w3.eth.get_transaction_count(address),
"gas": 100000,
"gasPrice": w3.eth.gas_price,
})
signed_tx = account.sign_transaction(tx)
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
print(f"Payment transaction: {{receipt.transactionHash.hex()}}")
Once the transaction confirms on Base, the API will consider the invoice paid and serve the requested data on subsequent requests (or immediately, depending on implementation).
5. Verify Access
After payment, retry the original request—it should now return 200 with the premium data.
resp2 = requests.get(url)
print(resp2.status_code)
print(resp2.json()) # Or whatever format the API returns
Security & Best Practices
- Never expose private keys in client‑side code. Use secure vaults, environment variables, or hardware wallets.
- Check the signature in the payment request to ensure it truly comes from the expected payee (prevents spoofing).
- Validate the network (
eip155:8453) to avoid replay attacks on other chains. - Monitor gas prices; on Base they are usually low, but still check before sending.
- Consider using a relayer if your agent lacks native blockchain capabilities; some services can pay on your behalf for a fee.
Ready to Try?
The Jennai x402 API is live now. Grab some USDC on Base (you can bridge from Ethereum or purchase via a DEX), and try the flow above. Successful payments will appear in the API’s /v1/stats endpoint under trades.
Happy building—and may your agents always have enough USDC for the data they need!
Note: This guide is for educational purposes. Always test with small amounts first and ensure you comply with local regulations regarding cryptocurrency use.
sgbscc-20).
We only recommend products we genuinely believe will be useful to our readers.

