METAR & NWS Weather Station Observations API avatar

METAR & NWS Weather Station Observations API

Pricing

from $0.50 / 1,000 observation records

Go to Apify Store
METAR & NWS Weather Station Observations API

METAR & NWS Weather Station Observations API

Hourly METAR/ASOS airport weather by ICAO code or US lat/lon, up to 30 days back: temp, dewpoint, wind, ceiling, visibility, flight category, raw METAR. NOAA aviationweather.gov + Iowa State ASOS archive. Same stations Kalshi/Polymarket weather markets name. No API key.

Pricing

from $0.50 / 1,000 observation records

Rating

0.0

(0)

Developer

Jack Sheward

Jack Sheward

Maintained by Community

Actor stats

0

Bookmarked

64

Total users

10

Monthly active users

7 days ago

Last modified

Share

METAR & NWS Weather Station Observations API

Pull raw METAR strings and hourly ASOS/NWS weather station observations for any ICAO station (KORD, KJFK, KLAX, EGLL…), any US lat/lon point, or a Kalshi city name. Each report is decoded into clean JSON: temperature (°F and °C), dewpoint, wind and gusts, altimeter, ceiling, visibility, flight category (VFR/MVFR/IFR/LIFR), and the 6-hour and 24-hour max/min temperature groups. You get up to 7 days of live reports including SPECI specials, and up to 30 days of hourly history per station.

These are the airport observations that aviation tools and weather dashboards use. Kalshi and Polymarket weather contracts also name these stations in their rules. The data comes from official public sources (aviationweather.gov and the Iowa State Mesonet ASOS archive), not scraped weather websites that break.

Need one number per day instead of every report? Set output to daily-summary and get one row per station per local day with the day's high, low, precipitation and snowfall: the official NWS Daily Climate Report for US stations, and a max/min computed from METAR observations for everywhere else. See Daily summary mode.

Unofficial. Not affiliated with NOAA/NWS, the FAA, Kalshi or Polymarket.

What you get

One record per station per observation:

FieldExampleNotes
station_idKNYCICAO code
station_nameNew York/Central Park, NY, USnull for archive rows
lat, lon40.779, -73.9692
utc_time2026-09-24T04:51:00Zactual observation time
temp_f, dewpoint_f55.0, 42.1
wind_dir, wind_speed_kt50, 9
ceiling_ftnulllowest broken/overcast layer (null = no ceiling)
visibility_sm10statute miles
flight_categoryVFRFAA categories
metar_rawMETAR KNYC 240451Z AUTO 05009G15KT …the report exactly as published
sourceaviationweather.govor mesonet-asos-archive
obs_time1790225460same instant as utc_time, as Unix seconds
report_typeMETARMETAR (routine) or SPECI (special report)
temp_c, dewpoint_c12.8, 5.6tenths of °C when the METAR has a T-group
wind_gust_kt15null when no gust was reported
altimeter_hpa1031.9altimeter setting in hPa
max_temp_6h_f, min_temp_6h_f64.9, 54.06-hour max/min groups (US reports at 00/06/12/18Z)
max_temp_24h_f, min_temp_24h_f66.9, 55.024-hour max/min group (US report nearest local-standard-time midnight)

The 6-hour and 24-hour groups only appear in some reports (mostly US), so these fields are null on the rest. Export as JSON, CSV or Excel directly from the dataset. The Temperatures dataset view shows the temperature columns side by side.

Output example

A real record from a run on 2026-09-24 ({"stationIds": ["KNYC"]}). This Central Park report is the one that carries the 24-hour max/min group:

