Save up to 17% with yearly billing

See pricing

METAR

METAR (регулярные метеорологические сводки по аэродрому) — это наблюдения за приземной погодой на конкретном аэродроме или станции. Стандартные сводки METAR выпускаются через регулярные интервалы (обычно каждый час или каждые полчаса), а специальная сводка (SPECI) выпускается при значительном изменении условий на станции с персоналом. Каждая сводка METAR содержит ключевые метеорологические данные: температуру, скорость и направление ветра, видимость, облачность и атмосферное давление. Пилоты, авиадиспетчеры, диспетчеры по обеспечению полётов и метеорологи используют эти сводки для оценки погоды в аэропорту при планировании полётов, навигации и принятии оперативных решений.

Запрос

Требования

Авторизация
x-api-key в каждом запросе (прямая подписка). Подробнее →
ICAO
4-буквенный код аэропорта (например, KJFK). Коды аэропортов США обычно начинаются с K. Подробнее →

Отправьте запрос GET с кодом ICAO аэропорта в пути. Необязательные query-флаги управляют декодированием.

GEThttps://data.skylinkapi.com/v3.1/weather/metar/{icao}
ПараметрТипОбязательныйПо умолчаниюОписание
icaostringДа-Четырёхбуквенный код ICAO — поиск, например KJFK
parsedbooleanНетfalseДобавить декодированные поля под ключом parsed

Ответ

Исходный ответ (по умолчанию)

{
  "raw": "METAR KJFK 062251Z 24017G23KT 10SM FEW060 FEW075 SCT110 BKN180 BKN250 28/17 A2974 RMK AO2 SLP072 T02830167 $",
  "icao": "KJFK",
  "airport_name": "John F. Kennedy International Airport",
  "timestamp": "2026-06-06T23:09:37Z"
}
ПолеТипОбязательныйОписание
rawstringДаПолная строка METAR в исходном виде
icaostringДаКод ICAO
airport_namestringДаНазвание аэропорта
timestampstring (ISO 8601)ДаВремя получения данных API — не время наблюдения

Декодированный ответ (parsed=true)

{
  "raw": "METAR KJFK 062251Z 24017G23KT 10SM FEW060 FEW075 SCT110 BKN180 BKN250 28/17 A2974 RMK AO2 SLP072 T02830167 $",
  "icao": "KJFK",
  "airport_name": "John F. Kennedy International Airport",
  "timestamp": "2026-06-06T23:09:37Z",
  "parsed": {
    "time": "2026-06-07T00:51:00+02:00",
    "wind": {
      "direction": 240,
      "speed": 17,
      "gust": 23,
      "variable": []
    },
    "visibility": {
      "value": 10,
      "repr": "10"
    },
    "clouds": [
      { "type": "FEW", "base": 60, "repr": "FEW060" },
      { "type": "FEW", "base": 75, "repr": "FEW075" },
      { "type": "SCT", "base": 110, "repr": "SCT110" },
      { "type": "BKN", "base": 180, "repr": "BKN180" },
      { "type": "BKN", "base": 250, "repr": "BKN250" }
    ],
    "temperature": 28,
    "dewpoint": 17,
    "altimeter": 29.74,
    "flight_rules": "VFR",
    "wx_codes": [],
    "remarks": "RMK AO2 SLP072 T02830167 $",
    "density_altitude": 1792,
    "pressure_altitude": 193,
    "relative_humidity": 0.49
  }
}
ПолеТипОбязательныйОписание
parsedobjectДа (при parsed=true)Отсутствует при parsed=false — а не равен null
parsed.timestring (ISO 8601)ДаВремя наблюдения из заголовка METAR — используйте его для определения возраста данных, а не timestamp
parsed.wind.directionintegerДаГрадусы (истинные). 0 при штиле или если направление не сообщается
parsed.wind.speedintegerДаУзлы. Никогда не null — 0 означает штиль
parsed.wind.gustinteger | nullДа (ключ присутствует всегда)Узлы. null, если порывов нет (а не 0)
parsed.wind.variableinteger[]ДаДиапазон направлений при переменном ветре, например [180, 270]. [], если ветер не переменный
parsed.visibility.valuenumber | nullДа (ключ присутствует всегда)Сухопутные мили. null для P6SM (> 6 SM) — трактуйте как «> 6»
parsed.visibility.reprstringДаИсходный токен из METAR
parsed.cloudsarrayДаСлои от нижнего к верхнему. [] при ясном небе
parsed.clouds[].typestringДа (для каждого элемента)Коды облачности
parsed.clouds[].baseintegerДа (для каждого элемента)Сотни футов AGL. 60 = 6000 ft
parsed.clouds[].reprstringДа (для каждого элемента)Исходный токен. BKN050CB = кучево-дождевые облака на 5000 ft
parsed.temperaturenumberДа°C
parsed.dewpointnumberДа°C
parsed.altimeternumberДаУстановка высотомера QNH в inHg
parsed.flight_rulesstringДаКатегория полётных условий (VFR, MVFR, IFR, LIFR)
parsed.wx_codesarrayДаТекущая погода. [], если явлений нет, — см. Коды текущей погоды
parsed.remarksstringДаВсё, что следует после RMK в исходной строке
parsed.density_altitudeintegerДаФуты — эффективная высота с поправкой на температуру и давление; важна для лётных характеристик ВС
parsed.pressure_altitudeintegerДаФуты — высота относительно стандартной атмосферы
parsed.relative_humiditynumberДаДесятичная дробь от 0 до 1

