Save up to 17% with yearly billing

See pricing

Обработка ошибок

Когда запрос завершается ошибкой, тело ответа — JSON, но его структура зависит от того, какой уровень отклонил вызов. Ваш клиент должен сначала ветвиться по HTTP-статусу, а затем разбирать тело по правилам ниже. Эта страница — единственный источник истины по обработке ошибок на уровне всей платформы для всех версий API (/v2, /v3, /v3.1) и всех эндпоинтов.

Ошибки авторизации различаются для двух каналов —

УровеньПоле верхнего уровняТипичные статусы
Уровень авторизации / квотmessage или code (строка)401, 403, 429
SkyLink APIdetail (строка или массив)404, 422, 500, 502, 504

Всегда читайте Content-Type: application/json. Не рассчитывайте на один формат ошибки для всех кодов статуса.

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


Ошибки авторизации и квот

Они возникают до обращения к уровню данных или вместо него. Тело содержит message или code, а не detail.

401 — API-ключ отсутствует или недействителен

{
  "code": "missing_api_key",
  "message": "Provide your key in the x-api-key header."
}

Ключ считывается только из заголовка x-api-key — передача его как query-параметра не принимается и возвращает тот же 401.

403 — эндпоинт не входит в ваш тариф

{
  "code": "plan_forbidden",
  "message": "This endpoint is not included in your plan."
}

429 — достигнут потолок защиты от злоупотреблений

{
  "message": "Too many requests"
}

См. Ограничения частоты запросов — в прямом API это суточный потолок защиты от злоупотреблений, а не ваш месячный лимит.

JSON Schema — ошибки шлюза (401, 403, 429)Развернуть раздел
{
  "type": "object",
  "required": ["message"],
  "properties": {
    "message": { "type": "string" }
  },
  "additionalProperties": true
}

Исправьте ключ или подписку — не повторяйте запросы с 401 или 403. При 429 сделайте паузу и повторите запрос; см. Правила повторных попыток и Ограничения частоты запросов о заголовках квот.

Настройка заголовков описана в разделе Начало работы.


Ошибки валидации (422)

Если запрос дошёл до SkyLink, но не прошёл валидацию входных данных, detail — это массив объектов:

{
  "detail": [
    {
      "type": "string_too_short",
      "loc": ["path", "icao"],
      "msg": "String should have at least 4 characters",
      "input": "KF",
      "ctx": { "min_length": 4 }
    }
  ]
}
ПолеОписание
detail[].typeИдентификатор валидатора, например string_too_short
detail[].locПуть к ошибочному полю, например ["path", "icao"] или ["query", "parsed"]
detail[].msgПонятное человеку пояснение
detail[].inputОтклонённое значение
detail[].ctxНеобязательные ограничения
JSON Schema — 422 (массив detail)Развернуть раздел
{
  "type": "object",
  "required": ["detail"],
  "properties": {
    "detail": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["type", "loc", "msg", "input"],
        "properties": {
          "type": { "type": "string" },
          "loc": { "type": "array", "items": { "type": "string" } },
          "msg": { "type": "string" },
          "input": { "type": "string" },
          "ctx": { "type": "object" }
        },
        "additionalProperties": true
      }
    }
  },
  "additionalProperties": false
}

Не повторяйте запрос — исправьте параметры и отправьте его снова.


Серверные ошибки и ошибки внешних сервисов (5xx)

Когда происходит сбой SkyLink или внешнего сервиса данных:

{
  "detail": "Internal Server Error"
}
JSON Schema — 5xx (строка detail)Развернуть раздел

Та же структура, что и у бизнес-строк detail (404 тоже использует эту форму):

{
  "type": "object",
  "required": ["detail"],
  "properties": {
    "detail": { "type": "string" }
  },
  "additionalProperties": false
}
СтатусЗначение
500Внутренняя ошибка сервера
502Внешний сервис данных недоступен
504Истекло время ожидания внешнего сервиса

Повторяйте запрос с экспоненциальной задержкой (не более 3 попыток). См. Правила повторных попыток.


Не найдено (404)

Ответы 404 используют строковую форму detail SkyLink, но сообщение и смысл зависят от эндпоинта: METAR без станции, TAF без прогноза, неизвестный ICAO-код аэропорта и отсутствующий исторический рейс имеют разную семантику. Описывайте 404 на каждой справочной странице (или в руководстве по интеграции раздела, если шаблон охватывает несколько эндпоинтов). Не дублируйте здесь все варианты; из своего обработчика ссылайтесь на страницу, соответствующую вызванному эндпоинту.

РазделГде описан 404
Погода — METAR / TAFMETAR · TAF · Когда данные о погоде отсутствуют
Погода — на маршрутеВетер на высотах · PIREP · AIRMET/SIGMET
Данные аэропортовАэропорты · Поиск аэропортов
Справочные данныеСтраны · Регионы
ADS-B в реальном времениОтслеживание ADS-B
Исторические данные ADS-BОбзор исторических данных ADS-B · Сведения о рейсе · История позиций
КартыАэронавигационные карты
Лётная эксплуатацияСтатус рейса
ВебхукиПодписки

Важно: некоторые эндпоинты вместо 404 возвращают пустой результат с HTTP 200 (например, поиск воздушного судна, когда ни один регистрационный номер не совпал). Прежде чем сводить все случаи «не найдено» к 404, сверьтесь со справочной страницей.

Ошибки 401/403, связанные с ограничениями тарифа для исторических данных ADS-B (подписка ниже уровня, необходимого для префикса пути), описаны на странице Обзор исторических данных ADS-B, а не здесь.


Правила повторных попыток

СтатусПовторять?Действие
401, 403НетИсправьте API-ключ / подписку
404НетРезервный сценарий для конкретного эндпоинта — см. справочную страницу
422НетИсправьте входные данные
429ДаЭкспоненциальная задержка; проверьте заголовки квот
500, 502, 504ДаЭкспоненциальная задержка (не более 3 попыток)
import time
import requests

RETRYABLE = {429, 500, 502, 504}


def fetch_with_retry(url: str, headers: dict, params: dict | None = None, max_retries: int = 3) -> requests.Response:
    delay = 1.0
    for attempt in range(max_retries + 1):
        r = requests.get(url, headers=headers, params=params, timeout=(10, 15))
        if r.status_code not in RETRYABLE or attempt == max_retries:
            return r
        time.sleep(delay)
        delay *= 2
    return r

О квотах тарифов, стоимости превышения квоты и уровнях путей исторических данных ADS-B см. Ограничения частоты запросов.