Обработка ошибок
Когда запрос завершается ошибкой, тело ответа — JSON, но его структура зависит от того, какой уровень отклонил вызов. Ваш клиент должен сначала ветвиться по HTTP-статусу, а затем разбирать тело по правилам ниже. Эта страница — единственный источник истины по обработке ошибок на уровне всей платформы для всех версий API (/v2, /v3, /v3.1) и всех эндпоинтов.
Ошибки авторизации различаются для двух каналов —
| Уровень | Поле верхнего уровня | Типичные статусы |
|---|---|---|
| Уровень авторизации / квот | message или code (строка) | 401, 403, 429 |
| SkyLink API | detail (строка или массив) | 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 / TAF | METAR · 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 см. Ограничения частоты запросов.
Начало работы
Подайте заявку на FREE Trial или оформите подписку — учётные данные, защита ключа, публичные эндпоинты и первый запрос к SkyLink API.
Ограничения частоты запросов
Квоты тарифов, посекундные ограничения частоты запросов, заголовки ответа с лимитами, цены на превышение квоты и уровни путей исторических данных ADS-B.