01 / OVERVIEW

API docs

One base URL, one main route, and a free preview on every dataset. You build the app, dashboard or bot. We supply the weather and storm data.

Short version. You send a place or an address to a URL and get JSON back. Every paid question has a free version that shows counts and the exact price. The paid version returns the records and takes the money from your prepaid balance.
  • Base URL https://data.truefixr.com
  • Main route GET /v1/data, picks the data with dataset=
  • Coverage US addresses. 10 forecast perils: tornado, hail, wind, flash flood, heavy rain, winter, ice, coastal surge, hurricane, wildfire.
  • History back to 2003, 11 peril categories, address level.
  • Forecast windows from 24 hours out to 10 days, refreshed 4 times a day.
  • Machine-readable openapi.json, llms.txt, x402.json

Storm data here means storms that were reported and radar-detected and matched to street addresses. It is not an inspection and not a damage assessment. Forecasts show what could happen, not what will, and can be wrong. Not affiliated with NOAA or the National Weather Service.

Quickstart, no SDK needed

No library needed, any HTTP client works. The three snippets below make the same two calls: the free menu, then live weather at one point. No key.

curl -s https://data.truefixr.com/v1/data | head -c 400
curl -s "https://data.truefixr.com/v1/data?dataset=weather&lat=32.78&lon=-96.80"

If it prints a temperature, you are set up. Next: recipes in four languages, or grab the starter kit.

Starter workflow

  1. Call the menu with no parameters. It lists every dataset, an example call and the price.
  2. Run the free preview of the dataset you want. Read estimated_cost_usd (or the line count and price).
  3. Buy a key if you want the full records. Minimum purchase is $25, prepaid, no subscription.
  4. Add addresses=true and the Authorization header to run the paid pull. Start with a small limit.

Authentication

Free previews need no key and no header. Paid pulls need your API key as a Bearer token. Keys look like tfx_live_... and are shown once when you buy, so put yours in a password manager or an environment variable right away.

Paid call
curl -s -G https://data.truefixr.com/v1/data \
  -d dataset=hazard_score -d addresses=true \
  --data-urlencode "address=891 Lake Hollow Blvd SW, Marietta, GA 30064" \
  -H "Authorization: Bearer $GETFIXN_KEY"
Keep the key secret. Never put it in front-end code that ships to other people's browsers, in a public repo or in a screenshot. Call the API from your server, or let each user paste their own key (the starter web app does this and sends it only to the API). If a key leaks, rotate it from My key.

Wrong or missing key on a paid pull? You get a 402 with the price, not a 401. See Errors.

No account at all: an AI agent can pay per call in USDC on Base with x402. See x402.

Your key and balance

Keys are tied to a prepaid balance. These routes exist in the OpenAPI spec: GET /v1/billing/account (the key goes in the api_key query parameter, so keep that URL out of shared logs), POST /v1/billing/rotate-key with body {"api_key": "..."} to get a new key, and POST /v1/billing/recover with body {"email": "..."} to recover a key. The My key page does the same without code.

Datasets

Choose the data with dataset=NAME. Every dataset has a free preview. Add addresses=true (or details=true for weather) and your key to buy the full pull.

The five products: ML Storm Forecast by Address (dataset=risk), Model-Based Weather by Address (dataset=weather), Model-Based Hourly Forecast by Address (dataset=weather with hours_ahead), Storm History by Address: Reported and Radar-Detected Events Since 2003 (dataset=history) and Past Storm Leads by Address: Reported and Radar-Detected, Last 365 Days (dataset=storms). The first three are model outputs. The last two are recorded events matched to addresses. Forecasts describe what could happen, not what will happen.

