Check-in
Online check-in, seat-map, boarding pass — полный self-service цикл.
Базовый префикс: /api/v1/checkin/
Пассажир проходит весь цикл регистрации сам (mobile / website) через
magic-link access_token (scope checkin:pax): выбор места,
DG-декларация, завершение, посадочный талон. Участие агента не требуется.
Окно регистрации (раздельно по каналам)
Окна настраиваются авиакомпанией (Настройки → Регистрация) и различаются для онлайн и стойки:
| Канал | Открытие | Закрытие | Ключ настройки |
|---|---|---|---|
| Онлайн (web/mobile) | за checkin.online_open_hours ч (по умолч. 24 ч) | за checkin.online_close_minutes мин (по умолч. 40 мин) | checkin.online_* |
| Стойка (counter/kiosk/agent) | за checkin.counter_open_hours ч (по умолч. 3 ч) | за checkin.counter_close_minutes мин (по умолч. 40 мин) | checkin.counter_* |
Self-service OCI всегда использует онлайн-окно. Вне окна — ответ 400 с текстом «Регистрация откроется … / закрыта с …» (локальное время авиакомпании).
Consumer self-service flow (magic-link)
Все эндпойнты ниже принимают ?access_token=<token> (scope
checkin:pax); токен должен быть выпущен для booking этого пассажира.
1. GET /flight/{flight_id}/seat-map
Карта салона: реальная конфигурация ВС, занятые места, доплаты за зоны.
Три варианта авторизации (выбор по контексту):
| Контекст | Заголовки | Назначение |
|---|---|---|
| Booking-time (до создания брони) | X-API-Key (consumer-app) | Read-only — пассажир выбирает место во время бронирования |
| OCI (после брони, magic-link) | ?access_token=X&booking_id=Y | Online check-in flow |
| Staff / agency | Authorization: Bearer <JWT> | Только для авиакомпании |
# Booking-time
curl -H "X-API-Key: $KEY" \
"https://api.nurcore.kg/api/v1/checkin/flight/$FLIGHT_ID/seat-map"
# OCI (через magic-link)
curl "https://api.nurcore.kg/api/v1/checkin/flight/$FLIGHT_ID/seat-map?access_token=$TOK&booking_id=$BOOK_ID"Response (сокращённо):
{
"flight_id": "uuid",
"aircraft_id": "uuid",
"columns": ["A", "B", "C", "D"],
"rows": [
{
"number": 12,
"class": "economy",
"seats": [
{"seat_number": "12A", "type": "standard", "status": "free", "fee": 0},
{"seat_number": "12B", "type": "extra_legroom", "status": "free", "fee": 500},
{"seat_number": "12C", "type": "standard", "status": "occupied", "fee": 0}
]
}
],
"stats": {"total": 180, "free": 156, "occupied": 24, "blocked": 0}
}status ∈ free | occupied | blocked — выбирайте только free.
2. POST /consumer?access_token=X
Создать регистрацию (статус in_progress). Для round-trip —
вызывается отдельно на каждое плечо: flight_id указывает на нужный
сегмент брони (outbound или return).
Body:
{
"booking_id": "11111111-1111-1111-1111-111111111111",
"passenger_id": "22222222-2222-2222-2222-222222222222",
"flight_id": "33333333-3333-3333-3333-333333333333",
"seat_number": "12A",
"special_requests": "VGML"
}| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
booking_id | UUID | ✅ | Должен совпадать с bid внутри access_token |
passenger_id | UUID | ✅ | Один из пассажиров этой брони |
flight_id | UUID | ✅ | Outbound или return |
seat_number | string | — | Формат ^\d{1,2}[A-Z]$; если не указан — место присваивается автоматически |
special_requests | string | — | IATA SSR-код (VGML, WCHR, …) если в fare.allowed_ssr_codes |
Response 201 — CheckinResponse (checkin_id, status="in_progress", seat_number, boarding_pass_issued=false).
Errors:
| Код | Сценарий |
|---|---|
| 400 | Окно регистрации не открыто / уже закрыто |
| 400 | SSR-код вне fare.allowed_ssr_codes |
| 401 | Невалидный access_token |
| 404 | Бронь / пассажир / рейс не найдены |
| 409 | Место уже занято / пассажир уже зарегистрирован |
3. POST /{checkin_id}/seat?access_token=X
Выбрать/сменить место. Body: {"seat_number": "12A"} или query
?seat_number=12A.
4. POST /{checkin_id}/dg-declare?access_token=X
IATA DGR 2.3 — подтверждение отсутствия dangerous goods. Обязательно
до выдачи посадочного. Body: {"confirmed": true}.
5. POST /{checkin_id}/complete?access_token=X
Завершить регистрацию (in_progress → completed).
6. POST /{checkin_id}/boarding-pass?access_token=X
Выпустить посадочный талон (требует завершённого DG-screening).
7. GET /{checkin_id}/boarding-pass/pdf?access_token=X
PDF посадочного с BCBP-штрихкодом (IATA Resolution 792 M1).
format=thermal— 80×200 мм термопринтер (default)format=a4— A4 лазерный
Lookup (Find my trip)
GET /api/v1/bookings/lookup-consumer?pnr=X&email=Y
Пассажир потерял ссылку — вводит PNR + email, получает свежий magic-link на почту. Response generic (не подтверждает существование) — защита от brute-force. Rate limit 3/min, 10/hour на IP.
B2B / Staff flow
Те же эндпойнты POST /{id}/seat, /complete, /dg-declare,
/boarding-pass, POST / принимают staff JWT (вместо access_token)
с соответствующими permission'ами (checkin:seat_select,
checkin:update, checkin:boarding_pass). Стойка/киоск используют
counter-окно регистрации.
GET /flight/{flight_id}/passengers
Список пассажиров рейса с check-in статусом.
GET /stats?flight_ids=id1,id2,...
Агрегированный счётчик checked-in / boarded по нескольким рейсам.