{
"station_id": "KNYC",
"station_name": "New York/Central Park, NY, US",
"lat": 40.779,
"lon": -73.9692,
"utc_time": "2026-09-24T04:51:00Z",
"temp_f": 55.0,
"dewpoint_f": 42.1,
"wind_dir": 50.0,
"wind_speed_kt": 9.0,
"ceiling_ft": null,
"visibility_sm": 10.0,
"flight_category": "VFR",
"metar_raw": "METAR KNYC 240451Z AUTO 05009G15KT 10SM CLR 13/06 A3047 RMK AO2 SLP310 T01280056 401940128",
"source": "aviationweather.gov",
"obs_time": 1790225460,
"report_type": "METAR",
"temp_c": 12.8,
"dewpoint_c": 5.6,
"wind_gust_kt": 15.0,
"altimeter_hpa": 1031.9,
"max_temp_6h_f": null,
"min_temp_6h_f": null,
"max_temp_24h_f": 66.9,
"min_temp_24h_f": 55.0
}

Input

{
"stationIds": ["KNYC", "KMDW", "Miami"],
"latLon": [{ "lat": 40.78, "lon": -73.97 }],
"hoursBack": 24
}
  • stationIds: 4-letter ICAO codes, up to 50 per run (extra codes are skipped with a warning). Case and separators don't matter ("kord, kjfk" works), and 3-letter US codes like ORD or JFK get the K prefix automatically. FAA identifiers with a digit (57C, T35) come from the Mesonet archive. Kalshi city names also work and map to the station that city's Kalshi market settles on. Examples: NYC/New York → KNYC (Central Park), Chicago → KMDW (Midway, not O'Hare), Houston → KHOU (Hobby), Dallas → KDFW. Miami, Austin, Los Angeles, Denver, Philadelphia and the other Kalshi cities work the same way, as do Kalshi's non-US cities (London → EGLL, Paris → LFPG, Tokyo → RJTT, Toronto → CYYZ and others). Kalshi tickers work too: KXHIGHCHI, KXLOWTNYC or a full market ticker such as KXHIGHTDAL-26SEP25-B80.5 (→ KDFW). The run's status message lists each mapping.
    • Airport codes and airport names are never remapped: ORD stays KORD, and DAL is Dallas Love Field (the status message points out that Kalshi's Dallas markets use KDFW).
    • A city and one of its other airports in the same item mean that airport: "Chicago O'Hare" → KORD only, "New York LaGuardia" → KLGA only. List the city as its own item (["Chicago", "O'Hare"]) to get both.
    • If you leave this empty and send no coordinates, you get KORD.
  • latLon: optional US-only points. Each one resolves to the nearest official observation station through the NWS registry (api.weather.gov). {"lat", "lon"} objects, [lat, lon] pairs and latitude/longitude keys all work. For points outside the US, pass the station's ICAO code instead. A run with only coordinates returns only those stations.
  • hoursBack: 1 to 720 (default 24). Up to 168h (7 days) comes from aviationweather.gov: live data, including SPECI special reports. Longer lookbacks come from the Iowa State Mesonet ASOS archive: routine hourly reports, up to the latest observation.
  • fields: optional list to slim the output, e.g. ["temp_f", "max_temp_24h_f"]. station_id and utc_time are always kept. Casing and separators are flexible (tempC, temp-c). Unknown names are skipped with a warning. With output: "daily-summary" the names are the summary fields instead (see below).
  • output: observations (default: everything above, unchanged) or daily-summary (one row per station per local day).
  • dateFrom, dateTo: YYYY-MM-DD station-local days for daily-summary only (today and yesterday also work). Ignored, with a warning, in observations mode.

Input problems and upstream hiccups never crash the run. Unusable values are skipped, transient API errors are retried, and the run's status message says what was returned and lists any warnings, such as an unknown station code. Large requests are split so that no aviationweather.gov response hits its 400-row limit, so reports are not silently dropped. If your Maximum cost per run is too low for even one record, the run stops before fetching anything and charges nothing.

Daily summary mode

Set output to daily-summary to get one row per station per station-local calendar day instead of one row per report:

{
"stationIds": ["KNYC", "KMDW", "KLAX", "EGLC"],
"output": "daily-summary",
"dateFrom": "2026-09-20",
"dateTo": "2026-09-26"
}

That returns 28 rows (4 stations × 7 days). Leave both dates empty to use hoursBack: the station-local days that overlap the last N hours (the default 24 hours gives yesterday and today). With only dateFrom the range runs through today; with only dateTo it is that single day. A run covers at most 366 days and 50 stations. City names, tickers and latLon work exactly as in the observation mode.

Where the numbers come from

sourceStationsValues
nws_cliUS stations with an NWS climate report, including every Kalshi US city (KNYC, KMDW, KLAX ...)The official NWS Daily Climate Report (CLI), read through the Iowa State Mesonet: high, low and their times, precipitation, snowfall, plus the day's normals and records.
metar_derivedEverything else: international airports (EGLC, RJTT, EGLL ...) and US stations without a climate reportThe highest and lowest temperature among that local day's METAR/ASOS reports (routine and special), with obs_count and a complete flag.

The two are not the same measurement. A CLI day runs midnight to midnight in local standard time (1 AM to 1 AM clock time while daylight time is in force) and its high and low come from the station's full-resolution sensor. A metar_derived day is the plain local calendar day (clock midnight to midnight, DST-aware) and its extremes are the warmest and coldest report, so the true peak can sit a little beyond them. International airports report whole °C, so their high_f values move in 1.8 °F steps; high_c is the exact reading.

Output example

A real row from a run on 2026-10-01 (nws_cli, Central Park):

{
"record_type": "daily_summary",
"station_id": "KNYC",
"station_name": "NEW YORK CITY",
"date": "2026-09-25",
"timezone": "America/New_York",
"source": "nws_cli",
"high_f": 69.0,
"high_c": 20.6,
"high_time": "2026-09-25T19:28:00Z",
"low_f": 55.0,
"low_c": 12.8,
"low_time": "2026-09-26T03:28:00Z",
"precipitation_in": 0.08,
"precipitation_trace": false,
"snowfall_in": 0.0,
"snowfall_trace": false,
"high_normal_f": 73.0,
"high_record_f": 90.0,
"high_record_years": [1970],
"low_normal_f": 59.0,
"low_record_f": 40.0,
"low_record_years": [1887],
"precipitation_normal_in": 0.14,
"precipitation_record_in": 2.36,
"precipitation_record_years": [1940],
"snowfall_normal_in": 0.0,
"snowfall_record_in": 0.0,
"snowfall_record_years": [2001, 2002],
"obs_count": null,
"complete": true,
"note": null,
"product_id": "202609260616-KOKX-CDUS41-CLINYC",
"product_issued_utc": "2026-09-26T06:16:00Z",
"source_url": "https://mesonet.agron.iastate.edu/api/1/nwstext/202609260616-KOKX-CDUS41-CLINYC",
"caveat": "Official NWS/METAR record, not a settlement source. Kalshi temperature markets resolve per The Weather Company and Polymarket per Wunderground; either can differ from this value by about a degree."
}

A metar_derived row has the same fields. London City on 2026-09-20 reads high_f 68.0, high_c 20.0, high_time 2026-09-20T12:50:00Z, low_f 57.2, obs_count 48, complete true; precipitation, snowfall, normals and records are null because METAR reports do not carry them.

Fields

FieldNotes
record_typedaily_summary, or notice for the free notice rows below
station_id, station_nameThe station code you asked for; the name comes from the NWS report or the Mesonet station list (null for some stations)
date, timezoneThe station-local calendar day and the IANA zone used for its boundaries
sourcenws_cli or metar_derived
high_f, high_c, low_f, low_cDaily high and low. CLI values are whole °F; high_c is converted
high_time, low_timeWhen it happened, in UTC (ISO 8601). The NWS prints local standard time and the actor converts it. During daylight time a low at "11:59 PM" standard time is 12:59 AM the next clock day, so its UTC date can be the day after date. For metar_derived it is the first report that reached the extreme
precipitation_in, snowfall_inInches (CLI only). A trace (T) is 0.0 with the matching *_trace flag true. null when the report has no value, such as snowfall at stations that do not measure it
high_normal_f, high_record_f, high_record_years, low_normal_f, low_record_f, low_record_years1991-2020 normals and the record for that calendar date (CLI only)
precipitation_normal_in, precipitation_record_in, precipitation_record_years, snowfall_normal_in, snowfall_record_in, snowfall_record_yearsSame, for precipitation and snowfall (CLI only; a record of T is 0.0)
obs_countmetar_derived: reports with a temperature that day. null for nws_cli
complete, noteWhether the day is finished and well covered, and why not (below)
product_id, product_issued_utc, source_urlnws_cli: the NWS product the row was read from and a link to its raw text. metar_derived: source_url is the archive request
caveatThe prediction-market caveat below, on every row

fields works here too (for example ["high_f", "low_f", "complete"]); record_type, station_id, date and source are always kept. Names are the ones in the table, with high, low, precip and snow as shortcuts.

Partial days are marked, never dropped

complete is false when:

  • nws_cli: the row is the preliminary report the NWS office issues during the day (so today's row, from about 4 PM local). The final report arrives after midnight local standard time and can differ. The row's note says so.
  • metar_derived: the local day has not ended yet, or the reports have a hole longer than 3 hours (a late first report or an early last one counts too). The note gives the reason, for example longest gap between observations 5.5 h. Compare obs_count with the station's usual rate (24 for hourly, 48 for half-hourly reporting).

A day with no usable data at all gets a notice row, not a row of nulls. Nothing is estimated or filled in.

Notice rows

Problems come back as free rows with record_type: "notice", a notice_code, the station_id, the affected dates and a message, so a run never ends in an error:

notice_codeMeaning
unsupported_stationThe code is not in the Mesonet station list (or a latLon point is outside the US)
future_datesDays after the station's local today; nothing exists yet
range_too_large, date_out_of_rangeMore than 366 days, or before 1900. Nothing is fetched
cli_missingThe NWS issued no climate report for those days, or has not yet (today's report appears in the afternoon)
no_observationsA derived station has no temperature reports for those days
upstream_error, time_budgetA Mesonet request failed or the run's time ran out; only the days it covered are missing
charge_limitMaximum cost per run was reached
inputPart of your input was ignored (invalid station code, unknown field name, unknown key)

Mesonet requests are spaced about one second apart, so a large run takes a while (50 stations take a few minutes). A run that returns only notices is charged nothing, not even the run start.

Kalshi and Polymarket caveat

These values are the official NWS and METAR record. They are not the settlement source of a prediction market. Kalshi temperature markets resolve per The Weather Company (the rules name the NWS CLI station), and Polymarket per Wunderground (or the source a market's rules name). Either can differ from the NWS value by about a degree, and day boundaries can differ too. Always check the market's own rules. The same warning is in the caveat field of every row.

Pricing

Pay per event, with no subscription. Prices from October 15, 2026 (until then an observation record costs $0.0005 and daily summary rows are free):

EventPrice
Actor start (once per run)$0.005
Observation record (one row in the dataset)$0.001 ($0.0009 on Apify Scale plans, $0.0008 on Business)
Daily summary record (one station-day row, output: "daily-summary")$0.001

Daily summary mode bills one daily summary record per summary row delivered, plus the actor start once the first row is returned. Notice rows are free, and a daily-summary run that returns no summary rows is not charged at all.

A record is one report, so the count depends on how often the station reports. Most US airports issue one routine METAR an hour, plus SPECI special reports when the weather changes. Many airports outside the US (London EGLL, Paris LFPG) report every 30 minutes, and some US automated stations every 20 minutes. What typical runs cost at the October 15 prices (counts from live runs on 2026-09-24):

RunRecordsCost
1 US airport, 24h (KORD, KNYC)24–34about $0.03–0.04
1 station reporting every 30 min, 24h (EGLL)about 48about $0.05
1 station reporting every 20 min, 24h (KMWC, Milwaukee Timmerman)about 72about $0.08
7 Kalshi settlement stations, 24h (KNYC, KMDW, KAUS, KMIA, KLAX, KPHL, KDEN)180about $0.19
2 US airports, 7 days (KORD 260 + KMDW 215)about 475about $0.48
EGLL, 7 days336about $0.34
10 US airports, 30 days (archive, hourly)about 7,200about $7.21
Daily summaries, 3 US stations, 7 days21about $0.03

You pay only for records delivered to your dataset. To cap a run's cost, set Maximum cost per run: the run stops at that amount and keeps what it already returned. fields shrinks each row but does not change the price. Platform usage is included in these prices.

Why this instead of scraping a weather website?

  • Primary sources. aviationweather.gov and the ASOS archive carry the same observations NWS publishes, and every record includes the raw METAR for auditability.
  • No scrape fragility. Public JSON/CSV APIs, not HTML scraping that breaks on redesigns.
  • The station in the contract. For weather derivatives or prediction-market positions you want the observations from the station named in the rules, not a weather app's interpolated value.

FAQ

Which stations are supported?

Any ICAO station that reports METAR. Lookbacks up to 7 days come live from aviationweather.gov, which covers stations worldwide. Deeper history (8–30 days) comes from the Iowa State Mesonet archive, which covers every US ASOS station (K-prefix) and many international airports, London Heathrow (EGLL) included. If aviationweather.gov has nothing for a station, or is down, that station is looked up in the Mesonet archive instead. This is how FAA identifiers like 57C return data, and the status message says so.

How fresh is the data?

aviationweather.gov observations typically appear within minutes of the station report.

Can I get the exact raw METAR string?

Yes. Every record carries metar_raw exactly as published.

Why do I get more than 24 records for 24 hours?

Two reasons. First, stations issue SPECI special reports between routine METARs when the weather changes. They are real observations, and report_type marks them. Second, not every station reports once an hour: many airports outside the US (EGLL, LFPG) issue a routine METAR every 30 minutes, and some US automated stations every 20 minutes. Keeping only report_type: "METAR" removes the specials, but at those stations it still leaves two or three routine reports an hour. Lookbacks longer than 7 days come from the archive and contain routine reports only.

How do I use this for Kalshi daily high/low temperature markets?

Each Kalshi temperature market names one NWS climate station in its rules, for example CLINYC (Central Park, KNYC) or CLIMDW (Chicago Midway, KMDW). Kalshi's current rules resolve on that station's daily max/min as reported by The Weather Company (weather.com/kalshi), so this actor is not the settlement source. Pass the city name ("Chicago"), the series or market ticker ("KXHIGHCHI") or the station code ("KMDW") with hoursBack: 24 to watch the same station.

Treat the max of hourly temp_f as a proxy that can read low. The official daily max is the highest reading over the whole day, and the peak often falls between hourly reports. The max_temp_6h_f groups cover those gaps, and the max_temp_24h_f group in the report nearest local-standard-time midnight is the closest METAR-side match to the daily value. It still isn't the settlement number. Traps: Chicago settles on Midway (KMDW), not O'Hare; Dallas on DFW (KDFW), not Love Field; Houston on Hobby (KHOU), not Bush.

For the official daily number itself, use daily summary mode: for the Kalshi US cities it returns that day's NWS Daily Climate Report (the report the rules name) with the high, low, their times and precipitation. That is the official NWS record, still not the settlement source (The Weather Company), so expect differences of about a degree. Today's row is the preliminary afternoon report and is marked complete: false.

Holding a Kalshi bracket? The Prediction Market Resolution Evidence Checker takes a market ticker or URL and grades the bracket against the live observation.

And Polymarket temperature markets?

Polymarket names its own station, and it is often a different airport from Kalshi's: NYC is LaGuardia (KLGA) on Polymarket but Central Park (KNYC) on Kalshi, and Chicago is O'Hare (KORD) rather than Midway. As of 2026-09-24, most Polymarket temperature markets resolve on the highest hourly "Temp" reading on NOAA's weather.gov time-series page for that station, with Wunderground as the fallback. A few markets resolve on Wunderground directly. Pull the station code from the market's rules (for example "KLGA", not "NYC", since city names here follow Kalshi) and compare against the routine hourly reports. Pasting the rules' own wording also works: "Chicago O'Hare Intl Airport Station" is read as KORD only. Always check the market's own rules for the station and the day boundary. Daily summary mode takes any station code too, so a market whose rules name London City Airport needs EGLC (the London city name here maps to Heathrow, EGLL); international stations return a metar_derived max/min per local calendar day, which is the closest official-record match to a Wunderground daily high.

What are max_temp_6h_f and max_temp_24h_f?

US METARs carry remark groups with the highest and lowest temperature since an earlier time. The 1snTTT/2snTTT groups give the 6-hour max/min in the 00, 06, 12 and 18 UTC reports, and the 4snTTTsnTTT group gives the 24-hour max/min in the report nearest local-standard-time midnight. The actor decodes them from metar_raw in tenths of °C and converts to °F. Reports without the group return null, not 0.

Does it work for a lat/lon with no airport nearby?

Yes, for US points. latLon resolves through the official NWS station registry to the nearest observing station. The registry covers the US only; elsewhere, use the airport's ICAO code.

Use with AI agents (MCP)

Connect your agent to the Apify MCP server (mcp.apify.com) and it can call this actor as a tool. Ask for "the latest METAR observations at KNYC" or "hourly temperatures in Chicago for the last 24 hours" and the agent fills in the input schema (stationIds, hoursBack) itself. Ask for "the official daily high and low for Chicago for the last week" and it sets output to daily-summary with dateFrom and dateTo. City names are accepted directly. The actor works as a ground-truth weather lookup for trading agents, aviation assistants and research pipelines. Keep fields short (for example ["temp_f", "max_temp_6h_f", "report_type"]) to keep responses small.

Optional: Claude-powered question & summary

Two optional inputs use Anthropic's Claude API. Both are off by default. When you don't use them, runs, rows and prices are exactly as before. The actor's owner pays for the Claude calls, so the Claude call itself costs you nothing. The rows your question asks for are billed at the normal per-row prices: check the ai_question notice and set Maximum cost per run. When you use these inputs, your question and up to 60 of this run's data rows are sent to Anthropic's API for processing; don't put personal data in the question.

  • question (text): describe what you want in plain English, e.g. "daily highs and lows in Chicago and NYC for the last week" or "last 12 hours at JFK". Claude turns it into this actor's own inputs (stationIds, output, dateFrom, dateTo, hoursBack). The answer is held to a JSON schema of those fields and then checked by the same validation as typed input. Inputs you set yourself always win (except output: "observations", which is the default and counts as unset): in the Console form, clear the prefilled Station IDs and Hours of history if you want the question to set them. A free notice row (notice_code: "ai_question") shows how the question was read.
  • aiSummary (true/false): after the data rows are delivered, Claude writes a summary of up to about 120 words in one free notice row (notice_code: "ai_summary"; it shows in the Observations and Daily summary views and in the JSON). It works from at most 60 rows, spread over the stations, and the notice says when it saw only a sample. The summary is advisory: it runs after the rows are pushed and can't change them, and it is told to report only what the rows say, with no forecasts and no market or betting calls. The rows stay the source of truth. It is written by Claude, not by NOAA/NWS, and is not official NWS information.

If Claude is unavailable (no API key configured, rate limit, timeout, refusal, an unusable answer, or too little run time left), the feature is skipped, the notice row says why, and the run continues with your explicit or default inputs. A Claude problem never fails a run. If your Maximum cost per run is too low to return any row, the question is not sent to Claude at all.

More prediction-market data actors

Changelog

2026-10-07

  • New optional inputs question (plain English → this actor's inputs) and aiSummary (a short plain-English summary of the delivered rows), both powered by Claude and off by default. The Claude calls add no billing events or price changes; rows fetched for a question are billed as usual. Runs that don't use them are unchanged.

2026-10-01

  • Prices from October 15, 2026: $0.001 per observation record (lower on Scale and Business plans) and $0.001 per daily summary record; daily summaries are free until then.
  • New daily summary mode: set output to daily-summary (new dateFrom/dateTo inputs; hoursBack is used when no dates are given) to get one row per station per station-local day. US stations with an NWS climate report return the official NWS Daily Climate Report (source nws_cli: high, low, times, precipitation, snowfall, normals, records); other stations return a max/min computed from METAR observations (metar_derived, with obs_count and a complete flag). Partial days are marked, missing days and bad stations become free notice rows.
  • Billing: one new event, daily summary record, per summary row. Notice rows are free and a daily-summary run that returns no summary rows is not charged. Observation mode, its input, output and billing are unchanged (output defaults to observations).
  • New Daily summary dataset view. New dependency: tzdata (station-local days need a time zone database).

2026-09-25

  • Up to 7 days (168h) of live aviationweather.gov data, including SPECI reports (was 72h). 169–720h still comes from the Iowa State Mesonet archive. Billing note: 73–168h lookbacks used to return the archive's routine reports. They now return the live feed, which includes SPECI reports and every 20- or 30-minute routine report, so the same request can return more records than before (KORD 100h: 130, was 100; EGLL 120h: 240, was 121). Set Maximum cost per run to cap spend.
  • Stations aviationweather.gov has no reports for, or cannot serve because it is down, are looked up in the Mesonet archive. FAA identifiers such as 57C or T35 keep returning data at every lookback.
  • Archive requests cover up to 5 stations each (was 1), so there are fewer requests to the Mesonet and fewer rate-limit retries on large runs. The records are identical.
  • Requests are planned further below aviationweather.gov's 400-row limit. If a single station's window still hits the limit (possible with 7-day pulls), it is refetched in smaller time windows instead of losing its oldest reports, and the run warns if anything could still be missing.
  • New output fields, added after the existing ones: obs_time, report_type, temp_c, dewpoint_c, wind_gust_kt, altimeter_hpa, max_temp_6h_f, min_temp_6h_f, max_temp_24h_f, min_temp_24h_f. Existing fields are unchanged.
  • Kalshi city names in stationIds (and city/cities input keys) map to the settlement station, e.g. Chicago → KMDW, NYC → KNYC, London → EGLL. Kalshi tickers (KXHIGHCHI, KXHIGHTDAL-26SEP25-B80.5) and Kalshi's own city codes (CHI, PHIL, MIN) map the same way. A city named together with one of its other airports ("Chicago O'Hare") gives only that airport. If two keys for the same input are sent (say stationIds and city), only one is used (stationIds wins) and the status message names the one ignored.
  • New Temperatures dataset view, input-schema field suggestions, and FAQ entries for Kalshi (The Weather Company settlement) and Polymarket (station per market).

2026-09-24

  • Multi-station requests are split so that no aviationweather.gov response hits its 400-row limit. A 20-station, 24-hour pull now returns every report; it was cut off at 400 rows before.
  • A run with only latLon no longer adds KORD. KORD is used only when neither stations nor coordinates are given.
  • Reliability fixes: lenient input parsing (strings, 3-letter codes, nested lists, aliases), retries with backoff on upstream 429/5xx, utc_time set to the actual observation time, NaN-safe values, and a status message that explains empty results instead of failing the run.