Docs · API Reference

AvioWeather API

REST API for aviation weather data. METAR, TAF, SIGMET, historic archive — sourced from NOAA AWC (current) and Iowa State ASOS (historic), fully decoded, served from a 5-minute global snapshot in eu-west-1 (Ireland).

Overview

The API is read-only, JSON over HTTPS, and authenticated with a single header. Base URL:

https://api.developer.avioweather.app

All endpoints live under /v1/. We never break v1 — additive changes only. When we do introduce breaking changes, they ship under /v2/ and v1 stays running for at least 12 months.

Authentication

Send your API key in the X-API-Key request header. Keys have the format ak_live_v2.<payload>.<signature> (signed; validated at the edge) and are generated from the developer portal after you create an account and choose a plan.

curl https://api.developer.avioweather.app/v1/metar/LIRF \
  -H "X-API-Key: ak_live_v2.xxxxxxxx~pro~000.xxxxxxxx"
Key safety: the plaintext key is shown once at generation time. We only store its SHA-256 hash — we cannot recover a lost key, only revoke it and issue a new one.
Key lifecycle: a key is valid for 12 months from creation, after which it returns KEY_EXPIRED — generate a new one from the portal. The plan tier is signed into the key, so any plan change revokes every existing key immediately — upgrade, downgrade, cancellation or refund, whether you change it yourself or an admin does. After a plan change, generate a fresh key from the portal; it carries the new tier. Both revoked and expired keys are rejected at the edge with 401.

Plans & limits

Each plan has a daily request cap. When the cap is reached, calls return 429 until 00:00 UTC the next day. There is no automatic overage. Paid plans include every endpoint — they differ only by volume.

PlanDaily requestsEndpoints
free300METAR (single + batch), station, usage
pro — €7.99/mo50,000All endpoints
business — €15.99/mo250,000All + priority support
enterprise — €37.99/mo500,000All + ~99.9% uptime target

Use GET /v1/usage to check remaining quota. That endpoint authenticates against your key but does not count toward the daily quota.

Hit your cap? Upgrading gives instant headroom. If you reach your daily cap and upgrade, you don't have to wait for the 00:00 UTC reset: the cap lifts as soon as you regenerate your key at the new tier (a plan change revokes your old keys, so you regenerate anyway — see Authentication). The limit then re-applies only if you exceed the new, higher cap. This holds at every step — free → pro → business → enterprise.

Errors

Errors come back as JSON with a stable code field — match on the code, not the human-readable error string.

StatusCodeMeaning
401NO_KEYX-API-Key header missing
401BAD_KEYKey not recognized
401REVOKEDKey revoked by admin or self-service (also on any plan change)
401KEY_EXPIREDKey older than 12 months — generate a new one
400BAD_REQUESTMalformed parameters (e.g. bad date format)
400RANGE_TOO_LARGEHistory range exceeds 60 days
403FEATURE_NOT_AVAILABLEEndpoint requires a higher plan (returned by the edge tier gate; the origin may also return TIER_INSUFFICIENT)
404NOT_FOUNDNo current METAR published for that airport, or unknown ICAO
429QUOTA_EXCEEDEDDaily request cap reached — retry after reset_iso (00:00 UTC), or upgrade and regenerate your key for instant headroom
502UPSTREAM_ERRORUpstream source (NOAA/Iowa) failed; retry with backoff
5xxInternal failure; safe to retry with exponential backoff

The 429 QUOTA_EXCEEDED response carries the reset time so you know when to retry — it's returned at the edge for every endpoint (including /v1/usage) while you're over the cap:

{
  "code": "QUOTA_EXCEEDED",
  "reset_iso": "2026-05-25T00:00:00Z",
  "message": "Daily quota reached. Resets at 00:00 UTC; upgrade for instant headroom."
}

GET /v1/metar/{icao}

GET /v1/metar/{icao} free+

Returns the most recent METAR for the given ICAO airport, fully decoded. Served from the 5-minute pipeline snapshot (the same data the AvioWeather apps consume); falls back to a live NOAA fetch if the station is not in the current snapshot. source tells you which path answered.

Path parameters

icao
string Four-letter ICAO code, e.g. LIRF. Case-insensitive.

Example response