Схемы объектов и допустимость null

При parsed=true объект parsed всегда содержит все ключи — при отсутствии данных ничего не опускается. В зависимости от поля используется null, 0 или []. Без parsed=true ключ parsed отсутствует (а не равен null).

СитуацияЧто вы получитеНо не это
Нет порывовwind.gust: nullотсутствующий ключ или 0
Штильwind.direction: 0, wind.speed: 0null, отсутствующий ключ
Ветер не переменныйwind.variable: []null
Видимость > 6 SM (P6SM)visibility.value: null, visibility.repr: "P6"value: 0
Нет текущих явлений погодыwx_codes: []null, отсутствующий ключ
Ясное небо (SKC/CLR)clouds: []null, отсутствующий ключ
Схемы вложенных объектов (ветер, видимость, облачность, текущая погода)Развернуть раздел

Ветер

Путь в JSON: parsed.wind. Всегда присутствует как объект.

ПолеТипОбязательныйNull?Если пусто
directionintegerДаНикогда0 = штиль или направление не указано
speedintegerДаНикогда0 = штиль
gustinteger | nullДаДаnull, если в METAR нет порывов
variableinteger[]ДаНикогда[], если ветер не переменный; [180, 270], если в исходной строке 180V270

Видимость

Путь в JSON: parsed.visibility. Всегда присутствует как объект.

ПолеТипОбязательныйNull?Если пусто
valuenumber | nullДаДаnull для P6SM — трактуйте как «> 6». В остальных случаях число
reprstringДаНикогдаИсходный токен: "10", "3", "P6" и т. д.

Слои облачности

Путь в JSON: parsed.clouds[]. Всегда массив (может быть пустым).

ПолеТипОбязательныйNull?Описание
typestringДаНикогдаКоды облачности
baseintegerДаНикогдаСотни футов AGL
reprstringДаНикогдаИсходный токен, например BKN050CB

Коды текущей погоды

Путь в JSON: parsed.wx_codes[]. Всегда массив (может быть пустым). Если сообщаются текущие явления погоды, каждый элемент содержит оба ключа:

ПолеТипОбязательныйNull?Описание
reprstringДаНикогдаИсходный токен, например -RA, TSRA
valuestringДаНикогдаРасшифровка, например Light Rain, Thunderstorm Rain

Пример из рабочего API (KORD):

"wx_codes": [{ "repr": "-RA", "value": "Light Rain" }]

Клиентские типы

Скопируйте в свой проект. Допустимость null соответствует разделу Схемы объектов и допустимость null выше.

"""METAR response and summary types - matches weather-metar field tables."""from __future__ import annotationsfrom dataclasses import dataclassfrom typing import LiteralFlightRules = Literal["VFR", "MVFR", "IFR", "LIFR"]@dataclassclass MetarRequest:    """Path/query input for GET /weather/metar/{icao}."""    icao: str    parsed: bool = False@dataclassclass MetarWind:    direction: int    speed: int    gust: int | None    variable: list[int]@dataclassclass MetarVisibility:    value: float | None    repr: str@dataclassclass MetarCloudLayer:    type: str    base: int    repr: str@dataclassclass MetarWxCode:    repr: str    value: str@dataclassclass MetarParsed:    time: str    wind: MetarWind    visibility: MetarVisibility    clouds: list[MetarCloudLayer]    temperature: float    dewpoint: float    altimeter: float    flight_rules: FlightRules    wx_codes: list[MetarWxCode]    remarks: str    density_altitude: int    pressure_altitude: int    relative_humidity: float@dataclassclass MetarResponse:    raw: str    icao: str    airport_name: str    timestamp: str    parsed: MetarParsed | None = None@dataclassclass MetarSummary:    """Shape returned by metar_summary() in the fetch example."""    icao: str    category: FlightRules    wind_kt: int    gust_kt: int | None    visibility_display: str    age_min: float    stale: bool

Типы данных (MetarResponse, MetarParsed) повторяют JSON ответа с parsed=true. MetarSummary определён в начале каждой вкладки примера кода.

Интеграция

Получение, кэширование и сводка наблюдений — следующий шаг после разбора успешного ответа.