datasetWhat it isLocate it withPaid price
stormsPast Storm Leads by Address: Reported and Radar-Detected, Last 365 Days.county + state, or lat + lon$0.05 per address
riskML Storm Forecast by Address: per-peril machine-learning forecasts for 10 perils, 24 hours to 10 days. Each record carries structure replacement value, people, storm type, forecast time and a risk label. The free preview adds a county grade as a teaser.county + state, or lat + lon$0.05 per address
addressOne property: its reported and radar-detected events over the last 365 days, with the county forecast label as secondary context.lat + lon$0.05 per address
historyStorm History by Address: Reported and Radar-Detected Events Since 2003, 11 event categories, optional date-of-loss mode.address or lat + lon$0.05 per line, $10 minimum per report
hazard_scoreOne property summarized by peril: counts, most recent event, years since last.address or lat + lon$0.50 per property
weatherModel-Based Weather by Address: current conditions, rain outlook, severe alerts, free lean response. Add hours_ahead (0 to 48) for Model-Based Hourly Forecast by Address.address or lat + lonFree lean. $0.0002 per call with details=true
facilitiesSchools, hospitals and other facilities currently under an active risk window.county + state (both)$0.05 per facility
wildfireCounty-level wildfire risk for the coming days, one record per county. Not address-level.state$0.05 per county
at_riskSchools and businesses at risk, by peril and window.state, kind, peril$0.05 per record
dailyDaily county digest: counts, storm types, dollar exposure. No address records.rank, limitAlways free
coverageWhich states and counties have data on file.state (optional)Always free

The free preview of GET /v1/data shows the full menu. Datasets are described live there, and the live response wins if it ever disagrees with this page.

Parameters

All parameters are query parameters on GET /v1/data. Unknown combinations return a 400 whose detail tells you what is missing. The OpenAPI spec also lists months, category, format and counties without further description. Check the free menu before relying on them.

ParameterTypeWhat it does
datasetstringWhich data. See the table above. Omit it to get the free menu.
countystringCounty name, such as Dallas. Send with state.
statestringTwo-letter state, such as TX. A state alone is a 400 for storms and facilities.
latnumberLatitude. Use with lon.
lonnumberLongitude. Use with lat.
addressstringStreet address. Geocoded for you. Accepted by history, hazard_score and weather.
addressesbooleantrue runs the paid pull and returns records. Default false, the free preview.
perilstringFilter by storm type, such as HAIL. Fewer addresses means a lower price. Use a key from storm_types in the preview.
daysintegerLook-back window in days for storms (up to 365).
windowstringForecast window for risk. Default 24h. Values that returned data when tested: 24h, 48h, 7d, 10d.
limitintegerMax records on a paid pull. Default 2000, max 5000. Your spend cap. Also the number of rows for daily.
radius_minumberhistory and hazard_score: search radius in miles. Default 5, min 1, max 25.
date_of_lossYYYY-MM-DDhistory: anchor the report on one date. Free preview returns a yes or no (date_of_loss_supported) and a plain answer.
hours_aheadintegerweather: 0 to 48. Returns a point forecast. The response says which forecast hour it used.
detailsbooleanweather: true returns the full detail pull. $0.0002 per call, needs a key.
rankstringdaily: exposure_value_usd, exposure_people, new_leads or unique_addresses. Returns the top counties nationwide, sorted.
kindstringat_risk: for example schools.
min_severitynumberstorms: minimum severity. Some storm types carry two units, see below.
max_severitynumberstorms: maximum severity.
severity_unitstringRequired when severity_by_type shows mixed_units: true. Pick a key under by_unit, such as pct or mph. Without it a mixed-unit filter returns a 400.

Narrower filters mean fewer addresses and a lower price. Always read the preview first.

Response fields

Everything is JSON. These are real free-preview responses from the live API, trimmed. Numbers change as the data refreshes. The county grade is a free-preview teaser, not a property score. Grade scale: A no or low risk, B moderate, C elevated, D severe, F extreme.

weather (free lean response)

GET /v1/data?dataset=weather&lat=32.78&lon=-96.80
{
  "location": { "lat": 32.784859, "lon": -96.802979 },
  "generated_at": "2026-10-03T13:00:00+00:00",
  "valid_time": "2026-10-03T14:00:00+00:00",
  "alerts": [],
  "nowcast": { "precip_rate_inhr": 0.051, "raining_now": true, "source": "precipitation nowcast" },
  "wind_gust_mph": 13.7615, "precip_in": 0.0209, "dewpoint_f": 69.9195, "temperature_f": 72.4259,
  "wind_speed_mph": 6.77, "wind_direction_deg": 14.1, "humidity_pct": 91.8,
  "precip_type": "rain", "pressure_mb": 999.5, "visibility_mi": 8.3885,
  "dataset": "weather", "billed": false
}

risk (free preview)

GET /v1/data?dataset=risk&county=Dallas&state=TX
{
  "dataset": "risk", "county": "Dallas", "state": "TX", "window": "24h",
  "grade": "B", "grade_label": "Moderate risk",
  "total_leads": 660,
  "storm_types": { "HEAVY_RAIN": 501, "FLASH_FLOOD": 386 },
  "generated": "2026-10-03T09:27:00.496555Z",
  "data_age_hours": 5.8,
  "estimated_cost_usd": 33.0
}

