Save up to 17% with yearly billing

See pricing

Ветер на высотах

Прогнозы ветра на высотах описывают ожидаемое направление и скорость ветра и температуру на стандартных высотах для планирования полётов в США. FB Winds (Winds and Temperatures Aloft) выпускаются по фиксированному графику и охватывают станции по всей континентальной части США; этот эндпоинт возвращает все станции, координаты которых попадают в ваш ограничивающий прямоугольник (bounding box). Используйте его вместе с METAR и TAF, когда нужны составляющие ветра на крейсерской высоте для планирования топлива и времени, а не приземные условия в отдельном аэропорту. Покрытие — только США: запросы по территориям за пределами США возвращают 404 без станций.

Запрос

Требования

Авторизация
x-api-key в каждом запросе (прямая подписка). Подробнее →

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

GEThttps://data.skylinkapi.com/v3.1/weather/winds-aloft
ПараметрТипОбязательныйПо умолчаниюОписание
bboxstringДа-Ограничивающий прямоугольник в формате lat1,lon1,lat2,lon2 — сначала юго-западный угол, затем северо-восточный. Пример: 40,-80,42,-73 (район Нью-Йорка)
forecastintegerНет12Период прогноза в часах — 6, 12 или 24
levelstringНетlowДиапазон высот: low (3000–39 000 ft MSL) или high (6000–45 000 ft MSL)

Советы по ограничивающему прямоугольнику. Держите прямоугольник как можно ближе к маршруту — меньшие области возвращают меньше станций, и ответ приходит быстрее. Координаты задаются в десятичных градусах (WGS-84). Долгота к западу от нулевого меридиана отрицательна (например, -73.78 для JFK).

Ответ

{
  "bbox": "40.0,-80.0,42.0,-73.0",
  "forecast_hour": 12,
  "level": "low",
  "valid_time": "131800Z",
  "stations": [
    {
      "station": "JFK",
      "latitude": 40.6413,
      "longitude": -73.7781,
      "winds": [
        {
          "altitude_ft": 3000,
          "wind_direction": 310,
          "wind_speed_kt": 7,
          "temperature_c": null,
          "light_and_variable": false,
          "raw": "3107"
        },
        {
          "altitude_ft": 18000,
          "wind_direction": 270,
          "wind_speed_kt": 35,
          "temperature_c": -9,
          "light_and_variable": false,
          "raw": "2735-09"
        }
      ],
      "raw_text": "JFK 3107 3215+13 2926+08 2827+06 2735-09 2645-23 255637 256344 255852"
    }
  ],
  "total": 1
}
ПолеТипОбязательныйОписание
bboxstringДаПовтор запрошенного ограничивающего прямоугольника
forecast_hourintegerДаПрименённый период прогноза (6, 12 или 24)
levelstringДаПрименённый диапазон высот (low или high)
valid_timestring | nullДа (ключ присутствует всегда)Время действия прогноза (UTC), например 131800Z. null, если не указано
stationsarrayДаСтанции FB Winds внутри bbox. [], если совпадений нет, — обычно вместе с 404
totalintegerДаКоличество станций в stations

Диапазоны высот

levelТипичные возвращаемые высоты (ft MSL)
low3000 / 6000 / 9000 / 12 000 / 18 000 / 24 000 / 30 000 / 34 000 / 39 000
high6000 / 9000 / 12 000 / 18 000 / 24 000 / 30 000 / 34 000 / 39 000 / 45 000

Точный набор высот для каждой станции зависит от продукта FB — не каждая станция возвращает все высоты.

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

Каждый ключ объекта станции присутствует всегда. Каждый ключ объекта уровня ветра присутствует всегда, если сам объект существует. Используйте null, 0 или [] согласно шаблонам ниже — никогда не проверяйте отсутствие ключа.

СитуацияЧто вы получитеЧего не будет
Низкий уровень без температурыtemperature_c: null0, отсутствующий ключ
Группа ветра не декодированаwind_direction: null, wind_speed_kt: nullотсутствующий ключ или 0
Слабый ветер переменного направленияlight_and_variable: true, wind_direction может быть nullnull для light_and_variable
Станция без декодированных уровнейwinds: []null, отсутствующий ключ
Нет исходной строки FB для станцииraw_text: nullотсутствующий ключ
Источник данных не указывает время действияvalid_time: nullотсутствующий ключ
Нет станций внутри bboxstations: [] + HTTP 404null
Схемы станции и уровня ветраРазвернуть раздел

Станция

