01 / x402
Pay per call with USDC on Base
x402 lets a program pay for an API call itself, mid-request. No signup, no key, no card. The server says what the call costs, your wallet pays that amount in USDC (a token worth one US dollar) on the Base network, and the data comes back.
It suits crypto bots and AI agents that already have a wallet. If you would rather have a normal account, buy an API key instead. Bot ideas, including prediction-market research, are on the bots page.
https://data.truefixr.com/.well-known/x402.json- Network: Base mainnet (
eip155:8453) - Asset: USDC, scheme
exact: pay exactly what the 402 asks - Settlement: through an outside facilitator service (PayAI), per the manifest, not run by us
- No signup. Wallet in, data out.
02 / THE FLOW
Request, 402, sign, retry, data
A standard x402 client does steps 2 to 4 for you. In your code it looks like one ordinary request.
- 1
Request
Your program calls a paid route with no key.
POST /v1/weather/batch - 2
402
The server answers HTTP 402 Payment Required and names the price in a header.
payment-required: ... - 3
Sign
Your wallet signs a USDC payment of exactly that amount on Base. Nothing is sent yet.
0.0002 USDC, Base - 4
Retry
The same request goes out again, now carrying the signed payment.
same call + payment - 5
Data
The payment is verified and settled, and the data comes back.
HTTP 200 + JSON
03 / SEE A REAL 402
The price is in the answer, before you pay
This is what the live API returned to an unpaid request for one location. Amounts are in USDC's six decimal places: 200 means $0.0002. The same call for the county forecast status route returned an amount of 50000, which is $0.05. Check the price on every route yourself before paying.
# Free: ask without paying. You get a 402 and the price, nothing is charged.
curl -i -X POST https://data.truefixr.com/v1/weather/batch \
-H "content-type: application/json" \
-d '{"locations":[{"lat":32.78,"lon":-96.80}]}'
# HTTP/2 402
# payment-required: <base64 JSON, decoded on the right>{
"x402Version": 2,
"accepts": [{
"scheme": "exact",
"network": "eip155:8453",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "200",
"payTo": "0xFf23cfFf46535E076e88835CD0Bbad8D1033E255",
"maxTimeoutSeconds": 300
}]
}Verify the pay-to address against /.well-known/x402.json before you fund anything. Both showed the same address when we checked on October 3, 2026.
04 / PRICES
What each call costs
The per-unit prices match the prepaid key. The 402 states the exact price of each call before you pay it.
| What you get | Route | Price | In the x402 manifest |
|---|---|---|---|
| Model-Based Weather by Address, batch, up to 500 locations per call | POST /v1/weather/batch | $0.0002 per location | Yes |
| County forecast status (county-level, not address-level), up to 500 locations per call | POST /v1/portfolio/risk | $0.05 per location | Yes |
| ML Storm Forecast by Address | GET /v1/data?dataset=risk&addresses=true | $0.05 per address | Via the /v1/data fallback |
| Model-Based Hourly Forecast by Address | GET /v1/data?dataset=weather&hours_ahead=12&details=true | $0.0002 per call | Via the /v1/data fallback |
| Past Storm Leads by Address (reported and radar-detected storms matched to street addresses) | GET /v1/data?dataset=storms&addresses=true | $0.05 per address | Via the /v1/data fallback |
| Storm History by Address | GET /v1/data?dataset=history | $0.05 per line, $10 minimum per report | Via the /v1/data fallback |
| Hazard score | GET /v1/data?dataset=hazard_score | $0.50 per query | Via the /v1/data fallback |
The /v1/data route accepts x402 as a fallback when no API key is sent. Free previews exist on every dataset and show counts and the exact price first. We decoded the 402 for the two batch routes only, so read the price in the 402 or the free preview for the others.
05 / CODE
Python, with the official x402 client
The script first asks the price with a plain request and pays nothing. Only with --go does it pay. The wallet key comes from X402_PRIVATE_KEY, never from the code.
"""Pay per call with USDC on Base (x402). No account, no API key.
pip install requests "x402[httpx,evm]" eth-account
export X402_PRIVATE_KEY=0x... # a DEDICATED wallet holding a few dollars of USDC on Base. Never your main wallet.
python x402_pay.py # dry run: asks the price, pays NOTHING
python x402_pay.py --go # really pays (about $0.0002 per location for weather)
Structure proven against this API with the official Python x402 v2 client. Other clients are untested.
GetFixn sells data, not trading advice. Forecasts can be wrong.
"""
import asyncio
import base64
import json
import os
import sys
import requests
URL = "https://data.truefixr.com/v1/weather/batch"
BODY = {"locations": [{"lat": 32.78, "lon": -96.80, "label": "Dallas"}]}
def quote():
"""Unpaid request. The server answers 402 and says what it wants. Costs nothing."""
r = requests.post(URL, json=BODY, timeout=30)
if r.status_code != 402:
sys.exit("expected 402, got %s" % r.status_code)
need = json.loads(base64.b64decode(r.headers["payment-required"]))["accepts"][0]
usd = int(need["amount"]) / 1_000_000 # USDC has 6 decimals
print("price: $%.4f USDC on %s, pay to %s" % (usd, need["network"], need["payTo"]))
return usd
async def pay():
from eth_account import Account
from x402 import x402Client
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact import register_exact_evm_client
acct = Account.from_key(os.environ["X402_PRIVATE_KEY"])
client = x402Client()
register_exact_evm_client(client, EthAccountSigner(acct))
async with x402HttpxClient(client) as http:
r = await http.post(URL, json=BODY) # 402 -> sign -> retry, all inside the client
await r.aread()
print(r.status_code, r.text[:400])
if __name__ == "__main__":
price = quote()
if "--go" in sys.argv:
asyncio.run(pay())
else:
print("dry run only. Add --go to pay $%.4f." % price)Run it
pip install requests "x402[httpx,evm]" eth-account
export X402_PRIVATE_KEY=0x... # dedicated low-balance wallet only
python x402_pay.py # dry run, pays nothing
python x402_pay.py --go # pays about $0.0002- Fund a wallet with a few dollars of USDC on Base. How network fees are handled is described in the x402 client docs, so read them before funding the wallet.
- For bots, wrap the call exactly as shown and add the same caps as the other bots: a daily budget in your code, backoff on 429 and 5xx, and a stop on repeated failures.
- A JavaScript client exists in the x402 project (
@x402/fetch). We have not tested it against this API, so it is not shown here.
06 / WHAT WE TESTED
What we tested, and what we did not
- Proven: Official Python x402 v2 client
- Payments were made against this API with the official Python x402 v2 client, the one in the example. The first payment settles immediately. Later small calls accrue to a $1.00 tab.
- Not proven: Everything else
- No other x402 clients or libraries have been tested against this API. If yours is different, try one tiny call with a throwaway wallet first and tell us what happened.
- Prices: Read the 402 each time
- The price in the 402 is the price you are asked to pay. Do not hard-code prices in a bot that pays. Compare the amount to your budget before signing.
- Money moves: On-chain payments are final
- A payment sent on Base cannot be taken back by a bank. Keep amounts small until your bot is boring and predictable.
07 / WALLET SAFETY
Use a dedicated, low-balance wallet
- One wallet, one job. Create a new wallet just for this bot. Never use the wallet that holds your savings or other assets.
- Keep it small. Fund it with a few dollars of USDC on Base, enough for a day or a week. Top it up on purpose.
- Base network only. Send USDC on Base. Sending the wrong token or network to a wallet can lose the funds.
- Key in an environment variable.
X402_PRIVATE_KEYon your own machine. Not in code, not in git, not in screenshots, not in a chat with an AI model. Put.envin.gitignore. - Dry run first. Print the price and exit, as the example does, and only pay when you have said so.
- Cap spending in your code. A bug in a loop should hit a ceiling, not an empty wallet.
- Check the pay-to address. It must match the address in
/.well-known/x402.json. A mismatch means stop. - Leaked key means move funds. If you think the key leaked, move what is left to a new wallet right away and stop using the old one.
GetFixn sells data, not trading advice. Nothing here is investment advice. Forecasts can be wrong. You are responsible for your own strategies and wallets, and for following the rules of any exchange or market you use. Not financial, tax or legal advice about crypto. We have no partnership with or endorsement from any exchange, wallet or chain. Heavy or commercial/trading volume? Email admin@truefixr.com.