Руководство по использованию API

Поля запроса смотрите в Swagger. Смысл ответа, статусы заказа и коды ошибок — на этой странице.

🚀 Открыть Swagger UI

📖 Введение

Успешный ответ: status = success и данные в results. Кроме получения токена, каждый вызов передаёт заголовок Authorization: Bearer <токен>.

Токен живёт 90 минут. Просроченный или поддельный токен — это не AUTH_1005, а HTTP 401 с телом detail.error.code = UNAUTHORIZED.

1️⃣ Получение токена аутентификации

POST /api/token/

Это фундаментальный шаг, который инициирует сессию взаимодействия с API. Без валидного токена ни один другой защищенный эндпоинт не будет доступен.

📥 Ключевые поля запроса:

  • username (string, обязательное) - Уникальный идентификатор партнера в нашей системе
  • password (string, обязательное) - Секретный ключ, ассоциированный с вашим именем пользователя

📤 Ключевые поля ответа:

  • status (string) - Индикатор успешности операции
  • token (string) - JWT. Срок 90 минут, в ответе срока нет
💡 Использование в Swagger UI: После получения токена используйте кнопку "Authorize" в верхней части страницы и вставьте токен в формате Bearer <ВАШ_ТОКЕН>

2️⃣ Запрос коммерческого предложения (Air Shopping)

POST /api/airshopping/

Это основной эндпоинт для поиска авиабилетов и формирования предложений.

📥 Ключевые поля запроса:

  • itinerary (array) - Массив сегментов маршрута с полями:
    • origin - IATA-код города отправления
    • destination - IATA-код города прибытия
    • date_to - Дата вылета (YYYY-MM-DD)
  • flight_class (string) - Класс обслуживания: Economy, Premium Economy, Business, First. Касса может не продавать выбранный класс и вернуть пустой список.
  • adt (integer) - Количество взрослых пассажиров
  • chd (integer, опц.) - Количество детей
  • inf (integer, опц.) - Количество младенцев без места
  • ins (integer, опц.) - Количество младенцев с местом
  • currency (string) - Валюта цен в ответе. Набор валют задаётся для вашего пользователя.

📤 Ключевые поля ответа:

  • results.Offer - массив предложений. Пустой массив значит, что рейсов нет, это не ошибка
  • OfferID - идентификатор предложения. Для брони берите его заново из ответа уточнения цены
  • TotalPrice - стоимость предложения
  • OfferExpirationTimeLimitDateTime - до какого момента предложение ещё можно уточнить. Наивная строка без смещения, в зоне поля timezone. Если timezone не передан, берётся зона учётной записи, а если она не задана — UTC. Время вылета и прилёта этой зоной не переводится

3️⃣ Запрос правил применения тарифов

POST /api/rules/

Предоставляет необходимую информацию для клиента перед покупкой билета.

📥 Ключевые поля запроса:

  • offer_id (string) - OfferID из предыдущего запроса

📤 Ключевые поля ответа:

  • Rules - массив. Текст правила в FareRuleText.Remark.RemarkText. DesigCode - код авиакомпании (IATA), один смысл на всех кассах. PaxType - тип пассажира, только если текст свой для этого типа. RuleKey - ключ тарифа поставщика, если он длиннее кода авиакомпании.

4️⃣ Уточнение цены

POST /api/offerprice/
⚠️ Критически важный этап: Цены могут быстро меняться. Этот запрос позволяет получить актуальную и финальную стоимость.

📥 Ключевые поля запроса:

  • offer_id (string) - OfferID предложения
  • currency (string) - Валюта для уточненной цены

📤 Ключевые поля ответа:

  • Offer.OfferID - новый идентификатор. Дальше используйте его, а не OfferID из поиска
  • Offer.TotalPrice - уточнённая стоимость
  • Offer.BookingID - номер заказа для создания, выписки, просмотра и отмены
  • Offer.OrderStatus - после уточнения цены это SELECTED. Создание заказа принимает только этот статус

5️⃣ Резервирование инвентаря

POST /api/inv-guarantee/

Отдельного резерва мест на этом шаге нет: место держится при создании заказа. Этот вызов можно пропустить. POST /api/inv-guarantee-release/ тоже не снимает место. Срок оплаты смотрите в PaymentTimeLimitDateTime ответа /api/create/.

📥 Ключевые поля запроса:

  • offer_id (string) - Актуальный OfferID из /api/offerprice/

📤 Ключевые поля ответа:

  • InventoryGuarantee.OfferID - тот же OfferID
  • InventoryGuarantee.InventoryGuaranteeTimeLimitDateTime - срок удержания. Если место на этом шаге не держится, поле пустое

