AIRMET/SIGMET
AIRMETs and SIGMETs are official aviation weather advisories for hazardous en-route conditions. AIRMET (Airmen's Meteorological Information) covers moderate hazards; SIGMET (Significant Meteorological advisory) covers higher-severity events. This endpoint returns every active advisory whose affected area intersects your bounding box — use it for en-route hazard overlays on maps and pre-flight briefings. Filter with type=airmet or type=sigmet when you only need one severity class. Empty results (no active advisories) are normal and very common in good weather.
Request
Requirements
x-api-key on every request (direct subscription). Learn more →Send a GET with a geographic bounding box and optional type filter.
https://data.skylinkapi.com/v3/weather/airsigmet| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
bbox | string | Yes | - | Bounding box as lat1,lon1,lat2,lon2 — southwest corner first. Example: 38,-90,45,-80 (Midwest corridor) |
type | string | No | all | Filter: airmet or sigmet. Omit to return both |
Bounding box tips. Keep boxes route-sized — very large bboxes can stress upstream processing. An empty reports array means no active advisories intersect the area (common in fair weather).
Response
{
"bbox": "38.0,-90.0,45.0,-80.0",
"filter_type": "airmet",
"reports": [
{
"raw": "WAUS46 KKCI 151445 WA6S AIRMET SIERRA ...",
"bulletin_type": "AIRMET",
"report_type": "AIRMET",
"country": "US",
"issuer": "KKCI",
"area": "S",
"region": "KZAU",
"start_time": "2025-01-15T14:45:00Z",
"end_time": "2025-01-15T20:45:00Z",
"body": "AIRMET IFR...",
"observation": {
"type": "IFR",
"intensity": null,
"floor": "SFC",
"ceiling": "FL180",
"coords": [
{ "lat": 41.5, "lon": -87.5 },
{ "lat": 42.0, "lon": -86.0 }
],
"movement": null
},
"forecast": null
}
],
"total": 1
}When no advisories intersect the bbox, the API returns "reports": [] and "total": 0.
| Field | Type | Required | Description |
|---|---|---|---|
bbox | string | Yes | Echo of the queried bounding box |
reports | array | Yes | Matching advisories (may be empty) |
total | integer | Yes | Count of items in reports |
filter_type | string | null | Yes (key always present) | Filter applied: "airmet", "sigmet", or null when unfiltered |
Report
JSON path: reports[]. Only raw is guaranteed non-null. All decoded fields are null when not parsed from the advisory.
| Field | Type | Required | Null? | Description |
|---|---|---|---|---|
raw | string | Yes | Never | Full advisory text as issued |
bulletin_type | string | null | Yes (key always present) | Yes | "AIRMET" or "SIGMET" |
report_type | string | null | Yes (key always present) | Yes | Advisory type, e.g. "AIRMET", "SIGMET", "CONVECTIVE SIGMET" |
country | string | null | Yes (key always present) | Yes | Issuing country code, e.g. "US" |
issuer | string | null | Yes (key always present) | Yes | Issuing authority identifier, e.g. "KKCI" |
area | string | null | Yes (key always present) | Yes | Affected area identifier, e.g. "S" (Sierra) |
region | string | null | Yes (key always present) | Yes | Flight Information Region (FIR) or region code, e.g. "KZAU" |
start_time | string | null | Yes (key always present) | Yes | Valid from (UTC, ISO 8601) |
end_time | string | null | Yes (key always present) | Yes | Valid until (UTC, ISO 8601) |
body | string | null | Yes (key always present) | Yes | Human-readable advisory body text |
observation | object | null | Yes (key always present) | Yes | Observed hazard details — see Observation and forecast |
forecast | object | null | Yes (key always present) | Yes | Forecast hazard details — same shape as observation. null when not present |
Object schemas and nullability
Every key in a Report object is always present — nothing is omitted when a section is not decoded. The observation and forecast objects themselves may be null, but when present every key inside them is always included.
| Situation | What you get | Not this |
|---|---|---|
| No hazard polygon decoded | observation.coords: [] | null, key missing |
| No forecast section | forecast: null | key missing |
| No observation section | observation: null | key missing |
| Advisory has no altitude floor | observation.floor: null | key missing or "0" |
| No movement information | observation.movement: null | {}, key missing |
| No active advisories | reports: [], total: 0 | null, HTTP error |
| Unfiltered request | filter_type: null | key missing |
AIRMET families
| Family | Hazards covered |
|---|---|
| SIERRA | IFR conditions, mountain obscuration |
| TANGO | Moderate turbulence, strong surface winds |
| ZULU | Moderate icing, freezing levels |
SIGMETs cover higher-intensity en-route hazards. Convective SIGMETs are issued for severe thunderstorms, hail, and tornadoes over the contiguous US.
Observation and forecast schemasExpand section
JSON path: reports[].observation and reports[].forecast (same shape). Present when decoded from the advisory; null otherwise.
| Field | Type | Required | Null? | Description |
|---|---|---|---|---|
type | string | null | Yes (key always present) | Yes | Phenomenon type — IFR (instrument conditions), TURB (turbulence), ICE (icing), VA (volcanic ash) |
intensity | string | null | Yes (key always present) | Yes | Intensity token, e.g. "MOD", "SEV" |
floor | string | null | Yes (key always present) | Yes | Lower altitude bound, e.g. "SFC", "FL100" |
ceiling | string | null | Yes (key always present) | Yes | Upper altitude bound, e.g. "FL180", "FL450" |
coords | array | Yes | Never | Polygon vertices for map rendering. [] when no boundary is decoded |
coords[].lat | number | Yes (per item) | Never | Vertex latitude |
coords[].lon | number | Yes (per item) | Never | Vertex longitude |
movement | object | null | Yes (key always present) | Yes | Advisory movement — direction and speed strings when present; null when stationary or not reported |
Client types
"""AIRMET/SIGMET response types - matches airsigmet field tables."""from dataclasses import dataclass, field@dataclassclass AirSigmetCoord: lat: float lon: float@dataclassclass AirSigmetObservation: type: str | None = None intensity: str | None = None floor: str | None = None ceiling: str | None = None coords: list[AirSigmetCoord] = field(default_factory=list) movement: dict | None = None@dataclassclass AirSigmetReport: raw: str bulletin_type: str | None = None report_type: str | None = None start_time: str | None = None end_time: str | None = None body: str | None = None observation: AirSigmetObservation | None = None forecast: AirSigmetObservation | None = None@dataclassclass AirSigmetResponse: bbox: str reports: list[AirSigmetReport] total: int filter_type: str | None = NoneIntegration
Fetch active advisories for a route bbox and build polygon overlays.
The example queries a corridor bbox, caches for 15 minutes (advisories update on a fixed schedule), and extracts advisory polygons with valid time windows for map rendering. Empty results are expected in VFR conditions — render "no active advisories," not an error.
import osimport timeimport requestsHEADERS = { "x-api-key": os.getenv("SKYLINK_API_KEY", "YOUR_API_KEY")}BASE = "https://data.skylinkapi.com/v3"CACHE: dict[str, tuple[dict, float]] = {}AIRSIG_TTL = 900 # 15 mindef fetch_airsigmets(bbox: str, advisory_type: str | None = None) -> dict: cache_key = f"airsig:{bbox}:{advisory_type or 'all'}" cached = CACHE.get(cache_key) if cached and time.time() < cached[1]: return cached[0] params: dict[str, str] = {"bbox": bbox} if advisory_type: params["type"] = advisory_type r = requests.get( f"{BASE}/weather/airsigmet", headers=HEADERS, params=params, timeout=(10, 25), ) r.raise_for_status() data = r.json() CACHE[cache_key] = (data, time.time() + AIRSIG_TTL) return datadef active_polygons(bbox: str) -> list[list[tuple[float, float]]]: """Return coord rings for map overlays (may be empty).""" payload = fetch_airsigmets(bbox, advisory_type="airmet") rings: list[list[tuple[float, float]]] = [] for report in payload.get("reports", []): obs = report.get("observation") or {} coords = obs.get("coords") or [] if coords: rings.append([(c["lat"], c["lon"]) for c in coords]) return ringsif __name__ == "__main__": import json bbox = "-74.5,40.3,-73.5,41.0" payload = fetch_airsigmets(bbox, "airmet") print(json.dumps(payload, indent=2, default=str)[:3000])Implementation notes
Empty is normal. Fair-weather routes often return total: 0. Your map layer can hide overlays when empty.
Validity windows. Use start_time and end_time to expire polygons client-side. Do not show advisories past end_time even if cached. If end_time is null, treat the advisory as active until the next poll.
Polygon rendering. Draw observation.coords (or forecast.coords) as closed polygons. When coords is [], show the body text in a list view instead of a map overlay. Always close the polygon ring (last vertex → first vertex) before passing to a mapping library.
Filter strategically. Pre-flight briefing UIs often fetch type=airmet for dispatch and type=sigmet for higher-severity overlays. Omit type when you need the full picture.
Large bboxes. Size the query to your route plus a modest buffer (approximately 1–2° latitude/longitude) and split long routes into segments if needed.
Error responses
Endpoint-specific failures only. For auth, validation, rate limits, and server errors, see Error Handling.
400 — invalid bbox format
{
"detail": "Invalid bounding box format. Expected 'lat1,lon1,lat2,lon2'"
}503 — upstream unavailable
Returned when the advisory feed is temporarily unreachable or the bbox is too large for upstream processing. Retry with exponential backoff and a smaller bbox.
{
"detail": "Upstream AIRMET/SIGMET service unavailable"
}Your SkyLink licence key, for keys bought direct from skylinkapi.com.
In: header
Query Parameters
Bounding box as 'lat1,lon1,lat2,lon2' (SW corner → NE corner)
Filter by type: 'airmet' or 'sigmet'
^(airmet|sigmet)$Response Body
application/json
application/json
curl -X GET "https://data.skylinkapi.com/v3/weather/airsigmet?bbox=string"{
"bbox": "38,-90,45,-80",
"reports": [
{
"raw": "WAUS46 KKCI 151445 WA6S AIRMET SIERRA ...",
"bulletin_type": "AIRMET",
"report_type": "AIRMET",
"area": "S",
"body": "AIRMET IFR...",
"observation": {
"type": "IFR",
"floor": "SFC",
"ceiling": "FL180"
}
}
],
"total": 1
}{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string",
"input": null,
"ctx": {}
}
]
}Related: Weather hub · PIREPs · METAR · AIRMET route use case