Путь в JSON: stations[]. Каждый элемент представляет одну станцию FB Winds внутри bbox.

ПолеТипОбязательныйДопускает nullОписание
stationstringДаНикогда3-буквенный идентификатор станции FB Winds (часто совпадает с ближайшим аэропортом, например JFK)
latitudenumberДаНикогдаШирота станции (десятичные градусы)
longitudenumberДаНикогдаДолгота станции (десятичные градусы)
windsarrayДаНикогдаУровни ветра и температуры для этой станции. [], если ни один уровень не декодирован
raw_textstring | nullДа (ключ присутствует всегда)ДаПолная исходная строка FB Winds для этой станции. null, если не указана

Уровень ветра

Путь в JSON: stations[].winds[]. Каждый элемент представляет один уровень высоты для родительской станции.

ПолеТипОбязательныйДопускает nullОписание
altitude_ftintegerДаНикогдаВысота уровня в футах над MSL
wind_directioninteger | nullДа (ключ присутствует всегда)ДаИстинное направление в градусах (0–360). null, если не декодировано
wind_speed_ktinteger | nullДа (ключ присутствует всегда)ДаСкорость в узлах. null, если не декодирована
temperature_cinteger | nullДа (ключ присутствует всегда)ДаТемпература в °C. На самых низких уровнях (3000–6000 ft) часто null
light_and_variablebooleanДаНикогдаtrue, если ветер слабый и переменного направления (< 5 kt). По умолчанию false
rawstringДаНикогдаЗакодированная группа ветра для этого уровня, например 2735-09 (270°/35 kt, −9 °C)

Слабый ветер переменного направления. Когда light_and_variable равно true, скорость ветра ниже 5 узлов и определённого направления нет — wind_direction и wind_speed_kt могут быть null или нулём.

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

"""Winds aloft response types - matches winds-aloft field tables."""from dataclasses import dataclassfrom typing import Literal@dataclassclass WindLevel:    altitude_ft: int    wind_direction: int | None    wind_speed_kt: int | None    temperature_c: int | None    light_and_variable: bool    raw: str@dataclassclass WindsAloftStation:    station: str    latitude: float    longitude: float    winds: list[WindLevel]    raw_text: str | None@dataclassclass WindsAloftResponse:    bbox: str    forecast_hour: int    level: str    valid_time: str | None    stations: list[WindsAloftStation]    total: int@dataclassclass CruiseWindSummary:    station: str    altitude_ft: int    direction_deg: int | None    speed_kt: int | None    temperature_c: int | None

Интеграция

Запросите ветер для ограничивающего прямоугольника маршрута и выберите уровень, ближайший к планируемой крейсерской высоте.

Пример запрашивает прямоугольник вокруг района Нью-Йорка, кэширует ответ на один час (продукты FB обновляются по фиксированному графику) и возвращает уровень ветра, ближайший к целевой высоте. При 404 вспомогательная функция возвращает null, и вызывающий код показывает пустое состояние вместо ошибки.

import osimport timefrom typing import TypedDictimport requests# CruiseWindSummary - helper return type. Full wire types are in the Client types section.class WindLevel(TypedDict):    altitude_ft: int    wind_direction: int | None    wind_speed_kt: int | None    temperature_c: int | None    light_and_variable: bool    raw: strclass Station(TypedDict):    station: str    latitude: float    longitude: float    winds: list[WindLevel]    raw_text: str | Noneclass WindsAloftResponse(TypedDict):    bbox: str    forecast_hour: int    level: str    valid_time: str | None    stations: list[Station]    total: intclass CruiseWindSummary(TypedDict):    station: str    altitude_ft: int    direction_deg: int | None    speed_kt: int | None    temperature_c: int | NoneHEADERS = {    "x-api-key": os.getenv("SKYLINK_API_KEY", "YOUR_API_KEY")}BASE = "https://data.skylinkapi.com/v3.1"CACHE: dict[str, tuple[WindsAloftResponse, float]] = {}WINDS_TTL = 3600  # 1 h - FB products update on a fixed scheduledef fetch_winds_aloft(bbox: str, forecast: int = 12, level: str = "low") -> WindsAloftResponse | None:    cache_key = f"winds:{bbox}:{forecast}:{level}"    cached = CACHE.get(cache_key)    if cached and time.time() < cached[1]:        return cached[0]    try:        r = requests.get(            f"{BASE}/weather/winds-aloft",            headers=HEADERS,            params={"bbox": bbox, "forecast": forecast, "level": level},            timeout=(10, 20),        )    except requests.Timeout as exc:        raise RuntimeError(f"SkyLink timeout fetching winds aloft for {bbox}") from exc    if r.status_code == 404:        return None    r.raise_for_status()    data: WindsAloftResponse = r.json()    CACHE[cache_key] = (data, time.time() + WINDS_TTL)    return datadef nearest_cruise_wind(    bbox: str,    target_altitude_ft: int = 18_000,    forecast: int = 12,) -> CruiseWindSummary | None:    """Pick the wind level closest to target altitude from the first station in the bbox."""    payload = fetch_winds_aloft(bbox, forecast=forecast, level="low")    if not payload or not payload["stations"]:        return None    station = payload["stations"][0]    levels = station["winds"]    if not levels:        return None    best = min(levels, key=lambda w: abs(w["altitude_ft"] - target_altitude_ft))    return {        "station": station["station"],        "altitude_ft": best["altitude_ft"],        "direction_deg": best["wind_direction"],        "speed_kt": best["wind_speed_kt"],        "temperature_c": best["temperature_c"],    }if __name__ == "__main__":    import json    from dataclasses import asdict    bbox = "-74.5,40.3,-73.5,41.0"    cruise = nearest_cruise_wind(bbox, target_altitude_ft=18_000)    print(json.dumps(asdict(cruise), indent=2) if cruise else "No winds data")

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

