polyweather OpenAPI
Programmatic access to live, minute-by-minute observed airport temperatures — the same sub-hourly runway-sensor data that leads the official METAR — plus today's-high tracking, METAR history and our next-METAR nowcast, across 30+ airports. JSON over HTTPS, rolling window only.
Base URL
https://www.polyweather.today/api/open/v1
Authentication
Send your key in the Authorization header. Requests must come from an IP bound to the key, or you get 403 ip_not_allowed (the response's detail shows the detected IP — bind that one). Manage keys in the developer console.
Authorization: Bearer pmw_live_xxxxxxxx
Plans & limits
| Plan | Price | Rate | Monthly | IPs / key | Access |
|---|---|---|---|---|---|
| Basic | $49/mo | 60/min | 100,000 | 1 | cities, latest, window, daily-high, metar |
| Pro | $99/mo | 300/min | 1,000,000 | 3 | + nowcast, multi-city latest |
Every response carries X-RateLimit-Remaining / X-RateLimit-Remaining-Month; a 429 includes Retry-After. {city} = ICAO (ZBAA) or slug (beijing); °C, UTC ISO-8601.
Quick start
curl -s "https://www.polyweather.today/api/open/v1/weather/ZBAA/latest" \ -H "Authorization: Bearer pmw_live_your_key"
Code examples
import requests
BASE = "https://www.polyweather.today/api/open/v1"
KEY = "pmw_live_your_key" # create at https://www.polyweather.today/developers
headers = {"Authorization": f"Bearer {KEY}"}
# Latest observation for Beijing (runway temp leads the METAR)
r = requests.get(f"{BASE}/weather/ZBAA/latest", headers=headers, timeout=10)
r.raise_for_status()
d = r.json()
print(d["runway_temp_c"], "->", d["metar_temp_c"], "high", d["daily_high_c"])
# Next-METAR nowcast (Pro)
nc = requests.get(f"{BASE}/weather/ZBAA/nowcast", headers=headers).json()["nowcast"]
print(nc["pred_int"], "p", nc["p_hit"], nc["light"])const BASE = "https://www.polyweather.today/api/open/v1";
const KEY = "pmw_live_your_key"; // create at https://www.polyweather.today/developers
const headers = { Authorization: `Bearer ${KEY}` };
// Latest observation for Beijing (runway temp leads the METAR)
const res = await fetch(`${BASE}/weather/ZBAA/latest`, { headers });
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const d = await res.json();
console.log(d.runway_temp_c, "->", d.metar_temp_c, "high", d.daily_high_c);
// Next-METAR nowcast (Pro)
const { nowcast } = await (await fetch(`${BASE}/weather/ZBAA/nowcast`, { headers })).json();
console.log(nowcast.pred_int, "p", nowcast.p_hit, nowcast.light);Endpoints
List supported cities and their codes.
{
"count": 16,
"cities": [
{
"code": "ZBAA",
"slug": "beijing",
"name": "Beijing",
"airport": "Beijing Capital International Airport",
"beta": false
}
]
}code ICAO code — use as {city} in other callsslug also accepted as {city}name city nameairport airport full namebeta true = newer station, less-calibrated nowcastNewest observation for one city.
{
"city": "ZBAA",
"name": "Beijing",
"runway_temp_c": 30.6,
"runway_at": "2026-06-22T06:08:00Z",
"metar_temp_c": 31,
"metar_at": "2026-06-22T06:00:00Z",
"daily_high_c": 31,
"daily_high_at": "2026-06-22T06:00:00Z",
"yesterday_high_c": 31,
"conditions": {
"wind_dir": 140,
"wind_kt": 8,
"gust_kt": 22,
"sky": "FEW",
"sky_cover": 1,
"visibility_km": 10,
"pressure_hpa": 1005,
"dewpoint_c": 16
},
"source": "noaa",
"generated_at": "2026-06-22T06:10:26Z"
}runway_temp_c latest minute-level runway-sensor mean (°C) — leads the METARrunway_at time of that runway reading (UTC)metar_temp_c latest official METAR temperature (whole °C)metar_at METAR observation time (UTC)daily_high_c today's running daily high — the number markets settle ondaily_high_at when today's high was reached (UTC)yesterday_high_c yesterday's daily high (context)conditions observed wind/sky/visibility/pressure/dewpoint — each field present only when reportedsource METAR source: noaa | amscgenerated_at snapshot build time (UTC)Rolling minute-by-minute series. Window only — no history beyond it.
limit — points to return, default 90, max 120{
"city": "ZBAA",
"name": "Beijing",
"window_minutes": 90,
"runway_ends": ["01", "18L", "18R", "19", "36L", "36R"],
"count": 3,
"points": [
{
"at": "2026-06-22T06:08:00Z",
"ends": { "19": 30.6, "18R": 30.2, "36L": 30.8 },
"mean": 30.6
}
]
}window_minutes rolling window length — only the last ~90 min is exposedrunway_ends this airport's runway-end labelscount number of points returnedpoints[].at minute timestamp (UTC), newest firstpoints[].ends per-runway-end temperature (°C)points[].mean average across endsToday's running high so far.
{
"city": "ZBAA",
"name": "Beijing",
"daily_high_c": 31,
"peaked_at": "2026-06-22T06:00:00Z",
"hourly_settlement": false,
"generated_at": "2026-06-22T06:10:26Z"
}daily_high_c today's running max (°C) — the settlement numberpeaked_at time of that high (UTC)hourly_settlement true = only on-the-hour readings count (e.g. Chengdu)Recent METARs (parsed temp + raw text).
limit — count, default 8, max 24{
"city": "ZBAA",
"name": "Beijing",
"metars": [
{
"at": "2026-06-22T06:00:00Z",
"temp_c": 31,
"raw": "METAR ZBAA 220600Z 14008KT 9999 FEW040 31/16 Q1005",
"source": "noaa"
}
]
}metars[].at observation time (UTC)metars[].temp_c METAR temperature (°C)metars[].raw raw METAR textmetars[].source data sourceNext-METAR forecast: prediction, probability distribution, decision light.
{
"city": "ZBAA",
"name": "Beijing",
"nowcast": {
"model": "anchor-v2",
"pred_int": 31,
"pred_float": 30.85,
"h_min": 22,
"next_metar_at": "2026-06-22T06:30:00Z",
"p_hit": 0.551,
"ladder": [
{ "t": 30, "p": 0.256 },
{ "t": 31, "p": 0.551 },
{ "t": 32, "p": 0.168 }
],
"light": "yellow"
},
"slope_30": 0.17,
"regime": "flat",
"forecast": {
"high_c": 32.4,
"peak_hour_local": "15:00",
"cloud_pct_peak": 45,
"models": [ { "name": "ECMWF", "high": 31.5 } ],
"tomorrow_high_c": 33
}
}nowcast.pred_int predicted NEXT METAR, rounded (°C)nowcast.pred_float predicted, unroundednowcast.h_min horizon: minutes until the next METARnowcast.next_metar_at expected next METAR time (UTC)nowcast.p_hit calibrated probability pred_int is exactly rightnowcast.ladder full probability distribution: { t: temp, p: probability }nowcast.light decision light green / yellow / red (signal reliability)slope_30 runway-temp slope, °C per 30 min (signed)regime flat | mid | fastforecast Open-Meteo model guidance: high_c, peak_hour_local, cloud_pct_peak, models[], tomorrow_high_cEvery city's latest in one call.
{
"count": 16,
"generated_at": "2026-06-22T06:10:26Z",
"cities": [
{
"city": "ZBAA",
"name": "Beijing",
"runway_temp_c": 30.6,
"metar_temp_c": 31,
"daily_high_c": 31,
"daily_high_at": "2026-06-22T06:00:00Z"
}
]
}cities[] per city: runway_temp_c, metar_temp_c, daily_high_c, daily_high_atErrors
| HTTP | error | Meaning |
|---|---|---|
| 401 | missing_api_key / invalid_api_key / key_revoked | Bad or missing Authorization header. |
| 402 | no_active_api_plan | Plan lapsed — renew at /developers. |
| 403 | ip_not_allowed | Request IP isn't allowlisted. The detected IP is in `detail` — bind that IP. |
| 403 | plan_upgrade_required | Endpoint needs API Pro (nowcast, multi-city). |
| 404 | unknown_city / unknown_resource | Check the path. |
| 429 | rate_limited | Per-minute or monthly cap hit — see Retry-After. |
Getting started
API access is a paid add-on. Open the developer console to buy a plan (crypto, instant) and create an IP-locked key — your plan also unlocks the full web dashboard.
View-only data — not betting or financial advice. Rolling-window access; historical bulk export is not offered.