Перейти к основному содержанию
API использует стандартизированный формат ответов об ошибках. Все ошибки возвращаются в формате JSON с единой структурой.

Структура ответа об ошибке

Все ошибки возвращаются в следующем формате:
{
  "code": "ErrorCode",
  "message": "Человекочитаемое описание ошибки",
  "details": {
    // Дополнительная информация об ошибке (опционально)
  },
  "request_id": "xxxx"
}

Поля ответа

  • code (обязательное): Машиночитаемый код ошибки. Используйте его для программной обработки ошибок.
  • message (обязательное): Человекочитаемое описание ошибки на языке, указанном в заголовке Accept-Language или языке по умолчанию.
  • details (опциональное): Дополнительная информация об ошибке. Структура зависит от типа ошибки.
  • request_id (опциональное): Эхо заголовка X-Request-ID, переданного в запросе. Используется для трассировки запросов.

Коды ошибок

Ошибки аутентификации и авторизации

401 Unauthorized

Ошибка аутентификации. Возвращается в следующих случаях:
  • Отсутствует или недействителен клиентский сертификат (mTLS): Запрос не содержит валидный клиентский сертификат или сертификат не прошел проверку.
  • Отсутствует или недействителен Bearer токен: Заголовок Authorization отсутствует, имеет неверный формат, или токен истек/недействителен.
  • Неверный формат токена: Токен не является валидным JWT или имеет неверную структуру.
Пример ответа (отсутствует клиентский сертификат):
{
  "code": "Unauthorized",
  "message": "Требуется клиентский сертификат для mTLS аутентификации",
  "request_id": "f2c8a9f6-1234-5678-9abc-def012345678"
}
Пример ответа (отсутствует Bearer токен):
{
  "code": "Unauthorized",
  "message": "Требуется Bearer токен в заголовке Authorization",
  "request_id": "f2c8a9f6-1234-5678-9abc-def012345678"
}
Пример ответа (недействительный токен):
{
  "code": "Unauthorized",
  "message": "Токен истек или недействителен",
  "request_id": "f2c8a9f6-1234-5678-9abc-def012345678"
}

403 Forbidden

Недостаточно прав для выполнения операции. Возвращается в следующих случаях:
  • Отсутствует необходимый scope в токене: Токен валиден, но не содержит требуемый scope для данной операции.
  • Неверный audience (aud) в токене: Поле aud в JWT не соответствует ожидаемому значению для данного API.
Пример ответа (отсутствует scope):
{
  "code": "Forbidden",
  "message": "Недостаточно прав для операции (требуется scope: booking.lounges)",
  "details": {
    "required_scope": "booking.lounges",
    "provided_scopes": ["catalog.lounges"]
  },
  "request_id": "f2c8a9f6-1234-5678-9abc-def012345678"
}
Пример ответа (неверный audience):
{
  "code": "Forbidden",
  "message": "Токен выдан для другого API (неверный audience)",
  "details": {
    "expected_aud": "https://api.every.ru/business-lounges",
    "provided_aud": "https://api.every.ru/other-service"
  },
  "request_id": "f2c8a9f6-1234-5678-9abc-def012345678"
}

Ошибки валидации и бизнес-логики

400 Bad Request

Некорректный запрос. Возвращается при ошибках валидации входных данных. Код ошибки: ValidationError Пример ответа:
{
  "code": "ValidationError",
  "message": "Некорректные параметры запроса",
  "details": {
    "field": "guests_count",
    "reason": "Количество гостей не может быть больше 10 человек"
  },
  "request_id": "xxxx"
}

404 Not Found

Ресурс не найден. Возвращается в следующих случаях: Код ошибки: CatalogResourceNotFound Ресурс каталога (бизнес-зал или фаст-трек) не найден. Пример ответа:
{
  "code": "CatalogResourceNotFound",
  "message": "Ресурс не найден",
  "request_id": "xxxx"
}
Код ошибки: BookingNotFound Бронирование не найдено. Пример ответа:
{
  "code": "BookingNotFound",
  "message": "Бронирование не найдено",
  "request_id": "xxxx"
}

409 Conflict

