NurCore API
API Reference

Public Endpoints

Endpoints без авторизации — airline profile, CMS-контент, app links для website / mobile.

Публичные read-only endpoints для отображения базовой информации на website и mobile. Не требуют X-API-Key или JWT. Защищены rate-limit 60 req/min/IP на API Gateway.

Base URL: https://api.nurcore.kg/api/v1/auth/public

Группы

КатегорияEndpoints
Airline profileGET /airline/profile
Static pagesGET /page-contents, GET /page-contents/{slug}
BannersGET /site-banners
Info blocksGET /site-info-blocks
Destination adsGET /destinations-ads
Mobile appsGET /app-links

GET /airline/profile

Информация об авиакомпании для header/footer и SEO.

curl "https://api.nurcore.kg/api/v1/auth/public/airline/profile"

Response 200:

{
  "airline_name": "Example Airlines",
  "airline_name_en": "Example Airlines",
  "iata_code": "ZM",
  "icao_code": "ASB",
  "callsign": "EXAMPLE",
  "country": "Кыргызстан",
  "country_code": "KG",
  "base_airport": "FRU",
  "timezone": "Asia/Bishkek",
  "default_currency": "KGS",
  "contact_email": "info@example-airline.com",
  "contact_phone": "+996 312 999999",
  "website": "https://example-airline.com",
  "legal_name": "ОсОО \"Example Airlines\"",
  "logo_url": "https://cdn.example-airline.com/logo.svg"
}

Не возвращает: tax_id, registration_number, pnr_prefix, ticket_prefix (чувствительные внутренние поля).


GET /page-contents

Список всех публичных страниц (метаданные).

curl "https://api.nurcore.kg/api/v1/auth/public/page-contents?language=ru"

Query:

ParamDefaultОписание
languageru2-буквенный код языка (ru / en / ky)

Response 200:

[
  {"id": "uuid", "slug": "about", "language": "ru", "title": "О компании", "sort_order": 1},
  {"id": "uuid", "slug": "faq", "language": "ru", "title": "Часто задаваемые вопросы", "sort_order": 2},
  {"id": "uuid", "slug": "terms", "language": "ru", "title": "Условия использования", "sort_order": 3}
]

GET /page-contents/{slug}

Полное содержимое одной страницы.

curl "https://api.nurcore.kg/api/v1/auth/public/page-contents/about?language=ru"

Path params:

ParamОписание
slugИдентификатор страницы (about / faq / terms / privacy / contacts)

Response 200:

{
  "id": "uuid",
  "slug": "about",
  "language": "ru",
  "title": "О компании Example Airlines",
  "content": "<p>Example Airlines — национальный авиаперевозчик...</p>",
  "meta_description": "Example Airlines — узнайте о нашей компании",
  "sort_order": 1
}

Errors: 404 если страница на указанном языке не настроена. Fallback на UI стороне: попробовать language=ru или language=en.


GET /site-banners

Активные баннеры главной с учётом active_from / active_to.

curl "https://api.nurcore.kg/api/v1/auth/public/site-banners?language=ru"

Response 200:

[
  {
    "id": "uuid",
    "title": "Лето в Стамбуле — от 18 000 KGS",
    "subtitle": "Бронируйте до 30 мая",
    "image_url": "https://cdn.example-airline.com/banners/istanbul-summer.jpg",
    "image_url_mobile": "https://cdn.example-airline.com/banners/istanbul-summer-mobile.jpg",
    "link_url": "/search?to=IST",
    "cta_text": "Купить билет",
    "language": "ru",
    "sort_order": 1
  }
]

image_url_mobile — опциональный mobile-optimized крой (например 16:9 для desktop, 4:5 для mobile). Если NULL — используйте image_url.


GET /site-info-blocks

Блоки преимуществ для главной страницы.

curl "https://api.nurcore.kg/api/v1/auth/public/site-info-blocks?language=ru&category=advantages"

Query:

ParamОписание
languageru / en / ky
categoryОпциональный фильтр (advantages / services / contacts)

Response 200:

[
  {
    "id": "uuid",
    "icon": "luggage",
    "title": "Багаж 23 кг бесплатно",
    "description": "Во всех тарифах кроме LIGHT",
    "link_url": "/baggage",
    "language": "ru",
    "category": "advantages",
    "sort_order": 1
  }
]

icon — короткое ключевое слово (luggage / meal / wifi / star). UI маппит на свой icon set (Lucide / Material Icons / custom SVG).


GET /destinations-ads

Промо-направления с фото и минимальной ценой.

curl "https://api.nurcore.kg/api/v1/auth/public/destinations-ads?language=ru&origin_iata=FRU"

Query:

ParamОписание
languageru / en / ky
origin_iataОпционально — фильтр по аэропорту вылета (FRU / OSS)

Response 200:

[
  {
    "id": "uuid",
    "title": "Стамбул",
    "subtitle": "Душа Турции",
    "image_url": "https://cdn.example-airline.com/destinations/istanbul.jpg",
    "origin_iata": "FRU",
    "destination_iata": "IST",
    "price_from": 18000,
    "currency": "KGS",
    "language": "ru",
    "sort_order": 1
  }
]

price_from — кэшированная минимальная цена. Для актуальной цены — звоните Schedules API.


Ссылки на mobile-приложения по платформе.

curl "https://api.nurcore.kg/api/v1/auth/public/app-links"

Response 200:

[
  {
    "id": "uuid",
    "platform": "ios",
    "store_url": "https://apps.apple.com/app/example-airline/id123456789",
    "app_id": "com.example.airline.app",
    "current_version": "1.2.0",
    "min_version": "1.0.0",
    "badge_url": "https://cdn.example-airline.com/badges/app-store.svg",
    "sort_order": 1
  },
  {
    "id": "uuid",
    "platform": "android",
    "store_url": "https://play.google.com/store/apps/details?id=com.example.airline.app",
    "app_id": "com.example.airline.app",
    "current_version": "1.2.0",
    "min_version": "1.0.0",
    "badge_url": "https://cdn.example-airline.com/badges/google-play.svg",
    "sort_order": 2
  },
  {
    "id": "uuid",
    "platform": "huawei",
    "store_url": "https://appgallery.huawei.com/app/C123456789",
    "app_id": "com.example.airline.app",
    "current_version": "1.2.0",
    "badge_url": "https://cdn.example-airline.com/badges/app-gallery.svg",
    "sort_order": 3
  }
]

Используйте min_version для force-upgrade в mobile-app при запуске.


Phone-OTP authentication

Дополнительно для passenger-flow доступна phone-based аутентификация:

EndpointНазначение
POST /api/v1/auth/passenger/phone/checkПроверить наличие аккаунта по номеру
POST /api/v1/auth/passenger/phone/request-codeЗапросить SMS-код
POST /api/v1/auth/passenger/phone/verifyПодтвердить код → токены

Flow

1. UI: POST /phone/check { phone: "+996555000000" }
       → { exists: true } или { exists: false }

2. UI: POST /phone/request-code { phone: "+996555000000" }
       → { sent: true, expires_in: 300, phone_masked: "+9965***00" }
       SMS уходит на номер

3. UI: POST /phone/verify { phone: "+996555000000", code: "123456" }
       → { access_token, refresh_token, passenger }
       Если аккаунта не было — создан автоматически (phone-only)

Rate limits

  • 1 SMS / 60 секунд / номер
  • 5 SMS / час / IP
  • 3 попытки ввода OTP

Errors

CodeСценарий
400Неверный код / OTP истёк
429Превышен rate-limit (Retry-After в заголовке)
503SMS-провайдер недоступен

Exchange Rates (Sprint 3.1)

Курсы валют для display в UI. Реальная оплата всегда происходит в валюте тарифа — эти курсы только для конвертации цен на отображение.

GET /fares/public/exchange-rates

curl "https://api.nurcore.kg/api/v1/fares/public/exchange-rates?\
base=KGS&source=both"

Query:

ParamDefaultОписание
baseKGSБазовая валюта (3-letter ISO)
sourceinternalinternal / nbkr / both

Source options:

  • internal — внутренние курсы авиакомпании
  • nbkr — только из НБ КР (api.nbkr.kg, daily XML, free)
  • both — merge с приоритетом internal

Response 200:

{
  "base": "KGS",
  "fetched_at": "2026-05-12T10:00:00Z",
  "source": "both",
  "rates": {
    "USD": {"rate": 0.0117, "effective_date": "2026-05-12", "source": "internal"},
    "EUR": {"rate": 0.0108, "effective_date": "2026-05-12", "source": "nbkr"},
    "RUB": {"rate": 1.05, "effective_date": "2026-05-12", "source": "nbkr"},
    "KZT": {"rate": 5.20, "effective_date": "2026-05-12", "source": "internal"}
  }
}

Семантика: rate означает "1 base = N target". То есть 1 KGS = 0.0117 USD.

GET /fares/public/exchange-rates/convert

curl "https://api.nurcore.kg/api/v1/fares/public/exchange-rates/convert?\
amount=5000&from_currency=KGS&to_currency=USD"

Response 200:

{
  "amount": 5000,
  "converted": 58.50,
  "rate": 0.0117,
  "from_currency": "KGS",
  "to_currency": "USD",
  "source": "internal",
  "effective_date": "2026-05-12"
}

Не для финансовых операций. Эта конвертация только для UI display. Реальная мульти-валютная оплата требует использования Quote API с явным target_currency.

Fallback на НБ КР

Когда source=both или nbkr и internal rate отсутствует, NurCore вызывает api.nbkr.kg (XML feed, обновляется ежедневно). НБ КР возвращает только курсы относительно KGS — для других base применяется cross-rate через KGS:

USD → EUR = (KGS per USD) / (KGS per EUR)

Поле source в каждой записи показывает источник: internal / nbkr / nbkr_cross (cross-rate через KGS).


Grouped fare prices

Для страницы поиска — вся сетка fare-families одним запросом:

curl -H "X-API-Key: $PUBLISHABLE_KEY" \
     "https://api.nurcore.kg/api/v1/fares/grouped-prices/?\
flight_id=$FLIGHT_ID&pax_types=ADT,CHD&currency=KGS"

Response 200:

{
  "flight_id": "uuid",
  "flight_date": "2026-05-15",
  "route_id": "uuid",
  "origin_iata": "FRU",
  "destination_iata": "IST",
  "currency": "KGS",
  "best_family_id": "uuid-light",
  "families": [
    {
      "fare_plan_id": "uuid-light",
      "fare_plan_name": "LIGHT",
      "class_of_service": "economy",
      "min_total_price": 12500,
      "currency": "KGS",
      "refundable": false,
      "changeable": false,
      "baggage_allowance": "0 kg",
      "cabin_baggage": "5 kg",
      "prices": [
        {"fare_price_id": "uuid", "passenger_type": "adult", "total_price": 12500, "...": "..."},
        {"fare_price_id": "uuid", "passenger_type": "child", "total_price": 9375, "...": "..."}
      ]
    },
    {
      "fare_plan_id": "uuid-classic",
      "fare_plan_name": "CLASSIC",
      "min_total_price": 18000,
      "...": "..."
    }
  ]
}

Раньше для отображения 3 fare-families на странице рейса требовалось 3 отдельных запроса. Этот endpoint решает N+1 проблему — все families в одном response, отсортированы по min_total_price, с готовым best_family_id для default-выбора в UI.

On this page