total_leads is the number of address-level forecast records in that window. estimated_cost_usd is the price of the paid pull at your current filters. Check data_age_hours: forecasts refresh 4 times a day.

risk (paid record, trimmed)

GET /v1/data?dataset=risk&county=Dallas&state=TX&window=24h&addresses=true&limit=1
{
  "county": "Dallas", "state": "TX", "window": "24h", "returned": 1,
  "value_basis": "Replacement cost of structure (not market value)",
  "leads": [{
    "structure_value": 300882, "people": 3.5,
    "full_address": "405 Evergreen Trail, Cedar Hill, TX 75104",
    "storm_type": "HEAVY_RAIN", "forecast_time": "2026-10-04T12:27:00Z",
    "risk_label": "Extreme", "storm_hits": 2
  }],
  "reference_id": "TFX-202610-6A3B8262"
}

structure_value is replacement cost (what it costs to rebuild), not market value. people is the estimated occupancy of the address. The risk label is a word tier. Forecasts describe what could happen, not what will happen.

address (free preview)

GET /v1/data?dataset=address&lat=32.78&lon=-96.80
{
  "dataset": "address", "county": "dallas", "state": "TX",
  "matched_by": "lat/lon (~150m radius)",
  "storm_event_count": 297,
  "storm_types": { "HEAVY_RAIN": 297 },
  "current_forecast_risk": { "grade": "B", "grade_label": "Moderate risk" },
  "severity_by_type": { "HEAVY_RAIN": { "min": 1.04, "max": 1.04, "unit": "in", "with_severity": 297 } }
}

history (free preview, with date of loss)

GET /v1/data?dataset=history&address=...&date_of_loss=2026-04-14
{
  "dataset": "history",
  "geocoded_address": "891 Lake Hollow Blvd SW, Marietta, GA 30064, USA",
  "radius_mi": 5.0,
  "real_line_count": 362,
  "estimated_cost_usd": 18.1,
  "by_peril": { "hail": 65, "wind": 123, "flood": 10, "lightning": 7, "tornado": 2, "hurricane": 19,
                "winter": 67, "extreme_temp": 24, "drought": 40, "wildfire": 1, "coastal": 0 },
  "date_of_loss": "2026-04-14",
  "date_of_loss_supported": false,
  "answer": "No severe-weather event is on file within 5.0 miles of this address on 2026-04-14."
}

daily (free, ranked)

GET /v1/data?dataset=daily&rank=exposure_value_usd&limit=20
{
  "dataset": "daily", "generated": "2026-10-03T09:34:36Z", "ranked_by": "exposure_value_usd", "returned": 2,
  "counties": [
    { "state": "TX", "county": "Harris", "new_leads": 2073075, "unique_addresses": 1680254,
      "exposure_value_usd": 523921470966, "exposure_people": 3490900,
      "storms": [ { "type": "HAIL", "count": 112748 } ], "has_hot": true }
  ]
}   // trimmed to one county

Paid pulls (addresses=true) return the matching records as a list in the response. The record fields differ by dataset (for example facilities return name, category, city, state, coordinates and risk label). Make one small paid call with a low limit and inspect the shape before you write a parser. Paid record shapes were not exercised for these docs.

Storm types and units. storm_types counts are per event, not per address, so they can add up to more than total_leads. Some storm types report severity in more than one unit. severity_by_type on a free preview tells you; if it shows mixed_units: true, send severity_unit=.

Batch routes

Two POST routes take up to 500 locations per call. You send your own list each time and it is never stored. They have no free preview, so they need a key (or an x402 payment) from the first call.

RouteDoesPrice
POST /v1/weather/batchCurrent conditions and active severe alerts for each location.$0.0002 per location
POST /v1/portfolio/riskCounty forecast status for each location (county-level, not address-level). Optional "window".$0.05 per location
POST /v1/portfolio/risk
curl -X POST https://data.truefixr.com/v1/portfolio/risk \
  -H "Authorization: Bearer $GETFIXN_KEY" -H "Content-Type: application/json" \
  -d '{"locations":[{"lat":30.27,"lon":-97.74,"label":"Austin office"}],"window":"24h"}'