Конфликт состояния операции. Возвращается в следующих случаях: Код ошибки: IdempotencyConflict Конфликт идемпотентности. Возвращается, когда запрос с существующим Idempotency-Key содержит тело запроса, отличающееся от сохранённого при первом использовании ключа. Пример ответа:
{
  "code": "IdempotencyConflict",
  "message": "Idempotency Key используется с другими параметрами",
  "request_id": "xxxx"
}
Код ошибки: BookingAlreadyConfirmed Попытка подтвердить уже подтверждённую бронь. Пример ответа:
{
  "code": "BookingAlreadyConfirmed",
  "message": "Бронь уже подтверждена",
  "request_id": "xxxx"
}
Код ошибки: BookingAlreadyCanceled Попытка отменить уже отменённую бронь. Пример ответа:
{
  "code": "BookingAlreadyCanceled",
  "message": "Бронь уже отменена",
  "request_id": "xxxx"
}

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

202 Accepted (PassNotReady)

Бронь находится в обработке, данные для прохода недоступны. Это не ошибка, а индикатор того, что данные ещё не готовы. Код ошибки: PassNotReady Заголовки ответа:
  • Location: URL ресурса для поллинга статуса (тот же endpoint /pass)
  • Retry-After: Рекомендуемая задержка перед повтором в секундах
Пример ответа:
{
  "code": "PassNotReady"
}
Рекомендации:
  • Используйте заголовок Retry-After для определения интервала поллинга
  • Повторяйте запрос к тому же endpoint /pass до получения успешного ответа или ошибки

500 Internal Server Error

Внутренняя ошибка сервиса. Возвращается при неожиданных ошибках на стороне сервера. Код ошибки: InternalError Пример ответа:
{
  "code": "InternalError",
  "message": "Внутренняя ошибка сервиса",
  "request_id": "xxxx"
}
Рекомендации:
  • Не повторяйте запрос немедленно — это может быть временная проблема
  • Если ошибка повторяется, обратитесь в поддержку с request_id

503 Service Unavailable

Сервис временно недоступен. Возвращается при временной недоступности сервиса (например, при техническом обслуживании). Код ошибки: ServiceUnavailable Заголовки ответа:
  • Retry-After: Рекомендуемая задержка перед повтором в секундах
Пример ответа:
{
  "code": "ServiceUnavailable",
  "message": "Сервис временно недоступен",
  "request_id": "xxxx"
}
Рекомендации:
  • Используйте экспоненциальную задержку между повторными попытками
  • Учитывайте заголовок Retry-After при планировании повторных запросов

Успешные ответы

304 Not Modified

Ресурс не был изменен с момента последнего запроса. Возвращается при использовании условных запросов с заголовками If-None-Match или If-Modified-Since. Особенности:
  • Тело ответа отсутствует (экономия трафика)
  • Возвращаются заголовки ETag и Last-Modified
Это не ошибка, а оптимизация для уменьшения трафика при повторных запросах к каталогам.

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

Рекомендации

  1. Используйте код ошибки для логики: Проверяйте поле code для программной обработки ошибок, а не HTTP статус код или сообщение.
  2. Сохраняйте request_id: Всегда логируйте request_id из ответа об ошибке. Это поможет при обращении в поддержку.
  3. Обрабатывайте детали ошибки: Поле details может содержать полезную информацию для исправления проблемы (например, какие поля не прошли валидацию).
  4. Повторные запросы:
    • Для 503 Service Unavailable: используйте экспоненциальную задержку и учитывайте Retry-After
    • Для 202 PassNotReady: повторяйте запрос с интервалом, указанным в Retry-After
    • Для 500 Internal Error: не повторяйте немедленно, это может быть постоянная проблема
  5. Ошибки аутентификации: При получении 401 Unauthorized проверьте:
    • Наличие и валидность клиентского сертификата (mTLS)
    • Наличие и валидность Bearer токена
    • Срок действия токена (токены действительны 1 час)
  6. Ошибки авторизации: При получении 403 Forbidden проверьте:
    • Наличие необходимых scope в токене
    • Правильность audience (aud) в JWT токене

Таблица кодов ошибок

HTTP кодКод ошибкиОписание
400ValidationErrorОшибка валидации входных данных
401UnauthorizedОшибка аутентификации
403ForbiddenНедостаточно прав для операции
404CatalogResourceNotFoundРесурс каталога не найден
404BookingNotFoundБронирование не найдено
409IdempotencyConflictКонфликт идемпотентности
409BookingAlreadyConfirmedБронь уже подтверждена
409BookingAlreadyCanceledБронь уже отменена
500InternalErrorВнутренняя ошибка сервиса
503ServiceUnavailableСервис временно недоступен
202PassNotReadyДанные для прохода ещё не готовы