6️⃣ Создание заказа (Booking Creation)

POST /api/create/

Основной этап формирования бронирования с привязкой к конкретным пассажирам.

📥 Ключевые поля запроса:

  • booking_id (integer) - BookingID из /api/offerprice/
  • paxes (array) - Массив данных о пассажирах:
    • pax_id - ID пассажира
    • ptc - Тип пассажира: ADT, CHD, INF или INS
    • individual - Личные данные: given_name, surname, birthdate, gender. middle_name необязателен
    • doc - Документ: doc_id, type_code, expiry_date, issuing_country_code
    • phone и email - обязательны у каждого пассажира
  • currency (string) - Валюта заказа
  • Idempotency-Key (заголовок, необязательный) - 8–80 символов: буквы, цифры, точка, подчёркивание, двоеточие, дефис. Один ключ на один заказ. Повтор того же ключа возвращает только номер и статус, без нового бронирования. Тот же ключ на другой заказ даёт ERR_1023

📤 Ключевые поля ответа:

  • Order.OrderStatus - после создания BOOKED. Это бронь, не билет. Повтор создания из другого статуса отвечает ERR_1013
  • Order.PaymentTimeLimitDateTime - срок оплаты. Наивная строка без смещения, в зоне поля timezone. Если timezone не передан, берётся зона учётной записи, а если она не задана — UTC. После срока место снимается, повторная оплата эту бронь не вернёт
  • Order.PNRBookingID - код брони у нас
  • Order.AirlineBookingID - код брони авиакомпании, если он уже есть

7️⃣ Одобрение заказа (Order Approval)

POST /api/change/
Этот шаг выписывает билет. Успех — только ответ HTTP 200 и Order.OrderStatus = ISSUED. Оплатите до PaymentTimeLimitDateTime из ответа создания заказа.

📥 Ключевые поля запроса:

  • booking_id (integer) - BookingID заказа для одобрения
  • currency (string) - Валюта заказа
  • Idempotency-Key (заголовок, необязательный) - тот же формат, что при создании. Один ключ на один заказ. Тот же ключ на другой заказ даёт ERR_1023

📤 Ключевые поля ответа:

  • Order.OrderStatus - При успехе ISSUED. В обычном ответе поля StatusCode нет. Повтор уже оплаченной выписки возвращает ISSUED и StatusCode = CLOSED
  • Ticket - Массив билетов. Номер билета в TicketNumber
  • Order.VoidTimelimitUtc - до какого времени билет можно аннулировать. Наивная строка без смещения, в зоне поля timezone, а не метка UTC. Если timezone не передан, берётся зона учётной записи, а если она не задана — UTC. Поля нет, если срок не прислали

8️⃣ Просмотр состояния заказа

POST /api/retrieve/

Order.OrderStatus в ответе — статус, записанный у нас: BOOKED, PROCESSING, ISSUED, FAILED или CANCELED. Если сохранённая карточка есть, ответ берётся из неё. Иначе заказ читается заново, но статус в ответе всё равно наш.

📥 Ключевые поля запроса:

  • booking_id (integer) - BookingID для просмотра
  • currency (string) - Валюта для ценовых компонентов

📤 Ключевые поля ответа:

  • Order.OrderStatus - Статус, записанный у нас: BOOKED, PROCESSING, ISSUED, FAILED или CANCELED. PROCESSING значит, что выписка ещё не закончена, это не билет
  • Ticket - Массив выписанных билетов. Пусто, пока статус не ISSUED

9️⃣ Отмена заказа

POST /api/cancel/
Неоплаченный заказ со статусом BOOKED отменяется без билета. Выписанный заказ аннулируется, пока открыто окно аннулирования. Когда оно закрыто, ответ ERR_1026: нужен возврат, а не повтор отмены. Заказ в PROCESSING отменить нельзя.

📥 Ключевые поля запроса:

  • booking_id (integer) - BookingID заказа для отмены

📤 Ключевые поля ответа:

  • Canceled - true, если отмена принята
  • MixOrderRef.Order.OperationStatus - Success при принятой отмене. Отдельного MixOrderID в этом ответе нет

⚠️ Коды ошибок веб-сервиса

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

📋 Как читать ошибку

Неуспешный вызов бизнес-логики возвращает тело без обёртки detail:

{
    "error": {
    "code": "AGR_PROVIDER_ERROR",
    "message": "CAN'T MAKE AUTOPRICING",
    "avs_code": "BOOKING_PRICE_UNAVAILABLE"
  }
}

code — прежний код. Его значение не меняется. avs_code — общее имя ситуации, одно для всех подключённых систем. По нему и нужно понимать ошибку. message — текст этой ошибки. Поле data бывает только у отдельных ошибок.