Покрытие только США. FB Winds — продукт США. Bbox над Европой или океаном без станций США возвращает 404 — это не ошибка аутентификации или квоты. Стройте bbox по точкам маршрута в США.

Пустой результат и 404. Если ни один центроид станции не попадает в bbox, API возвращает 404 с сообщением detail, в котором указаны прогноз и уровень. Немного расширьте bbox или сместите его вдоль маршрута.

Выбор level. Используйте low для типичного крейсерского полёта авиалайнеров ниже FL390. Используйте high, когда нужны данные для FL390–FL450. Если сервис временно недоступен для уровня, вы можете получить 503 — повторите запрос с экспоненциальной задержкой (backoff).

Отсутствие температуры на низких высотах. На уровне 3000 ft, а иногда и 6000 ft температура обычно не указывается (temperature_c: null). Используйте для планирования направление и скорость ветра; отсутствующую температуру трактуйте как «не сообщается на этом уровне».

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

Здесь описаны только ошибки, специфичные для эндпоинта. Об ошибках аутентификации, валидации, ограничениях частоты запросов и ошибках сервера, общих для всех эндпоинтов, см. Обработка ошибок.

404 — в bbox нет станций

{
  "detail": "No FB winds stations found in the given bounding box for forecast=12h, level=low"
}

Частые причины: bbox за пределами покрытия США, слишком маленький bbox между станциями или координаты вне США. Расширьте прямоугольник или убедитесь, что маршрут проходит над США.

400 — некорректный формат bbox

{
  "detail": "Invalid bounding box format. Expected 'lat1,lon1,lat2,lon2'"
}

503 — источник данных недоступен

{
  "detail": "Winds aloft service temporarily unavailable"
}

Повторите запрос после короткой задержки. Если ошибка сохраняется, попробуйте другой level или другой час forecast.

GET
/weather/winds-aloft
x-api-key<token>

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

In: header

Query Parameters

bbox*Bbox

Bounding box as 'lat1,lon1,lat2,lon2' (SW corner → NE corner)

forecast?Forecast

Forecast period in hours (6, 12, or 24)

Default12
Range6 <= value <= 24
level?Level

Altitude range: 'low' (3K-39K ft) or 'high' (6K-45K ft)

Default"low"
Match^(low|high)$

Response Body

application/json

application/json

curl -X GET "https://data.skylinkapi.com/v3.1/weather/winds-aloft?bbox=string"
{
  "bbox": "40,-80,42,-73",
  "forecast_hour": 12,
  "level": "low",
  "valid_time": "130000Z",
  "stations": [
    {
      "station": "JFK",
      "latitude": 40.6413,
      "longitude": -73.7781,
      "winds": [
        {
          "altitude_ft": 3000,
          "wind_direction": 270,
          "wind_speed_kt": 9,
          "light_and_variable": false,
          "raw": "2709"
        }
      ],
      "raw_text": "JFK      2709 3012+08 ..."
    }
  ],
  "total": 1
}
Empty
Empty
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

См. также: Раздел «Погода» · METAR · TAF · Сценарий: ветер на крейсерской высоте