DEV Community

Geo
Geo

Posted on

METAR and TAF for any ICAO airport: aviation weather as a JSON API (official NOAA data, no API key)

If your app touches aviation — preflight planning, drone operations, dispatch dashboards, flight-sim scenery, or AI training data — you need METAR and TAF weather reports, and you need them as data, not as text to scrape off a website. This tutorial shows how to get decoded METAR observations and TAF forecasts for any list of ICAO airports from the official NOAA aviation weather API through a pay-per-use REST endpoint, with real output from a live run.

What METAR and TAF are

A METAR is an observation: what the weather station at an airport reports right now — wind, visibility, clouds, temperature, dew point, altimeter, and an FAA/ICAO flight category (VFR/MVFR/IFR/LIFR). A TAF is a forecast: expected conditions at that airport over the coming ~24-30 hours, broken into periods with change times (FM, BECMG, TEMPO).

The authoritative US source is NOAA's Aviation Weather API at aviationweather.gov — public US-government data, anonymous access, no API key. The hard parts are turning the compact raw text (METAR EGLL 131320Z 32008KT 9999 -RA FEW010 BKN020 15/13 Q1006) into structured fields your pipeline can consume, staying polite to a shared public service, and handling the awkward cases (unknown stations, stations without TAFs, multiple observations per station).

Quick start: three airports, both report types

The METAR & TAF Aviation Weather API wraps that NOAA source. Call it with a list of ICAO codes:

{
  "icaoIds": ["KJFK", "KLAX", "EGLL"],
  "reportTypes": "both",
  "hoursBeforeNow": 2,
  "maxConcurrency": 2
}
Enter fullscreen mode Exit fullscreen mode
  • icaoIds — required; codes are trimmed, uppercased, deduplicated.
  • reportTypes — metar, taf, or both (default both).
  • hoursBeforeNow — 0-24 hours of METAR history to request (0 = latest only). Never sent to the TAF endpoint, which always returns the current forecast.
  • maxConcurrency — 1-5 (default 2).

All stations are combined into one NOAA request per report type, so a run requesting METAR + TAF makes at most two source requests no matter how many airports are in the batch.

What you get back

A successful run stores one dataset row per report returned by NOAA. A real METAR row (trimmed for brevity) from a live run against EGLL:

{
  "recordType": "data",
  "reportType": "metar",
  "stationId": "EGLL",
  "stationName": "London/Heathrow Intl, EN, GB",
  "observationTime": "2026-09-08T13:20:00.000Z",
  "tempC": 15,
  "dewpointC": 13,
  "windDir": 320,
  "windSpeedKt": 8,
  "visibility": "6+",
  "altimeter": 1006,
  "flightCategory": "MVFR",
  "wxString": "-RA",
  "cloudLayers": [
    {"cover": "FEW", "baseFt": 1000},
    {"cover": "BKN", "baseFt": 2000}
  ],
  "latitude": 51.477,
  "longitude": -0.461,
  "rawOb": "METAR EGLL 131320Z 32008KT 9999 -RA FEW010 BKN020 15/13 Q1006",
  "fetchTimestamp": "2026-09-08T13:43:03.874Z"
}
Enter fullscreen mode Exit fullscreen mode

A TAF row carries issuanceTime, validFrom/validTo, and a forecast array of periods — each with fromTime/toTime, plus decoded wind, visibility, clouds, and (when NOAA supplies them) change type, probability, gusts, wind shear, altimeter, vertical visibility, weather, icing, turbulence, and temperature data:

{
  "recordType": "data",
  "reportType": "taf",
  "stationId": "KLAX",
  "issuanceTime": "2026-09-08T11:33:00.000Z",
  "validFrom": "2026-09-08T12:00:00.000Z",
  "validTo": "2026-09-09T18:00:00.000Z",
  "forecast": [
    {
      "fromTime": "2026-09-08T12:00:00.000Z",
      "toTime": "2026-09-08T17:00:00.000Z",
      "windDir": "VRB",
      "windSpeedKt": 3,
      "visibility": "6+",
      "cloudLayers": [{"cover": "SCT", "baseFt": 25000}]
    }
  ],
  "rawOb": "TAF KLAX ...",
  "fetchTimestamp": "2026-09-08T13:43:03.874Z"
}
Enter fullscreen mode Exit fullscreen mode

Every data row keeps the raw report text in rawOb so nothing the source said is lost. Decoded fields reflect NOAA's current API response and may be absent when the source omits them.

Calling it from code

Every Apify actor is a REST API. Start a run with your Apify API token:

curl -X POST "https://api.apify.com/v2/acts/gp005~metar-taf/runs" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"icaoIds":["KJFK","KLAX","EGLL"],"reportTypes":"both","hoursBeforeNow":2}'
Enter fullscreen mode Exit fullscreen mode

Then download the run's dataset as JSON, CSV, Excel, or XML. That makes the actor scriptable into flight-planning, drone-preflight, dispatch, or routing workflows — or schedule it with an Apify cron expression for recurring METAR snapshots, and point a webhook at run completion. The actor is also reachable through Apify's MCP server and from no-code tools like Make, n8n, or Zapier.

What a run costs

Pay-per-event, no subscription. At the current Store rates:

Event Price
Run start (actor-start) $0.005
Report served (report-served, per data row) $0.003

A smoke run of the canonical input above (KJFK/KLAX/EGLL, both report types, 2 hours of METAR history) returned 11 report rows — 8 METAR (history can include several observations per station) and 3 TAF:

$0.005 + 11 × $0.003 = $0.038

Apify's free plan includes platform credits, so most first runs are effectively free. Pricing is set by the publisher and may change — check the Store listing before running at scale.

Gotchas

  • Multiple METAR rows per station are normal. With hoursBeforeNow: 2, a busy station can return several observations. Request 0 for only the most recent.
  • Not every station issues a TAF, and NOAA silently omits unknown ICAO codes — if a station is missing from results, check the spelling.
  • International coverage exists but US stations dominate; availability outside CONUS is thinner and intermittent. NOAA provides no SLA for this public endpoint.
  • No historical TAFs. The actor requests the current TAF; hoursBeforeNow applies only to METAR observations.
  • Decoded fields are advisory. For operational decisions, always review the rawOb text alongside NOTAMs and official guidance. Don't use this as the sole source for safety-critical go/no-go calls.

FAQ

Does this need a NOAA API key?

No. The official Aviation Weather API supports anonymous requests. The only credential you need is your Apify API token, which you already have if you use the platform.

Is it scraping aviationweather.gov?

No. It calls the documented JSON data endpoints directly — no HTML pages, no browser. NOAA aviation weather data is US-government public data.

Can I request non-US airports?

Yes, where NOAA has METAR or TAF coverage — e.g. EGLL, YSSY. Availability outside the United States varies by station, and not every station issues a TAF.

Can I get historical TAFs?

No. This actor requests the current TAF forecast; the history setting (hoursBeforeNow) applies only to METAR observations.

The actor is live on Apify: https://apify.com/gp005/metar-taf

Top comments (0)