Ошибка формы запроса устроена иначе. Код VALIDATION_ERROR, текст «Ошибка валидации данных», подробности в details, и всё это лежит внутри detail.error.
Ошибки аутентификации (AUTH)
Код Обычная фраза
AUTH_1000 Неверный логин или пароль
AUTH_1001 Ваш аккаунт деактивирован
AUTH_1002 Доступ запрещен с вашего IP-адреса
AUTH_1003 Неверный API-ключ
AUTH_1004 Пользователь не найден
AUTH_1005 Неверный токен авторизации
Коды сервиса
Код Обычная фраза
ERR_1000 Внутренняя ошибка сервера
ERR_1001 Валюта не разрешена
ERR_1002 Предложение не найдено
ERR_1003 Не найден курс для пары
ERR_1004 Не указаны разрешенные валюты для пользователя
ERR_1005 Не найдены API данные
ERR_1006 Не существует временная зона
ERR_1007 Ошибка при конвертации времени
ERR_1008 Ошибка при парсинге даты
ERR_1009 Кошелек не найден
ERR_1010 Заказ не найден
ERR_1011 Недостаточно средств. Превышен кредитный лимит
ERR_1012 Ошибка подключения к базе данных
ERR_1013 Один или несколько обязательных параметров равны None
ERR_1014 Ошибка обновления баланса
ERR_1015 Ошибка получения информации о балансе
ERR_1016 Ошибка при получении API данных
ERR_1017 Произошла ошибка при создании Client
ERR_1018 Доступ к эндпоинту запрещен
ERR_1019 Доступ запрещен к заказу
ERR_1020 Доступ запрещен
ERR_1021 Не найдено
ERR_1023 Выписка этого заказа уже выполняется
ERR_1024 Модуль временно недоступен
ERR_1025 Поиск этой линейки временно занят
ERR_1026 Срок аннулирования истёк, нужен возврат
ERR_1027 Создание возможно только из статуса SELECTED
PAX_1000 Ограничение маршрута пассажира
PAX_1001 Некорректное ограничение маршрута
UNKNOWN_ERROR Неизвестная ошибка

У одного кода бывает несколько фраз. Код не меняется, читайте message. Например ERR_1013 — «Создание возможно только из статуса SELECTED» или «Для создания заказа нужен хотя бы один пассажир». ERR_1020 — «Доступ запрещен» либо «Заказ привязан к другому реквизиту». ERR_1023 — выписка или создание уже идут, либо ключ идемпотентности занят другим заказом. Это не билет. ERR_1026 при пустом сроке аннулирования говорит: нет срока, отмена билета недоступна.

Общие имена

У одной и той же ситуации одно имя в avs_code, откуда бы ни пришла ошибка. Полный список имён: GET /error-codes/ с тем же токеном. Если отдельного имени нет, приходит PROVIDER_ERROR. Старые значения в поле code при этом не меняются.

avs_code HTTP Что это значит
BOOKING_PRICE_UNAVAILABLE 422 Эту бронь уже нельзя оценить и выписать. Оформите заказ заново
DATE_NOT_AVAILABLE 422 На эту дату рейсы не продаются
DOCUMENT_CHARSET_INVALID 400 Документ для международной перевозки нужно вводить латиницей
FLIGHT_NOT_FOUND 422 Такого рейса нет. Ищите заново
FLIGHT_SEGMENTS_NOT_CONNECTED 400 Сегменты маршрута не стыкуются по дате
FLIGHT_SEGMENT_CANCELLED 422 Место в брони снято. Оформите заказ заново
PASSENGER_AGE_FORMAT_INVALID 400 Возраст пассажира указан в виде, который касса не принимает
PASSENGER_INFANT_LIMIT_EXCEEDED 400 Количество младенцев превышает допустимое на одного взрослого
PAYMENT_DEADLINE_TOO_CLOSE 409 Срок оплаты слишком близко. Оформите заказ заново и оплатите до срока
POINT_FORMAT_INVALID 400 Город или аэропорт указан в виде, который касса не принимает
PROVIDER_ERROR 502 Произошла ошибка на стороне поставщика
VALIDATION_DATE_IN_PAST 400 Дата вылета или прилёта находится в прошлом

Фразы авиакомпании

Нет мест или продажа запрещена
Рейс закрыт или мест нет. Это ответ авиакомпании. Повтор той же брони места не добавляет.
Дублирование номера билета или документа
Перевозчик сообщил, что номер уже использован. Не повторяйте оплату, если по заказу уже пришёл OrderStatus = ISSUED.