Response shapes come from the API's own x402 manifest and docs: /v1/portfolio/risk returns results with lat, lon, county, grade per location. /v1/weather/batch returns results with current and alerts. Paid calls were not run for these docs, so verify with one location first. Bigger lists: split into chunks of 500.

Errors and limits

CodeMeaningWhat to do
400A required parameter is missing or does not fit the dataset.Read the detail text. It names what is missing.
402Payment required: a paid pull with no valid key or balance, or an unpaid x402 route.Add a Bearer key, top up, or pay with x402. The body states the price in accepts[0].amount.
422A parameter has the wrong type, such as text where a number belongs.Fix the value named in loc.
429Too many free previews (60 per minute per IP).Wait a minute. Space out calls, or use a key.

402 payment required

This is what a paid route returns when there is no valid key or payment. It tells you the price. Nothing is charged.

HTTP 402, trimmed
{
  "x402Version": 2,
  "error": "Payment required",
  "resource": { "url": "https://data.truefixr.com/v1/weather/batch", "description": "...", "mimeType": "application/json" },
  "accepts": [{
    "scheme": "exact",
    "network": "eip155:8453",
    "asset": "0x8335...",
    "amount": "200",
    "payTo": "0xFf23cfFf46535E076e88835CD0Bbad8D1033E255",
    "maxTimeoutSeconds": 300,
    "extra": { "name": "USD Coin", "version": "2" }
  }],
  "extensions": { "bazaar": { /* ... */ } }
}

The price of the call is accepts[0].amount in atomic USDC (6 decimals), so 200 means $0.0002 (price in USD = amount / 1,000,000). The same object is also sent in the PAYMENT-REQUIRED response header as base64 JSON. The old for_ai_agents and price_usd fields are gone. Handle 402 by stopping and asking the user to top up, never by retrying in a loop.

400 and 422

HTTP 400 and 422
// GET /v1/data?dataset=weather
{ "detail": "dataset=weather needs address, or lat+lon" }

// lat=abc
{ "detail": [ { "type": "float_parsing", "loc": ["query", "lat"], "msg": "Input should be a valid number, unable to parse string as a number" } ] }

Practical limits

  • Free previews: 60 requests per minute per IP (429 beyond that).
  • Batch routes: 500 locations per call.
  • Paid pulls: 2,000 records by default, up to 5,000 with limit. There is no cursor in the API. Split big jobs by county, peril or days.
  • History radius: 1 to 25 miles.
  • Observed: some default HTTP clients (for example Python's built-in urllib with its stock User-Agent) were blocked with a 403. requests, fetch and curl worked. If you hit a 403, set your own User-Agent header.

Pricing

Prepaid balance, pay as you go. Minimum purchase is $25 (presets 25, 50, 100, 250, 500 or a custom amount). No subscription, no contract. Calls come out of your balance. Free previews cost nothing and show the price first.

What you getPriceFree preview
Past Storm Leads by Address (reported and radar-detected storms matched to addresses)$0.05 per addressCounts, storm types, repeat-hit addresses, exact cost
Storm History by Address, 2003 to present$0.05 per line, $10 minimum per reportLine count by peril and exact price; date-of-loss yes or no
ML Storm Forecast by Address (10 perils, 24 hours to 10 days)$0.05 per addressCounty grade (teaser), storm types, per-peril counts, exact cost
Hazard score$0.50 per queryEvent counts per peril
County forecast status, batch (up to 500 locations)$0.05 per locationNo preview on the batch route
Model-Based Weather by Address, full data (details=true)$0.0002 per callFree lean response
Model-Based Hourly Forecast by Address (hours_ahead 0 to 48)$0.0002 per callFree lean response
Facilities, at-risk records, wildfire counties$0.05 per recordCounts only
Daily county digest, coverage, the menuFreeAlways free

Optional auto top-up (off unless you tick it): charges the saved card the same amount when your balance drops below $5, at most once every 20 hours. See Pricing and Buy API key.

Prices are the live ones from the menu on /v1/data. A paid history report is $10 minimum however few lines it has.

MCP setup

MCP lets AI assistants such as Claude and Cursor call outside tools. Point the client at one URL and the assistant can look up storm data. Free previews work without a key.

Server URL: https://mcp.atlasunited.io/mcp. It was checked live with a tools/list call and exposes six tools: get_weather_data, get_storm_history, get_risk_forecast, get_property_storm_history_report, get_current_weather and get_address_report.

Claude Desktop

Easiest: in Settings, add a custom connector with the URL above. Or edit claude_desktop_config.json (the mcp-remote bridge is a common pattern for remote servers):

claude_desktop_config.json
{
  "mcpServers": {
    "getfixn-storm-data": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.atlasunited.io/mcp"]
    }
  }
}