{
  "icao": "LIRF",
  "name": "Roma Fiumicino",
  "latitude": 41.8, "longitude": 12.24, "elevation_m": 5,
  "raw": "LIRF 191420Z 22008G18KT 9999 FEW040 SCT100 17/09 Q1018",
  "observed_at": "2026-05-19T14:20:00Z",
  "flight_category": "VFR",
  "wind": { "direction_deg": 220, "variable": false, "speed_kt": 8, "gust_kt": 18 },
  "visibility": { "statute_miles": 6.21, "meters": 9999, "or_more": true },
  "clouds": [ { "cover": "FEW", "base_ft": 4000, "modifier": null }, { "cover": "SCT", "base_ft": 10000, "modifier": null } ],
  "weather": [],
  "temperature_c": 17, "dewpoint_c": 9,
  "altimeter_hpa": 1018, "sea_level_pressure_hpa": null,
  "source": "pipeline", "age_seconds": 95
}

Each cloud layer carries a modifier: "CB" (cumulonimbus) or "TCU" (towering cumulus) when the raw observation tags that layer convective, otherwise null — e.g. { "cover": "OVC", "base_ft": 400, "modifier": "CB" }. NOAA omits this from its structured feed, so we recover it from the raw text: it is present on every METAR path (this endpoint, the batch endpoint, and history) and is always null on TAF forecast layers (which carry no per-period raw text).

GET /v1/metar?icao=…

GET /v1/metar?icao=A,B,C free+

Batch METAR for up to 20 ICAOs in a single call, resolved from one snapshot read. A batch call costs 1 request against your daily quota, regardless of how many ICAOs you pass. Unknown ICAOs come back as { "icao": "XXXX", "error": "NOT_FOUND" } in the array rather than failing the whole request. The icao list is case-insensitive, order-independent, and deduplicated — LIRF,EGLL and egll, lirf, EGLL return the same result and hit the same cache entry.

Query parameters

icao
string Comma-separated ICAO codes. Maximum 20 per request — any codes beyond the first 20 (after dedup) are dropped, not rejected.
{ "count": 3, "metars": [ { "icao": "LIRF", … }, … ] }

GET /v1/station/{icao}

GET /v1/station/{icao} free+

Station metadata (name, coordinates, elevation) plus the latest flight category and observation time.

{
  "icao": "LIRF", "name": "Roma Fiumicino",
  "latitude": 41.8, "longitude": 12.24, "elevation_m": 5,
  "flight_category": "VFR", "last_observation_at": "2026-05-19T14:20:00Z",
  "source": "pipeline"
}

GET /v1/taf/{icao}

GET /v1/taf/{icao} pro+

Current TAF (terminal aerodrome forecast), raw plus decoded forecast periods (wind, visibility, clouds, weather, change indicator).

{
  "icao": "LIRF",
  "raw": "TAF LIRF 201700Z 2018/2124 30013KT CAVOK BECMG 2022/2024 04006KT …",
  "issued_at": "2026-05-20T17:00:00.000Z",
  "valid_from": "2026-05-20T18:00:00Z",
  "valid_to": "2026-05-22T00:00:00Z",
  "forecast": [
    {
      "from": "2026-05-20T18:00:00Z",
      "to": "2026-05-20T22:00:00Z",
      "change_indicator": null,
      "probability": null,
      "wind": { "direction_deg": 300, "variable": false, "speed_kt": 13, "gust_kt": null },
      "visibility": { "statute_miles": 6.0, "meters": 9656, "or_more": true },
      "clouds": [ { "cover": "NSC", "base_ft": null, "modifier": null } ],
      "weather": [ "NSW" ],
      "wind_shear": null
    }
  ]
}

GET /v1/sigmet

GET /v1/sigmet?near=LIRF&radius=100&hazard=TS pro+

Active SIGMETs worldwide, parsed: canonical hazard tag plus the affected-area polygon as [lat, lon] rings. With no query parameters it returns every active SIGMET (US domestic + international). All parameters below are optional and can be combined.

Query parameters

