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.

Discovery
discovery URL
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.

Your agent + walletGetFixn API1 POST /v1/weather/batch2 402 + price header3 sign USDC payment (local)4 retry with payment5 200 + data
  1. 1

    Request

    Your program calls a paid route with no key.

    POST /v1/weather/batch
  2. 2

    402

    The server answers HTTP 402 Payment Required and names the price in a header.

    payment-required: ...
  3. 3

    Sign

    Your wallet signs a USDC payment of exactly that amount on Base. Nothing is sent yet.

    0.0002 USDC, Base
  4. 4

    Retry

    The same request goes out again, now carrying the signed payment.

    same call + payment
  5. 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.

curl, unpaid
# 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>
payment-required header, decoded
{
  "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 getRoutePriceIn the x402 manifest
Model-Based Weather by Address, batch, up to 500 locations per callPOST /v1/weather/batch$0.0002 per locationYes
County forecast status (county-level, not address-level), up to 500 locations per callPOST /v1/portfolio/risk$0.05 per locationYes
ML Storm Forecast by AddressGET /v1/data?dataset=risk&addresses=true$0.05 per addressVia the /v1/data fallback
Model-Based Hourly Forecast by AddressGET /v1/data?dataset=weather&hours_ahead=12&details=true$0.0002 per callVia 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 addressVia the /v1/data fallback
Storm History by AddressGET /v1/data?dataset=history$0.05 per line, $10 minimum per reportVia the /v1/data fallback
Hazard scoreGET /v1/data?dataset=hazard_score$0.50 per queryVia 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.

x402_pay.pyDownload
"""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

terminal
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

  1. One wallet, one job. Create a new wallet just for this bot. Never use the wallet that holds your savings or other assets.
  2. 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.
  3. Base network only. Send USDC on Base. Sending the wrong token or network to a wallet can lose the funds.
  4. Key in an environment variable. X402_PRIVATE_KEY on your own machine. Not in code, not in git, not in screenshots, not in a chat with an AI model. Put .env in .gitignore.
  5. Dry run first. Print the price and exit, as the example does, and only pay when you have said so.
  6. Cap spending in your code. A bug in a loop should hit a ceiling, not an empty wallet.
  7. Check the pay-to address. It must match the address in /.well-known/x402.json. A mismatch means stop.
  8. 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.