Cursor

Add this to ~/.cursor/mcp.json (or the project's .cursor/mcp.json):

~/.cursor/mcp.json
{
  "mcpServers": {
    "getfixn-storm-data": {
      "url": "https://mcp.atlasunited.io/mcp"
    }
  }
}

Check it by hand

List the tools
curl -s -X POST https://mcp.atlasunited.io/mcp \
  -H "content-type: application/json" \
  -H "accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

The server URL and tool list are verified. The client config snippets follow each client's standard pattern for remote MCP servers and were not run inside those apps for this page. If a client changes its format, use its own docs for the URL field.

x402: pay per call, no account

x402 lets a bot or AI agent pay for a call in USDC on Base with no signup and no key. The server answers 402 with a price, the agent signs a payment from its own wallet, retries, and gets the data. Settlement is on chain. Per the API's notes, the first payment settles immediately and later small calls accrue to a $1.00 tab.

See the 402 yourself (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}]}'
  1. Discover. Read /.well-known/x402.json: payable routes, network eip155:8453, asset USDC, pay-to address.
  2. Ask. Call a paid route. You get HTTP 402 and a base64 payment-required header with the exact amount.
  3. Pay. Sign an x402 exact payment from your wallet and retry the same request with it.
  4. Receive. HTTP 200 and the data.

Payable routes listed in the manifest: GET /v1/data?dataset=weather&details=true, POST /v1/weather/batch, POST /v1/portfolio/risk. A standard x402 client does steps 2 to 4 for you. Python (needs pip install "x402[httpx,evm]" eth-account):

x402_example.py (needs a funded wallet)
import asyncio, os
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

URL = "https://data.truefixr.com/v1/weather/batch"
BODY = {"locations": [{"lat": 32.78, "lon": -96.80}]}

async def main():
    acct = Account.from_key(os.environ["EVM_PRIVATE_KEY"])   # a small, separate wallet
    client = x402Client()
    register_exact_evm_client(client, EthAccountSigner(acct))
    async with x402HttpxClient(client) as http:
        r = await http.post(URL, json=BODY)                  # 402, pay, retry: all inside
        await r.aread()
        print(r.status_code, r.text[:300])

asyncio.run(main())
Use a small, separate wallet holding a few cents of USDC, and keep its private key in an environment variable on your own machine. Never paste a private key into chat, code you share or a web form. This snippet follows the official x402 buyer client and the structure published by the API. It was not run here, because running it spends real USDC: test with a small wallet first.

GetFixn sells data, not trading advice. Nothing here is investment advice. Forecasts can be wrong. You are responsible for your own strategies and for following the rules of any exchange or market you use.

Prediction-market bots and paying agents

Two common setups. Both only fetch data. Neither places an order.

  • Prediction-market bot (Kalshi-style weather contracts). Fetch live weather, hours_ahead forecasts and county forecast grades for the cities you trade, write them to a file and let your own model read it. Working code in four languages: recipe 12. The free tier covers it.
  • Agent with a wallet. Skip the key and pay per call in USDC on Base with x402. See x402 below and recipe 13.

GetFixn sells data, not trading advice. Nothing here is investment advice. Forecasts can be wrong. You are responsible for your own strategies and for following the rules of any exchange or market you use. No exchange endorses or partners with GetFixn. Heavy or commercial volume? Email admin@truefixr.com.

Caching and good habits

  • Preview first. Every paid pull has a free preview with the exact price. Read it in code and stop if it is higher than you expect.
  • Cap spend with limit. limit=25 on a paid pull is a hard ceiling on records.
  • Cache by full URL. Forecasts refresh 4 times a day, live weather hourly. Minutes for weather, an hour or more for forecasts, a day for history.
  • Throttle loops. One call per second keeps free previews under 60 a minute.
  • Retry politely. Back off on 429 and 5xx. Never retry a 402.
  • Label it honestly. In your own UI call it "reported and radar-detected storms" and "forecast risk, what could happen", never as damage assessments.

Working code for each of these: errors and spend caps, caching, rate limiting.

Changelog

  1. GetFixn launched. Buy a key from $50, examples, starter kit and docs for builders.