Пример кэширует каждую сводку METAR на пять минут (наблюдения обновляются не чаще чем раз в 30–60 минут), использует таймауты 10 s / 15 s на подключение/чтение и строит сводку по parsed.time (время наблюдения), а не по timestamp (время запроса к API).

import osimport timefrom dataclasses import dataclassfrom datetime import datetime, timezonefrom typing import Literalimport requests# MetarSummary - helper return type. Full wire types (MetarResponse, MetarParsed, …)# are in the Client types section on the METAR docs page.FlightRules = Literal["VFR", "MVFR", "IFR", "LIFR"]@dataclassclass MetarSummary:    icao: str    category: FlightRules    wind_kt: int    gust_kt: int | None    visibility_display: str    age_min: float    stale: boolHEADERS = {    "x-api-key": os.getenv("SKYLINK_API_KEY", "YOUR_API_KEY")}BASE = "https://data.skylinkapi.com/v3.1"CACHE: dict[str, tuple[dict, float]] = {}METAR_TTL = 300  # 5 min - safe inside the 30–60 min observation cycledef parse_observation_time(iso: str) -> datetime:    """Parse parsed.time - API returns ISO 8601 with timezone offset."""    return datetime.fromisoformat(iso.replace("Z", "+00:00"))def fetch_metar(icao: str) -> dict | None:    cache_key = f"metar:{icao}:parsed"    cached = CACHE.get(cache_key)    if cached and time.time() < cached[1]:        return cached[0]    try:        r = requests.get(            f"{BASE}/weather/metar/{icao}",            headers=HEADERS,            params={"parsed": "true"},            timeout=(10, 15),        )    except requests.Timeout as exc:        raise RuntimeError(f"SkyLink timeout fetching METAR for {icao}") from exc    if r.status_code == 404:        return None    r.raise_for_status()    data = r.json()    CACHE[cache_key] = (data, time.time() + METAR_TTL)    return datadef metar_summary(icao: str) -> MetarSummary | None:    metar = fetch_metar(icao)    if not metar:        return None    p = metar["parsed"]    obs = parse_observation_time(p["time"])    age_min = (datetime.now(timezone.utc) - obs).total_seconds() / 60    vis = p["visibility"]["value"]    return MetarSummary(        icao=icao,        category=p["flight_rules"],        wind_kt=p["wind"]["speed"],        gust_kt=p["wind"]["gust"],        visibility_display=f"{vis} SM" if vis is not None else "> 6 SM",        age_min=round(age_min, 1),        stale=age_min > 90,    )if __name__ == "__main__":    import json    from dataclasses import asdict    summary = metar_summary("KJFK")    print(json.dumps(asdict(summary), indent=2) if summary else "METAR not available")

Другие примеры: Сценарии использования погодных данных.

Примечания по реализации

timestamp и parsed.time. timestamp меняется при каждом запросе. parsed.time — время наблюдения из заголовка METAR; используйте его для сообщений вида «данным X минут».

visibility.value равно null. Если станция сообщает P6SM, value равно null, а repr — "P6". Трактуйте null как «> 6 SM», а не как отсутствие данных.

Доступность станций. Не для каждого кода ICAO есть станция METAR. Ответ 404 означает, что наблюдение недоступно, — сам аэропорт при этом может существовать. Показывайте пустое состояние, а не баннер с ошибкой.

Кэширование. Клиентский кэш на 3–5 минут сокращает дублирующиеся вызовы, не пропуская новых наблюдений.

Ответы с ошибками

Здесь описаны только сбои, специфичные для METAR. Ошибки аутентификации, валидации, ограничения частоты запросов и ошибки сервера описаны в разделе Обработка ошибок. Паттерны резервного перехода между METAR и TAF см. в разделе Когда погодные данные отсутствуют.

404 — нет METAR для этого кода ICAO

{
  "detail": "Airport not found for ICAO code: KXYZ"
}

Аэропорт может не существовать либо существовать, но не иметь станции METAR. Сообщение не различает эти случаи — трактуйте любой ответ 404 для METAR как отсутствие доступного наблюдения.

GET
/weather/metar/{icao}
x-api-key<token>

Your SkyLink licence key, for keys bought direct from skylinkapi.com.

In: header

Path Parameters

icao*Icao

4-letter ICAO airport code

Length4 <= length <= 4

Query Parameters

parsed?Parsed

Include parsed/decoded METAR fields alongside raw text

Defaultfalse

Response Body

application/json

application/json

curl -X GET "https://data.skylinkapi.com/v3.1/weather/metar/KJFK"
{
  "raw": "METAR KJFK 271851Z 16013KT 10SM FEW024 15/09 A3020 RMK AO2 SLP216 T01500089",
  "icao": "KJFK",
  "airport_name": "John F Kennedy International Airport",
  "timestamp": "2025-09-27T12:00:00Z"
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

См. также: TAF · Сценарии использования · Ошибки · Продакшн