near
string ICAO of a reference airport. Combined with radius, returns only SIGMETs whose area is within range of it (the point is inside the polygon, or the boundary is within the radius). Requires radius.
radius
number Radius in nautical miles (1–1000) around near. Requires near.
hazard
string Filter by hazard tag (case-insensitive): TS, CONVECTIVE, TURB, ICE, VA, IFR, MTN OBSCN.
{
  "count": 1,
  "near": "LIRF", "radius_nm": 100,
  "sigmets": [
    {
      "id": "-39021139160",
      "type": "SIGMET",
      "hazard": "TS",
      "raw_text": "CONVECTIVE SIGMET 9W … AREA EMBD TS MOV FROM 29020KT. TOPS TO FL330.",
      "valid_from": "2026-05-20T19:55:00Z",
      "valid_to": "2026-05-20T21:55:00Z",
      "coordinates": [ [48.5, -109.2], [48.9, -106.1], … ]
    }
  ]
}

GET /v1/metar/{icao}/history

GET /v1/metar/{icao}/history?from=YYYY-MM-DD&to=YYYY-MM-DD pro+

Every decoded METAR observed for the station across a UTC date range (max 60 days per request). The 60-day cap is per call, not the depth of the archive: history reaches back roughly 20 years — to go further back, request consecutive 60-day windows by shifting the from/to dates. Served from the durable archive; missing days are backfilled on demand from Iowa State ASOS (open data) and cached. Each observation has the same decoded shape as GET /v1/metar/{icao}, including the per-layer cloud modifier ("CB"/"TCU"/null).

Query parameters

from
string UTC start day YYYY-MM-DD.
to
string UTC end day YYYY-MM-DD (inclusive).
{
  "icao": "LIRF", "from": "2026-05-01", "to": "2026-05-07",
  "count": 336, "sources": ["iowa"],
  "observations": [
    {
      "icao": "LIRF", "name": "Rome/Fiumicino, RM, IT",
      "latitude": 41.8, "longitude": 12.239, "elevation_m": 2,
      "raw": "METAR LIRF 010020Z 27007KT CAVOK 19/16 Q1021",
      "observed_at": "2026-05-01T00:20:00Z", "flight_category": "VFR",
      "wind": { "direction_deg": 270, "variable": false, "speed_kt": 7, "gust_kt": null },
      "visibility": { "statute_miles": 6.21, "meters": 9999, "or_more": true },
      "clouds": [], "weather": [],
      "temperature_c": 19, "dewpoint_c": 16,
      "altimeter_hpa": 1021, "sea_level_pressure_hpa": null
    },
    {
      "icao": "LIRF", "name": "Rome/Fiumicino, RM, IT",
      "latitude": 41.8, "longitude": 12.239, "elevation_m": 2,
      "raw": "METAR LIRF 011220Z 20015G27KT 2000 +TSRA BKN015CB OVC025 22/20 Q1009",
      "observed_at": "2026-05-01T12:20:00Z", "flight_category": "IFR",
      "wind": { "direction_deg": 200, "variable": false, "speed_kt": 15, "gust_kt": 27 },
      "visibility": { "statute_miles": 1.24, "meters": 2000, "or_more": false },
      "clouds": [ { "cover": "BKN", "base_ft": 1500, "modifier": "CB" }, { "cover": "OVC", "base_ft": 2500, "modifier": null } ],
      "weather": ["+TSRA"],
      "temperature_c": 22, "dewpoint_c": 20,
      "altimeter_hpa": 1009, "sea_level_pressure_hpa": null
    }
  ]
}

GET /v1/usage

GET /v1/usage all plans · free of quota

Returns the remaining daily quota for the calling account (usage is metered per account across all its keys). Does not decrement the counter.

{
  "tier": "pro",
  "quota": 50000,
  "used": 12483,
  "remaining": 37517,
  "reset_iso": "2026-05-21T00:00:00Z",
  "period": "day"
}

Data sources & attribution

Current observations and forecasts are sourced from the NOAA Aviation Weather Center / National Weather Service (USA); historic METARs from the Iowa Environmental Mesonet (Iowa State University) ASOS archive. Both are public-domain / open-data sources. Applications redistributing this data must credit the original source — e.g. "Weather data via AvioWeather (NOAA AWC / Iowa State ASOS)". Use of the API is also subject to the Terms & Conditions and Acceptable Use Policy. Weather data is provided "as is" for situational awareness and is not a substitute for an official pre-flight briefing.

© 2026 Savaresi Aviation · billing@savaresi.aero · last updated 2026-06-06