A daily and seasonal forecast API for the contiguous US. Every value returns as a calibrated distribution — mean, sigma, and confidence bands we verify in public — with the source named on every number. Price a weather risk, size a position, or schedule a crew against the full distribution, not a point estimate.
{ "succeeded": true, "data": { "station_id": "NYC", "network": "NY_ASOS", "daily": [ { "date": "2026-06-21", "kind": "high", "prediction_interval": { // p50 is the point estimate "p10": 77.7, "p25": 80.2, "p50": 82.1, "p75": 84.0, "p90": 86.5, "sigma": 3.4 }, "provenance": { "source": "nws+climo_sigma", "model_cycle": "12Z", "station_id": "NYC", "network": "NY_ASOS" } } ], "generated_at": "2026-06-20T18:22:04Z" }, "credits_remaining": 9847.0 }
Live forecast explorer Every forecast is a distribution. Hover any of the 19 calibration stations for the live high and low you'd plan against — sun, sky, and precipitation show typical climatology for now.
Hover or tap a station to read its forecast distribution
Calibration receipts
Walk-forward over six years × nineteen contiguous-US stations × daily high and low temperatures. No data leakage: for each evaluated day, σ was fit on records strictly before that day. Most weather APIs ship a number. We ship the number, the confidence range around it, and the proof the range is honest.
91.0%
Empirical coverage
on nominal 90% intervals — target 90%
80.9%
Empirical coverage
on nominal 80% intervals — target 80%
0.7 pp
Calibration error
mean |empirical − nominal| over both bands
What you get
A single forecast number isn't enough to plan against. Theta Weather returns the full picture: a central estimate, a confidence range, and the source the value came from, in one consistent response shape across six endpoints.
Every value carries a mean, a standard deviation, and a p05–p95 confidence interval calibrated against decades of station observations. The verification endpoint lets you replay the model against historical windows so the bands stop being a black box.
Every day in every response identifies the source, the Weather Forecast Office covering the location, and the model cycle that produced it. When the engine falls back to climatology, the response says so. No silent substitutions.
Forecasts pull from the same gridpoint guidance the NWS publishes, station by station, the same source emergency managers and broadcasters rely on. Climatology and a 30-year observational baseline cover what the forecast cycle doesn't.
Endpoints
All endpoints return the same confidence-range envelope and the same source fields, so you write the integration once. Credit cost scales with how much work the request does. Coverage is the contiguous US for v0; Alaska, Hawaii, and US territories are on the roadmap.
Worked example
A point forecast can't answer "what are the odds the high lands between 86 and 88°F?" A calibrated distribution can — integrate it over the bracket. That one line is how traders price temperature markets, how utilities weight load scenarios, and how parametric products set triggers. The calibration record is what makes the number usable: probability from an uncalibrated distribution is just formatting.
# P(lo <= high_f < hi) from one /v1/forecast/point response from math import erf, sqrt def bracket_p(mu, sigma, lo, hi): cdf = lambda x: 0.5 * (1 + erf((x - mu) / (sigma * sqrt(2)))) return cdf(hi) - cdf(lo) # from the response above: prediction_interval.p50 and .sigma pi = r["data"]["daily"][0]["prediction_interval"] bracket_p(pi["p50"], pi["sigma"], 86.0, 88.0) # => 0.084 — an 8.4% bracket
Docs
Six POST endpoints, one auth header, one response envelope. No SDK required and no client library to wait on — if you can send JSON, you are done.
Send your key as the X-Theta-Key header on every request. Keys are shown once, at mint time, in your account. There is no OAuth flow and no token exchange.
# Base URL https://api.weather.oasis-x.io curl -X POST https://api.weather.oasis-x.io/v1/forecast/point \ -H "X-Theta-Key: $THETA_KEY" \ -H "Content-Type: application/json" \ -d '{"body": {"station_id": "NYC", "horizon_days": 7}}' # Note the "body" wrapper — request fields go inside it, on every # endpoint. Sending them at the top level returns 422 with # {"loc": ["body","body"], "msg": "Field required"}.
Every endpoint accepts either station_id (with optional network), or a lat/lon pair that we snap to the nearest covered station. Coverage is the contiguous US in v0. The station we actually used is echoed back in provenance, so a snapped coordinate is never ambiguous.
kind ("high" or "low", default "high"), start_date, end_date
Returns days[], each with climo_value_f, residual_sigma_f, a prediction_interval, provenance, and n_history_records.
1 credit
horizon_days (default 7)
Returns daily[] with a calibrated prediction_interval per day, plus hourly[]. Hourly points carry a raw NWS value with prediction_interval: null and provenance.source: "nws_hourly_uncalibrated" — the calibration is daily, and we will not dress up an hourly number as calibrated.
1 credit
kind, horizon_months (1–12, default 3)
Returns monthly mean_f with a prediction_interval per period.
2 credits
kind, start_date, end_date, window_days (default 30)
Returns observations[] with value_f, quality_flag and source — the same ASOS record we calibrate against — plus a rolling summary of the trailing window_days. Every plan gets n, mean, sigma, min, max. Basic and above also get skew, kurtosis, p25, p75, iqr, and may set window_days. On the free plan the window is served at 30 and rolling_window_days tells you so — we will not quietly summarise a different span than you asked for.
5 credits
window_a_start/end, window_b_start/end, optional granger_station_id, granger_max_lag (default 7), include_mixture
Returns tests with Kolmogorov–Smirnov, Mann–Whitney and one-way ANOVA — each carrying a statistic, a p-value and the question it answers. ANOVA also states its assumptions, so when it disagrees with Mann–Whitney you know which to trust.granger_station_id and you also get granger, tested in both directions. The series are deseasonalized first and the lag is chosen by AIC; both are reported. Each result carries measured_false_positive_rate — we measured our own method at 9% against a nominal 5%, and 100% without the deseasonalization step, so you can size how much to trust a p-value.include_mixture for a 1–3 component Gaussian fit per window, chosen by AIC, with weights, means, sigmas, the AIC of every candidate, and a KS goodness-of-fit. Components are returned unlabelled on purpose: naming one "trend" or "ENSO" would be a claim about the atmosphere, not a property of the fit.
10 credits
kind, start_date, end_date
Our receipts. Each row pairs the forecast interval with actual_value_f, residual_f, and the booleans in_p80 / in_p90. The response closes with rolling_coverage_p80, rolling_coverage_p90, and rolling_calibration_error. Check our numbers yourself, over any window you like.
10 credits
Every success returns { succeeded, message, data, credits_remaining }. The endpoint-specific payload is always under data. Your running balance also comes back in the X-Theta-Credits-Remaining response header, so you can track burn without a side-channel counter. Every calibrated value is a prediction_interval: p10, p25, p50, p75, p90 always, with p05, p95, and sigma where available. p50 is the point estimate — if you want a single number, that is the one.
X-Theta-Key header. Revoked keys also return 401.
no charge
error: insufficient_credits means top up, feature_not_in_tier means upgrade. Both carry current_tier and an upgrade URL; the second also names the feature and the required_tier. Nothing is debited on either — a request we refuse is a request you do not pay for.
no charge
Pricing
The calibrated intervals, the per-day provenance and the verification receipts are the same on every plan, free included — we would rather you evaluate the real thing than a crippled version of it. What the paid tiers add is call volume, more keys, and the statistical surface area on top: higher moments from Basic, window comparison and mixture fits from Pro. Credits debit per call, weighted by endpoint cost. Plans renew monthly; unused credits do not roll over. Full breakdown on the pricing page.
Free
$0 /mo
Basic
$29 /mo
Pro
$99 /mo
Team
$499 /mo
Enterprise
Custom
Pick a sign-in email and password. You'll get your first key on the next screen, ready to call the five core endpoints right away — window comparison is on Pro and up.
Your API key (shown once — copy it now):
Send it as the X-Oasis-Weather-Key header on requests to
.